Hide datalabels inside stacked column chart if we have 1 data - javascript

I need to hide the inside datalabels if there is only one dataset which is greater than zero. What I mean by dataset is
series: [{
name: 'John',
data: [5, 3, 0, 7, 2]
}, {
name: 'Jane',
data: [2, 2, 0, 2, 0]
}, {
name: 'Joe',
data: [3, 4, 3, 2, 0]
}]
If series.data[i] all are zero except one then hide the inside data labels. In the above case the 3rd and 5th dataset has 0,0,3 and 2,0,0 values only 1 non zero value so hide the inside datalabel.
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: ( // theme
Highcharts.defaultOptions.title.style &&
Highcharts.defaultOptions.title.style.color
) || 'gray'
}
}
},
legend: {
align: 'right',
x: -30,
verticalAlign: 'top',
y: 25,
floating: true,
backgroundColor:
Highcharts.defaultOptions.legend.backgroundColor || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
formatter:function() {
if(this.y != 0) {
return this.y;
}
}
}
}
},
series: [{
name: 'John',
data: [5, 3, 0, 7, 2]
}, {
name: 'Jane',
data: [2, 2, 0, 2, 0]
}, {
name: 'Joe',
data: [3, 4, 3, 2, 0]
}]
});
Here I have highlighted which datalabel should need to be remove from inside..

In the formatter function you can check if at least two of the series have y value greater than 0.
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
formatter: function() {
var series = this.series.chart.series,
xPos = this.point.x,
filteredSeries;
if (this.y != 0) {
filteredSeries = series.filter((s) => (s.yData[xPos]));
return filteredSeries.length > 1 ? this.y : '';
}
}
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/6m4e8x0y/4971/
API Reference: https://api.highcharts.com/highcharts/series.column.dataLabels.formatter

Related

Sort stackbar chart in highchart based on size of each stackbar

