I am trying to plot multiple column graphs on the same chart, stacked on each other. This is an example of desired output.
Each colored column segment represents percent of team to have reached a given level by the end of the given month. So it's like 4 separate column charts stacked. I think this is different than grouped and stacked, but may be mistaken.
Thanks for any feedback.
This can be done with a combination of stacked and column range. There are a few caveats with this in that you have to have a category for your yAxis which causes some funkiness with how you set your series' data values. I opted for one method and I am sure there are others. What I did was first set the chart type to 'columnrange':
chart: {
type: 'columnrange'
},
Then I set up the yAxis properties to use categories:
yAxis: {
categories: ['Level 0', 'Level 1', 'Level 2', 'Level 3'],
Since the offset of the category is in-between the tick marks of the axis I removed them and set the start position to not be on the tick:
startOnTick: false,
min: .5,
gridLineWidth: 0,
Up next I have to set the format of the labels (essentially just hiding the first label):
labels: {
formatter: function() {
var label = this.axis.defaultLabelFormatter.call(this);
if (!this.isFirst) {
return label;
}
}
},
Now I create plotLines to mimic the gridlines with the last one a different color to denote the "Target":
plotLines: [{
color: '#e6e6e6',
width: 1,
value: 1
}, {
color: '#e6e6e6',
width: 1,
value: 2
}, {
color: 'red',
width: 2,
value: 3,
label: {
text: 'Target'
}
}]
Now I setup the plotOptions for this chart. Note that the stacking parameter is not listed in the API as being part of the columnrange type but it still functions (as of this answer using v5.0):
plotOptions: {
columnrange: {
stacking: true
}
},
Okay, almost there. I then set up the series data:
series: [{
name: 's1',
data: [
[0, .64],
[0, .9],
[0, 1]
]
}, {
name: 's2',
data: [
[null, null],
[1, 1.1],
[1.0, 1.5]
]
}, {
name: 's3',
data: [
[null, null],
[null, null],
[2.0, 2.5]
]
}]
The important part of the data values is that each "level" is a whole integer such that Level 1 is from 0 to 1 and Level 2 is from 1 to 2 and Level 3 is from 2 to 3. This works out good as you try to determine your percentage in each level for each month as they are still in uniform increments.
I did not modify the tooltip as you gave no specs on that.
Sample jsFiddle and full code:
$(function() {
Highcharts.chart('container', {
chart: {
type: 'columnrange'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
categories: ['Level 0', 'Level 1', 'Level 2', 'Level 3'],
startOnTick: false,
min: .5,
gridLineWidth: 0,
title: {
text: null
},
labels: {
formatter: function() {
var label = this.axis.defaultLabelFormatter.call(this);
if (!this.isFirst) {
return label;
}
}
},
plotLines: [{
color: '#e6e6e6',
width: 1,
value: 1
}, {
color: '#e6e6e6',
width: 1,
value: 2
}, {
color: 'red',
width: 2,
value: 3,
label: {
text: 'Target'
}
}]
},
plotOptions: {
columnrange: {
stacking: true
}
},
legend: {
enabled: true
},
series: [{
name: 's1',
data: [
[0, .64],
[0, .9],
[0, 1]
]
}, {
name: 's2',
data: [
[null, null],
[1, 1.1],
[1.0, 1.5]
]
}, {
name: 's3',
data: [
[null, null],
[null, null],
[2.0, 2.5]
]
}]
});
});
Related
I'm trying to implement a chart with different series but each series will have a value for different categories independently.
What I want to have:
What I have today:
With the following code:
document.addEventListener('DOMContentLoaded', function () {
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Fruit Consumption'
},
xAxis: {
categories: ['a1', 't1', 't2', 'l1', 'l2', 'p1']
},
yAxis: {
title: {
text: 'Fruit eaten'
}
},
series: [{
name: 'a',
data: [267]
},{
name: 't',
data: [0, 21, 400]
},{
name: 'l',
data: [0, 0, 0, 600, 242]
},{
name: 'p',
data: [0, 0, 0, 0, 0, 1000]
}],
});
});
There is free space between bars because series has 0 as values for some category.
I just want to have a "nice" chart with all columns one by one.
Maybe, it's a different way to configure series and categories...
Disable grouping:
plotOptions: {
series: {
grouping: false
}
}
Live demo: http://jsfiddle.net/BlackLabel/x6758dcq/
API Reference: https://api.highcharts.com/highcharts/plotOptions.column.grouping
The Highchart graph code is shown below I want every bar label color is different. Currently, I'm getting the same color in bar
Highcharts.chart('container', {
chart: {
type: 'column',
},
title: {
text: 'Popular '
},
credits:{
enabled:false
},
xAxis: {
max: 20,
type: 'category',
style:{
fontSize: '12px'
}
},
yAxis: {
min: 0,
allowDecimals:false,
title: {
text: 'Number of applications',
style:{
fontSize: '12px'
}
},
gridLineWidth:0,
minorGridLineWidth: 0,
tickLength: 5,
tickWidth: 1,
tickPosition: 'inside',
lineWidth:1
},
scrollbar: {
enabled: true
},
legend: {
enabled: false
},
tooltip: {
pointFormat: 'hi'
},
series: [{
name: Stats',
data: data,
color:'#2ecc71',
pointWidth: 25,
}],
Data format is :
[
[
"Qualcom",
17
],
[
"The ram",
12
],
[
"Aoperty",
8
],
[
"Ob.",
8
],
[
"Sugh",
8
],
]
The output is shown in the picture I want every bar is in a different color can you help me?
Referring to comments you can set a specific color to a single point by adding a color property programmatically to its object like that:
series: [{
data: [
["Qualcom", 17],
{
name: "The ram",
y: 12,
color: 'red'
},
["Aoperty", 8],
["Ob.", 8],
["Sugh", 8]
],
color: '#2ecc71'
}]
API reference:
https://api.highcharts.com/highcharts/series.column.data.color
Demo:
https://jsfiddle.net/BlackLabel/craqy1sv/1/
If you want to add a specific color to a point when a condition is matched you can loop through each series point in chart load event and update a matched point:
chart: {
type: 'column',
events: {
load: function() {
var chart = this,
series = chart.series[0];
series.points.forEach(function(point) {
if (point.name === 'The ram') {
point.update({
color: 'red'
})
}
});
}
}
}
API reference:
https://api.highcharts.com/highcharts/chart.events.load
https://api.highcharts.com/class-reference/Highcharts.Point#update
Demo:
https://jsfiddle.net/BlackLabel/jmuoevz1/
You need to set colorByPoint :true to use different colors like that
series: [{
name: 'Stats',
data: [
[
"Qualcom",
17
],
[
"The ram",
12
],
[
"Aoperty",
8
],
[
"Ob.",
8
],
[
"Sugh",
8
]
],
colorByPoint: true,
pointWidth: 25,
}]
Fiddle
I adapted the highcharts population pyramid (https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/bar-negative-stack/) as follows:
I omitted the option "categories", instead used the option "type: 'category'" and added the categories to the data series. I want to do this because the data comes as a tuple from a file. Unfortunately, the right-hand x-axis is not labeled correctly. I want the right hand x-axis labeled same as the left one. Is this possible without using the option "categories"?
Here is the jsfiddle: https://jsfiddle.net/nehqb9k4/
chart : {
renderTo: 'container',
type: 'bar',
height: 480,
},
xAxis : [{
type: 'category',
reversed: false,
}, { // mirror axis on right side
type: 'category',
opposite: true,
linkedTo: 0,
reversed: false,
}],
yAxis: {
title: {
text: null
},
labels: {
formatter: function () {
return Math.abs(this.value) + '%';
}
}
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
name: 'Male',
data: [
['0-4', -2.2],
['5-9', -2.1],
['10-14', -2.2],
['15-19', -2.4],
['20-24', -2.7],
['25-29', -3.0],
['30-34', -3.3],
['35-39', -3.2],
['40-44', -2.9],
['45-49', -3.5],
['50-54', -4.4],
['55-59', -4.1],
['60-64', -3.4],
['65-69', -2.7],
['70-74', -2.3],
['75-79', -2.2],
['80-84', -1.6],
['85-89', -0.6],
['90-94', -0.3],
['95-99', -0.0],
['100 +', -0.0]
]
}, {
name: 'Female',
data: [
['0-4', 2.1],
['5-9', 2.0],
['10-14', 2.1],
['15-19', 2.3],
['20-24', 2.6],
['25-29', 2.9],
['30-34', 3.2],
['35-39', 3.1],
['40-44', 2.9],
['45-49', 3.4],
['50-54', 4.3],
['55-59', 4.0],
['60-64', 3.5],
['65-69', 2.9],
['70-74', 2.5],
['75-79', 2.7],
['80-84', 2.2],
['85-89', 1.1],
['90-94', 0.6],
['95-99', 0.2],
['100 +', 0.0]
]
}]
You need to set the right xAxis for the second series:
series: [{
// xAxis: 0 by default
name: 'Male',
data: [
...
]
}, {
name: 'Female',
xAxis: 1,
data: [
...
]
}]
Live demo: https://jsfiddle.net/BlackLabel/70yv1Lae/
API: https://api.highcharts.com/highcharts/series.bar.xAxis
I use highcharts for a chart. I made series with "linkedTo" because I need to group the columns by region and generate a legend displaying these regions. Until then, the result is the desired one. But I can not display the name of my categories on the X axis. Under each column there should be "A", "B", ... As in the picture. See the jsfiddle for the code. Thank you for your help.
http://jsfiddle.net/yucca/hpkLy6t0/24/
// Create the chart
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'TEST'
},
subtitle: {
text: 'TEST'
},
xAxis: {
type: 'category',
categories: ['A', 'B', 'C', 'D']
},
legend: {
enabled: true,
labelFormatter: function() {
return this.userOptions.id
}
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: false,
}
}
},
tooltip: {
headerFormat: '<span style="font-size:11px">{series.name}</span><br>',
pointFormat: '<span style="color:{point.color}">{point.name}</span>: <b>{point.y:.2f}%</b> of total<br/>'
},
series: [
{
id:'China',
color: '#004f9e',
data: [1100]
},
{
id:'International',
color: '#e73357',
data: [10]
},
{
linkedTo: 'International',
color: '#e73357',
data: [1000]
},
{
linkedTo: 'China',
color: '#004f9e',
data: [686]
}
]
});
graph
You need to make a slight alteration to your series in order for this to work.
series: [{
data: [{
id:'China',
color: '#004f9e',
y: 1100
},{
id:'International',
color: '#e73357',
y: 10
},{
linkedTo: 'International',
color: '#e73357',
y: 1000
},{
linkedTo: 'China',
color: '#004f9e',
y: 686
}],
}]
What I did is the following:
I changed the data[] so it holds an array of your values.
I changed the values stored as data: [686] to y: 686
Here you can find a working JSFiddle
I am using Highcharts and would like to combine 2 types of chart.
I would like a Bar with negative stack (changing the chart type to column) combined with Column with negative values so for each category, I have both positive and negative values.
I can't find any example of doing this so I don't even know if this is possible.
I did have a thought about doing something with the series like nested series but again don't know if this is possible and can't find an example.
If what I'm trying to do possible?
Column with negative values
// Age categories
var categories = [
'0-4', '5-9', '10-14', '15-19',
'20-24', '25-29', '30-34', '35-39', '40-44',
'45-49', '50-54', '55-59', '60-64', '65-69',
'70-74', '75-79', '80-84', '85-89', '90-94',
'95-99', '100 + '
];
Highcharts.chart('container', {
chart: {
type: 'bar'
},
title: {
text: 'Population pyramid for Germany, 2015'
},
subtitle: {
text: 'Source: Population Pyramids of the World from 1950 to 2100'
},
xAxis: [{
categories: categories,
reversed: false,
labels: {
step: 1
}
}, { // mirror axis on right side
opposite: true,
reversed: false,
categories: categories,
linkedTo: 0,
labels: {
step: 1
}
}],
yAxis: {
title: {
text: null
},
labels: {
formatter: function () {
return Math.abs(this.value) + '%';
}
}
},
plotOptions: {
series: {
stacking: 'normal'
}
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + ', age ' + this.point.category + '</b><br/>' +
'Population: ' + Highcharts.numberFormat(Math.abs(this.point.y), 0);
}
},
series: [{
name: 'Male',
data: [-2.2, -2.2, -2.3, -2.5, -2.7, -3.1, -3.2,
-3.0, -3.2, -4.3, -4.4, -3.6, -3.1, -2.4,
-2.5, -2.3, -1.2, -0.6, -0.2, -0.0, -0.0]
}, {
name: 'Female',
data: [2.1, 2.0, 2.2, 2.4, 2.6, 3.0, 3.1, 2.9,
3.1, 4.1, 4.3, 3.6, 3.4, 2.6, 2.9, 2.9,
1.8, 1.2, 0.6, 0.1, 0.0]
}]
});
Bar with negative stack
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Column chart with negative values'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
credits: {
enabled: false
},
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]
}]
});
Thanks to #Pawel Fus, I was able to do what I wanted and to remove the duplicate legend labels, I added showInLegend: false, in the series I wanted to hide the legend
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Column chart with negative values'
},
colors: Highcharts.getOptions().colors.splice(0, 3),
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
credits: {
enabled: false
},
plotOptions: {
series: {
stacking: true
}
},
series: [{
stack: 'john',
name: 'John',
data: [5, 3, 14, 7, 2]
}, {
stack: 'jane',
name: 'Jane',
data: [2, 12, 3, 2, 1]
}, {
stack: 'joe',
name: 'Joe',
data: [3, 4, 4, 2, 5]
}, {
showInLegend: false,
stack: 'john',
name: 'John',
data: [-5, -3, -4, -7, -2]
}, {
showInLegend: false,
stack: 'jane',
name: 'Jane',
data: [-2, -2, -3, -2, -1]
}, {
showInLegend: false,
stack: 'joe',
name: 'Joe',
data: [-3, -4, -4, -2, -5]
}]
});