Related
I'm trying to draw bar chart with 2 series supperposed, it's working well using barGap: '-100%' :
But when first serie value is smaller than second one, the first value bar is hidden by second one. Is there a way to always display all bars from smaller to highter ?
Thank you
option = {
xAxis: {
data: ['a', 'b', 'c', 'd'],
axisTick: { show: false },
},
yAxis: {
},
animationDurationUpdate: 1200,
series: [
{
type: 'bar',
itemStyle: {
normal: {
color: '#ddd'
}
},
silent: true,
barWidth: 40,
barGap: '-100%',
data: [60, 60, 60, 60]
},
{
type: 'bar',
barGap: '-100%',
barWidth: 40,
data: [80, 60, 13, 25]
}
]
};
I'm making a chart here and I have a little problem with removing the distance between the boxes
var myConfig = {
type: 'bar',
legend: {
layout: "x4",
overflow : "page",
shadow : false,
align : "left",
alpha :0.05,
"adjust-layout": true,
marker : {
type : "circle",
size : "7px",
"border-color" :"none"
}
},
scaleX: {
// convert text on scale indices
labels: ['Automotive', 'Retail', 'Wholesale']
},
plot: {
barWidth:"50%",
animation: {
effect: 'ANIMATION_EXPAND_BOTTOM',
method: 'ANIMATION_STRONG_EASE_OUT',
sequence: 'ANIMATION_BY_NODE',
speed: 275,
}
},
series: [
{
// plot 1 values, linear data
values: [23, 20, 27],
text: 'Sum of target Premi',
backgroundColor: '#fa6383',
borderRadius: 5,
},
{
// plot 2 values, linear data
values: [35, 42, 33],
text: 'Sum of premi Leads',
backgroundColor: '#fb9f40',
borderRadius: 5,
},
{
// plot 2 values, linear data
values: [15, 22, 13],
text: 'Sum of premi Activity',
backgroundColor: '#fdcd55',
borderRadius: 5,
},
{
// plot 2 values, linear data
values: [15, 22, 13],
text: 'Sum of premi Booking',
backgroundColor: '#4bc0c1',
borderRadius: 5,
}
]
};
for my settings like this. there are suggestions so there can be no space ?
i have try documentation but does not work.
https://www.zingchart.com/docs/chart-types/bar
I'm not sure that I correctly understood your problem but probably you can try to use "barsOverlap" in "plot" configuration to achieve the desired result.
var myConfig = {
type: 'bar',
legend: {
layout: "x4",
overflow : "page",
shadow : false,
align : "left",
alpha :0.05,
"adjust-layout": true,
marker : {
type : "circle",
size : "7px",
"border-color" :"none"
}
},
scaleX: {
// convert text on scale indices
labels: ['Automotive', 'Retail', 'Wholesale']
},
plot: {
barWidth:"50%",
barsOverlap: '50%',
animation: {
effect: 'ANIMATION_EXPAND_BOTTOM',
method: 'ANIMATION_STRONG_EASE_OUT',
sequence: 'ANIMATION_BY_NODE',
speed: 275,
}
},
series: [
{
// plot 1 values, linear data
values: [23, 20, 27],
text: 'Sum of target Premi',
backgroundColor: '#fa6383',
borderRadius: 5,
},
{
// plot 2 values, linear data
values: [35, 42, 33],
text: 'Sum of premi Leads',
backgroundColor: '#fb9f40',
borderRadius: 5,
},
{
// plot 2 values, linear data
values: [15, 22, 13],
text: 'Sum of premi Activity',
backgroundColor: '#fdcd55',
borderRadius: 5,
},
{
// plot 2 values, linear data
values: [15, 22, 13],
text: 'Sum of premi Booking',
backgroundColor: '#4bc0c1',
borderRadius: 5,
}
]
};
I take one of the examples posted and slightly modify it by removing some data. When the sets don't have the same number of data points, the tooltips stop displaying.
Please see the following two examples. The first one being the one posted in the docs. The second, the modified version. When hovering starting from the end data points, the tooltip doesn't display anything for the last columns.
Example from docs: https://codepen.io/junedchhipa/pen/YJQKOy
var options = {
chart: {
height: 310,
type: 'line',
stacked: false,
},
stroke: {
width: [0, 2, 5],
curve: 'smooth'
},
plotOptions: {
bar: {
columnWidth: '50%'
}
},
series: [{
name: 'Series Column',
type: 'column',
data: [23, 11, 22, 27, 13, 22, 37, 21, 44, 22, 30]
}, {
name: 'Series Area',
type: 'area',
data: [44, 55, 41, 67, 22, 43, 21, 41, 56, 27, 43]
}, {
name: 'Series Line',
type: 'line',
data: [30, 25, 36, 30, 45, 35, 64, 52, 59, 36, 39]
}],
fill: {
opacity: [0.85,0.25,1],
gradient: {
inverseColors: false,
shade: 'light',
type: "vertical",
opacityFrom: 0.85,
opacityTo: 0.55,
stops: [0, 100, 100, 100]
}
},
labels: ['01/01/2003', '02/01/2003','03/01/2003','04/01/2003','05/01/2003','06/01/2003','07/01/2003','08/01/2003','09/01/2003','10/01/2003','11/01/2003'],
markers: {
size: 0
},
xaxis: {
type:'datetime'
},
yaxis: {
title: {
text: 'Points',
},
min: 0
},
legend: {
show: false
},
tooltip: {
shared: true,
intersect: false,
y: {
formatter: function (y) {
if(typeof y !== "undefined") {
return y.toFixed(0) + " points";
}
return y;
}
}
}
}
var chart = new ApexCharts(
document.querySelector("#chart"),
options
);
chart.render();
// check if the checkbox has any unchecked item
checkLegends()
function checkLegends() {
var allLegends = document.querySelectorAll(".legend input[type='checkbox']")
for(var i = 0; i < allLegends.length; i++) {
if(!allLegends[i].checked) {
chart.toggleSeries(allLegends[i].value)
}
}
}
// toggleSeries accepts a single argument which should match the series name you're trying to toggle
function toggleSeries(checkbox) {
chart.toggleSeries(checkbox.value)
}
Modified example:
https://codepen.io/mmk2118/pen/mdbpOWN
var options = {
chart: {
height: 310,
type: 'line',
stacked: false,
},
stroke: {
width: [0, 2, 5],
curve: 'smooth'
},
plotOptions: {
bar: {
columnWidth: '50%'
}
},
series: [{
name: 'Series Column',
type: 'column',
data: [23, 11, 22, 27, 13, 22, 37, 21, 44, 22, 30]
}, {
name: 'Series Area',
type: 'area',
data: [44, 55, 41, 67, 22, 43, 21, 41]
}, {
name: 'Series Line',
type: 'line',
data: [30, 25, 36, 30, 45, 35, 64, 52, 59, 36, 39]
}],
fill: {
opacity: [0.85,0.25,1],
gradient: {
inverseColors: false,
shade: 'light',
type: "vertical",
opacityFrom: 0.85,
opacityTo: 0.55,
stops: [0, 100, 100, 100]
}
},
labels: ['01/01/2003', '02/01/2003','03/01/2003','04/01/2003','05/01/2003','06/01/2003','07/01/2003','08/01/2003','09/01/2003','10/01/2003','11/01/2003'],
markers: {
size: 0
},
xaxis: {
type:'datetime'
},
yaxis: {
title: {
text: 'Points',
},
min: 0
},
legend: {
show: false
},
tooltip: {
shared: true,
intersect: false,
y: {
formatter: function (y) {
if(typeof y !== "undefined") {
return y.toFixed(0) + " points";
}
return y;
}
}
}
}
var chart = new ApexCharts(
document.querySelector("#chart"),
options
);
chart.render();
// check if the checkbox has any unchecked item
checkLegends()
function checkLegends() {
var allLegends = document.querySelectorAll(".legend input[type='checkbox']")
for(var i = 0; i < allLegends.length; i++) {
if(!allLegends[i].checked) {
chart.toggleSeries(allLegends[i].value)
}
}
}
// toggleSeries accepts a single argument which should match the series name you're trying to toggle
function toggleSeries(checkbox) {
chart.toggleSeries(checkbox.value)
}
Your codepen example uses an older version of ApexCharts.
Please update by pulling the latest version here
https://cdn.jsdelivr.net/npm/apexcharts#latest
Also, if you have a different number of data-points in each series, you can turn off shared tooltip and only show the tooltip when the user hovers over bars/markers directly.
tooltip: {
shared: false,
intersect: true
}
I need to show tooltips for only the last two series when hovering the mouse over the graph. In this example the idea will be to show only the tool tips for the values 1699 and 1750. The rest of the values can't show any tooltips when hovering the mouse. How can I achive that? I haven't found any way to do so. Is it possible? Thanks in advance.
(function () {
var categories= ['1350', '1400', '1450', '1500', '1550', '1699', '1750'];
Highcharts.chart('grafica1', {
chart: {
type: 'area',
},
title: {
text: ' '
},
xAxis: {
labels: {
enabled: true,
formatter: function () {
return categories[this.value];
}
},
tickmarkPlacement: 'on',
title: {
enabled: false
}
},
yAxis: {
title: {
text: 'Percent'
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.percentage:.1f}%</b> ({point.y:,.0f} millions)<br/>',
split: true
},
plotOptions: {
area: {
stacking: 'percent',
lineColor: '#ffffff',
lineWidth: 1,
marker: {
lineWidth: 1,
lineColor: '#ffffff',
}
}
},
series: [{
name: 'Africa',
data: [502, 635, 809, 947, 1402, 3634, 5268]
}, {
name: 'L. America',
data: [106, 107, 111, 133, 221, 767, 1766]
}, {
name: 'Oceania',
data: [163, 203, 276, 408, 547, 729, 628]
}, {
name: 'S-E. Asia',
data: [18, 31, 54, 156, 339, 818, 1201]
}, {
name: 'Japan',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'China',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'Near East',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'Asian CIS',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'Russia',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'East Europe',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'Central Europe',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'W. Europe - Nordic',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'Nordic',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'N. America',
data: [2, 2, 2, 6, 13, 30, 46]
}]
});
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="grafica1" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
You can use the formatter like this :
tooltip: {
formatter: function() {
if(this.points[0].key < (this.points[0].series.xData.length -2)){
return false;
}
var s = [];
s.push(this.x);
this.points.forEach(function(point) {
s.push('<b>' + point.series.name + '</b>: ' + point.y);
});
return s;
},
split: true
},
Fiddle
Not the cleanest code (there still an error in the console) but it's work.
Edit
Following Deep 3015 comment, code and fiddle updated
You can wrap tooltip.prototype.renderSplit method to show the tooltip only if the points have certain x values.
Highcharts.wrap(Highcharts.Tooltip.prototype, 'renderSplit', function (p, labels, points) {
if (!this.options.showOnLastTwo) {
return p.call(this, labels, points)
}
const point = points[0]
if (point) {
const allowedXs = point.series.xData.slice(-2)
if (allowedXs.includes(point.x)) {
return p.call(this, labels, points)
}
}
this.destroy()
})
And set in tooltip options showOnLastTwo flag to true:
tooltip: {
split: true,
showOnLastTwo: true
},
The flag is not necessary but the wrap changes Highcharts globally so it will affect every chart - the flag will prevent this.
live example: http://jsfiddle.net/sLvekuht/1/
Is there a way to add another line to the bar in the BoxPlot chart which will represent the Mean (Average)? This will look like the Median line which is automatically drawn for you in the below Fiddle
http://jsfiddle.net/tLucL6mq/3/
Fiddle code:
$('#container').highcharts({
chart: {
type: 'boxplot',
inverted: true
},
title: {
text: 'Sample Base Salary Range'
},
legend: {
enabled: false
},
xAxis: {
categories: ['4', '3', '2', '1', '0'],
title: {
text: 'Job Level'
}
},
yAxis: {
title: {
text: 'Base Salary'
}
},
plotOptions: {
boxplot: {
fillColor: '#F0F0E0',
lineWidth: 2,
medianColor: '#0C5DA5',
medianWidth: 3
}
},
series: [{
name: "Observation Data",
data: [
['0', 68, 75, 79, 82, 84, 89], //level 4 - category 0
['1', 53, 63, 68, 72, 75, 79], //level 3 - category 1
['2', 47, 52, 59, 64, 67, 68], //level 2 - category 2
['3', 35, 37, 39, 42, 46, 51], //level 1 - category 3
['4', 32, 33, 34, 38, 40, 45] //level 0 - category 4
],
tooltip: {
headerFormat: '<b>{point.series.name}</b><br/><em>Job Level: {point.x}</em><br/>',
pointFormat: '- Max: {point.high}<br/>' +
'- Q3: {point.q3}<br/>' +
'- Median: {point.median}<br/>' +
'- Q1: {point.q1}<br/>' +
'- Min: {point.low}<br/>'
}
}, {
name: "Outlier Data",
color: Highcharts.getOptions().colors[0],
type: 'scatter',
data: [ // x, y positions where 0 is the first category
[0, 74],
[1, 67],
[4, 40],
[4, 48]
],
marker: {
fillColor: 'yellow',
lineWidth: 2,
lineColor: '#0C5DA5'
},
tooltip: {
headerFormat: '<b>{point.series.name}</b><br/><em>Job Level: {point.x}</em><br/>',
pointFormat: 'Base Salary: {point.y}'
}
}]
});
I'm not seeing in the docs how to do this... Is this possible at all?
Also, in the example, when you hover any part of the boxplot, the tooltip pops up. Is there a way to show the tooltip when you hover the Median or one of the Quartiles so that it only shows that data point's info?
I'm thinking it would be similar to how the tooltip for the scatter series shows data for individual points.
Edit:
I finally got my head around the syntax to pass in point objects instead of the array of values for each data set. After getting that object syntax correct, I added a new property for mean and included that value in the tooltip.
http://jsfiddle.net/tLucL6mq/4/
series: [{
name: "Observation Data",
data: [
{x: '0', low: 68, q1: 75, median: 79, q3: 82, high: 84, mean: 77.6}, //level 4 - category 0
{x: '1', low: 53, q1: 63, median: 68, q3: 72, high: 75, mean: 66.2}, //level 3 - category 1
{x: '2', low: 47, q1: 52, median: 59, q3: 64, high: 67, mean: 57.8}, //level 2 - category 2
{x: '3', low: 35, q1: 37, median: 39, q3: 42, high: 46, mean: 39.8}, //level 1 - category 3
{x: '4', low: 32, q1: 33, median: 34, q3: 38, high: 40, mean: 35.4} //level 0 - category 4
],
tooltip: {
headerFormat: '<b>{point.series.name}</b><br/><em>Job Level: {point.x}</em><br/>',
pointFormat: '- Min: {point.low}<br/>' +
'- Q1: {point.q1}<br/>' +
'- Median: {point.median}<br/>' +
'- Q3: {point.q3}<br/>' +
'- Max: {point.high}<br/>' +
'- Mean: {point.mean}<br/>'
}
}
This is almost what I wanted, but ideally, I would like to see the mean line displayed on the box for each data set just like the median line is.
In general, it's not supported to add such line, but it's Highcharts, so you can extend default functions: http://jsfiddle.net/tLucL6mq/5/ ;)
Simple snippet:
(function (H) {
// when changing point format for boxplot, values will calculate automatically
H.seriesTypes.boxplot.prototype.pointArrayMap = ['low', 'q1', 'median', 'q3', 'high', 'mean'];
H.seriesTypes.boxplot.prototype.toYData = function (point) {
return [point.low, point.q1, point.median, point.q3, point.high, point.mean];
};
// draw lines after default drawPoints is called:
H.wrap(H.seriesTypes.boxplot.prototype, 'drawPoints', function (p) {
p.call(this);
var chart = this.chart,
r = chart.renderer,
xAxis = this.xAxis,
yAxis = this.yAxis,
x, y;
// for each point, draw line:
H.each(this.points, function (p, i) {
x = p.shapeArgs.x;
y = p.meanPlot;
if (p.meanPlotX) {
// update existing path:
p.meanPlotX.attr({
d: ['M', x, y, 'L', x + p.shapeArgs.width, y]
});
} else {
// create mean-line for the first time
p.meanPlotX = r.path(['M', x, y, 'L', x + p.shapeArgs.width, y]).attr({
stroke: 'black',
'stroke-width': 2
}).add(p.series.group);
}
});
});
})(Highcharts)
Extra:
It will work with your previous format [x, y1, y2, y3, y4, y5, y6] because of the first two methods (pointArrayMap and toYData), of course in case y6=mean: http://jsfiddle.net/tLucL6mq/7/