https://jsfiddle.net/vasjav1/ywspnocd
I wants to sort the stackbar chart from min to max, i.e. smallest bar should occurs first, and largest should occur at the end. I didn't find any solution being present anywhere else related to stackbar chart. there is solution present here https://www.highcharts.com/docs/advanced-chart-features/data-sorting, but it's mostly fitting for the barchart, but I couldn't fit it with the stack bar. Can someone please help me to sort stackbarchart?
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'right',
x: -30,
verticalAlign: 'top',
y: 25,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
},
series: [{
name: 'John',
data: [5, 3, 4, 7, 2]
}, {
name: 'Jane',
data: [2, 2, 3, 2, 1]
}, {
name: 'Joe',
data: [3, 4, 4, 2, 5]
}]
});
You would first have to sort the data and then feed it to highcharts. For instance, if your input data can be represented as this:
{
"Apples": { "John": 5, "Jane": 2, "Joe": 3 },
"Oranges": { "John": 3, "Jane": 2, "Joe": 4 },
"Pears": { "John": 4, "Jane": 3, "Joe": 4 },
"Grapes": { "John": 7, "Jane": 2, "Joe": 2 },
"Bananas": { "John": 2, "Jane": 1, "Joe": 5 },
};
...then you could sort that, and then translate it to the argument you want to pass to highcharts:
// The original input data in one object (or array):
let data = {
"Apples": { "John": 5, "Jane": 2, "Joe": 3 },
"Oranges": { "John": 3, "Jane": 2, "Joe": 4 },
"Pears": { "John": 4, "Jane": 3, "Joe": 4 },
"Grapes": { "John": 7, "Jane": 2, "Joe": 2 },
"Bananas": { "John": 2, "Jane": 1, "Joe": 5 },
};
// Sort the data by sum of values:
let sorted = Object.entries(data).map(([cat, obj]) =>
[cat, obj, Object.values(obj).reduce((a, b) => a + b)]
).sort((a, b) => a[2] - b[2]);
// Now generate the argument for the chart:
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: sorted.map(([cat]) => cat)
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'right',
x: -30,
verticalAlign: 'top',
y: 25,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
},
series: Object.keys(sorted[0][1]).map(name => ({
name, data: sorted.map(([_, {[name]: val}]) => val)
}))
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
Currently, the data-sorting feature works only with individual series.
You can use dependent sorting as described here (example: https://jsfiddle.net/BlackLabel/3f8x7j5w/)
series: [{
id: 'mainSeries',
dataSorting: {
enabled: true
},
data: [...]
}, {
linkedTo: 'mainSeries',
data: [...]
}, {
linkedTo: 'mainSeries',
data: [...]
}, {
linkedTo: 'mainSeries',
data: [...]
}]
or sort each series individually (example: https://jsfiddle.net/BlackLabel/dsm0bz3k/), but the best way will be to use the solution from trincot's answer.

Highcharts age pyramid stacked bar (grouping)

I would like to use the highcharts age pyramid for men and women. Men and women can fall into three different categories. For example a, b and c. I would like to have a stacked bar for the three groups for men and women separately per age. Hopefully you can help me with this.
I have created the following age pyramid example, but as you can see, it has not yet been possible to add more than two groups.
JavaScript
var chart = Highcharts.chart('container', {
chart: {
type: 'bar',
marginLeft: 10
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
}
},
xAxis: {
left: '50%',
categories: ['15-19', '20-21'],
lineWidth: 0,
tickWidth: 0,
labels: {
align: 'left',
x: -18
},
title: {
text: 'Age Group',
align: 'high',
rotation: 0,
x: 40
}
},
yAxis: [{
left: '55%',
width: '45%',
labels: {
enabled: false
},
title: {
x: -160,
text: 'Female'
},
gridLineWidth: 0
}, {
reversed: true,
width: '45%',
offset: 0,
labels: {
enabled: false
},
title: {
x: 170,
text: 'Male'
},
gridLineWidth: 0
}],
series: [{
data: [1, 3],
color: {
linearGradient: {
x1: 0,
x2: 0,
y1: 0,
y2: 1
},
stops: [
[0, '#3F7EBF'],
[1, '#1F3F5F']
]
},
}, {
data: [2, 5],
color: {
linearGradient: {
x1: 0,
x2: 0,
y1: 0,
y2: 1
},
stops: [
[0, '#980061'],
[1, '#4C0030']
]
},
yAxis: 1
}]
});
This is what i want to achieve in the end:
This chart type is not supported by Highcharts library out of the box.
However, something similar can be created using two charts next to each other with one axis reversed. Check demo and code posted below.
Code:
Highcharts.chart('container1', {
chart: {
type: 'bar'
},
title: {
text: ''
},
xAxis: {
categories: ['15-19', '20-21', '21-25'],
labels: {
enabled: false
}
},
yAxis: {
min: 0,
reversed: true,
title: {
text: 'males',
align: 'high'
}
},
credits: {
enabled: false
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
name: 'A',
data: [5, 3, 4]
}, {
name: 'B',
data: [2, 2, 3]
}, {
name: 'C',
data: [3, 4, 4]
}]
});
Highcharts.chart('container2', {
chart: {
type: 'bar'
},
title: {
text: ''
},
xAxis: {
categories: ['15-19', '20-21', '21-25'],
labels: {
align: 'center'
}
},
yAxis: {
min: 0,
title: {
text: 'females',
align: 'low'
}
},
credits: {
enabled: false
},
legend: {
reversed: true
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
name: 'A',
data: [2, 4, 1]
}, {
name: 'B',
data: [5, 2, 1]
}, {
name: 'C',
data: [4, 1, 2]
}]
});
#container1 {
width: 45%;
float: left;
}
#container2 {
width: 55%;
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container1"></div>
<div id="container2"></div>
Demo:
https://jsfiddle.net/BlackLabel/cg5af2dz/
Just a multiple series of data
series: [{
name: 'A (m)',
data: [6, 2],
yAxis: 1
}, {
name: 'B (m)',
data: [2, 2],
yAxis: 1
},
...
]
and stacking: 'normal'
series: {
stacking: 'normal'
}
solves the problem
var chart = Highcharts.chart('container', {
chart: {
type: 'bar',
height: 170,
marginLeft: 10
},
title: '',
plotOptions: {
bar: {
dataLabels: {
enabled: false,
}
},
series: {
stacking: 'normal'
}
},
xAxis: {
left: '50%',
categories: ['15-19', '20-21'],
lineWidth: 0,
tickWidth: 0,
offset: 0,
labels: {
enabled: true,
align: 'left',
x: -18
},
stackLabels: {
enabled: true,
align: 'right',
x: 20
},
title: {
text: 'age group',
align: 'high',
rotation: 0,
x: 40
}
},
yAxis: [{
left: '55%',
width: '45%',
offset: 0,
labels: {
enabled: false
},
title: {
x: -210,
text: 'males'
},
gridLineWidth: 0
}, {
reversed: true,
width: '45%',
offset: 0,
labels: {
enabled: false
},
title: {
x: 210,
text: 'females'
},
stackLabels: {
enabled: true,
align: 'left',
x: -20
},
gridLineWidth: 0
}],
series: [{
name: 'A (m)',
data: [6, 2],
color: '#000',
yAxis: 1
}, {
name: 'B (m)',
data: [2, 2],
color: '#02aff1',
yAxis: 1
}, {
name: 'C (m)',
data: [2, 2],
color: '#e0301e',
yAxis: 1
}, {
name: 'A (f)',
data: [2, 2],
color: '#000',
}, {
name: 'B (f)',
data: [2, 2],
color: '#02aff1',
}, {
name: 'C (f)',
data: [6, 2],
color: '#e0301e',
}]
});
<script src="https://code.highcharts.com/highcharts.src.js"></script>
<div id="container"></div>

Highcharts dashed line on x axis not going all the way across

I have this highchart's jsfiddle and I want the dashed line to go all the way across the graph from 0-10.I have tried this out on a different graph called scatter and it works I want it to work on the type column graph. How do I do this? Is there something in the highcharts api that I am missing?
https://jsfiddle.net/arielkotch/n9dk126y/1/
Highcharts.chart('container', {
chart: {
type: 'column',
renderTo:'#container'
},
title: {
text: ''
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
},
plotOptions: {
column: {
stacking: 'normal',
}
},
series: [{
name: 'John',
borderColor: '#0000FF',
color: '#FFFFFF',
data: [5, 3, 4, 7, 2]
}, {
name: 'Jane',
borderColor: '#0000FF',
color: '#0000FF',
data: [2, 2, 3, 2, 1]
},
{
//5-width
//height
data: [
[4, 10],
[0, 10]
],
lineWidth: 2,
dashStyle: "Dash",
lineColor: 'black',
type: 'scatter',
marker: {
enabled: false
},
showInLegend: false,
enableMouseTracking: false
},
{
data: [
[0, 20]
],
lineWidth: 2,
dashStyle: "Dash",
lineColor: 'black',
type: 'scatter',
marker: {
enabled: false
},
showInLegend: false,
enableMouseTracking: false
}
]
});
To create such type of lines, you should use yAxis.plotLines:
yAxis: {
...,
plotLines: [{
value: 10,
zIndex: 2,
width: 2,
dashStyle: "Dash",
color: 'black',
}]
}
Live demo: https://jsfiddle.net/BlackLabel/ujyrz4h1/
API Reference: https://api.highcharts.com/highcharts/yAxis.plotLines

Control the height of a stacked column chart - Highcharts

I am trying to use this chart here JSFiddle but I want to control the height of the bars with a different number and use the values within the bar to show their percentages
This is chart in case my link doesn't work
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'right',
x: -30,
verticalAlign: 'top',
y: 25,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
},
series: [{
name: 'John',
data: [5, 3, 4, 7, 2]
}, {
name: 'Jane',
data: [2, 2, 3, 2, 1]
}, {
name: 'Joe',
data: [3, 4, 4, 2, 5]
}]
});

Remove Zero From the HIGHCHART

I have been working on Highcharts just got into one trouble the problem is when there is not any value exist for some data on the chart then it displays 0 on it which looks bad kindly checkout the following jsfiddle the labels on the chart gets populated by the following function but i am not able to put check on it that it should display only those bars whose values are above zero on the chart
http://jsfiddle.net/CzHyC/3/ [KINDLY CHECK THE APPLE section on the chart]
$(function () {
var chart;
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'blue'
}
}
},
legend: {
align: 'right',
x: -100,
verticalAlign: 'top',
y: 20,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColorSolid) || 'gray',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
formatter: function() {
return '<b>'+ this.x +'</b><br/>'+
this.series.name +': '+ this.y +'<br/>'+
'Total: '+ this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
},
series: [{
name: 'John',
data: [0, 3, 4, 7, 2]
}, {
name: 'Jane',
data: [2, 2, 3, 2, 1]
}, {
name: 'Joe',
data: [3, 4, 4, 2, 5]
}]
});
});
});
This is the way I have dealt with this situation.
When you are creating your data points, instead of putting a 0, put a null.
So for example your data array will look like:
[null,3,4,7,2] instead of [0,3,4,7,2]
Fiddle

Categories