is there any way to add tooltip to the stackedLabels in highcharts, like in the below example:
I have male, female as my stack names and I am dispalying them at the bottom of the chart..however in case they are long names, I'm adding ellipsis, in such case is there a way to see the entire name on hover inside tooltip?
fiddle:
http://jsfiddle.net/rq8m7e0v/
code:
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas', "getete"]
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
verticalAlign: 'bottom',
y:90,
enabled: true,
formatter: function() {
return this.stack;
}
}
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true
}
}
},
series: [{
name: 'John',
data: [53, 33, 43,63,7,83],
stack: 'male'
}, {
name: 'Joe',
data: [33, 43,43,63,73,8],
stack: 'female'
}, {
name: 'Jane',
data: [42, 54,43,62,74,84],
stack: 'male',
}, {
name: 'Janet',
data: [34, 40, 42,36,74,83],
stack: 'female',
}]
});
Highcharts doesn't have built-in tooltip for stack label, but still you can create your own tooltip for that. It's simple to add custom events to legendItem (mouseover and mouseout for example) and show that tooltip.
events: {
load: function() {
var stackLabels = this.yAxis[0].stacking.stackTotalGroup.element.children,
somePoint = this.series[0].points[0],
chart = this;
for (let i = 0; i < stackLabels.length; i++) {
stackLabels[i].addEventListener('mouseover', function() {
// show custom tooltip
});
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/orqyLjct/
API: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts
Related
I am trying to get my highcharts graph to look like this or similar to this.
I have tried to use groupped category addon for highcharts, but it down not seem to work well with stack option.
sample in JSFiddle: http://jsfiddle.net/02ey1hbr/7/
Highcharts.chart('container', {
chart: {
type: 'bar'
},
title: {
text: 'Stacked bar chart'
},
xAxis: {
labels: {
rotation: -0,
style: {
fontSize: '10px',
align: 'Right',
}
},
categories: [{
name: "Case A",
categories: ["Male", "Female"]
}, {
name: "Case B",
categories: ["Male", "Female"]
}]
},
yAxis: {
min: 0,
title: {
text: 'x-axis'
}
},
legend: {
reversed: true
},
plotOptions: {
bar: {
stacking: 'normal'
}
},
series: [{
name: 'x',
data: [5,3,4,5],
stack: 'StackA'
}, {
name: 'y',
data: [3,5,4,5],
stack: 'StackA'
},{
name: 'x',
data: [5,3,4,5],
stack: 'StackB'
}, {
name: 'y',
data: [3,5,4,5],
stack: 'StackB'
}
]
});
To display bar the way you want, you need to get rid of the stack property from all series. Why do you want to preserve them? They are used for dividing series into groups. I also corrected position of labels using x property.
API Reference:
http://api.highcharts.com/highcharts/series%3Ccolumn%3E.stack
http://api.highcharts.com/highcharts/xAxis.labels.x
Example:
http://jsfiddle.net/sjtdgq9L/
Within my project, using stacks allows me to get better control over the 12 data sets in a series that is split into 2 stacks. Example in jsfiddle is a smaller version to get the proof of concept working and better interact with community. Stacks also make the code much easier to maintain.
Using: Proper x-axis for Highcharts stack group column as a reference, i was able to modify my example to: http://jsfiddle.net/02ey1hbr/11/ and achieve a working example with stacks. Its not perfect but really close to.
Highcharts.chart('container', {
chart: {
type: 'bar'
},
title: {
text: 'Stacked bar chart'
},
xAxis: [{
categories: ["Case A", "Case B","Case C", "Case D"],
labels: {
rotation: -90,
x: -60,
style: {
fontSize: '10px',
align: 'Right',
}
},
tickWidth: 1,
tickLength: 60,
},
{
categories: ['Male', 'Female','Male', 'Female','Male', 'Female','Male', 'Female'],
opposite: false,
labels: {
rotation: 0,
x: 60,
style: {
fontSize: '10px',
align: 'Right',
}
},
tickWidth: 0,
}],
yAxis: {
min: 0,
title: {
text: 'x-axis'
}
},
legend: {
reversed: true
},
plotOptions: {
bar: {
stacking: 'normal'
}
},
series: [{
name: 'x',
data: [1,8,9,16],
stack: 'StackA'
}, {
name: 'y',
data: [1,7,10,15],
stack: 'StackA'
},{
name: 'x',
data: [3,6,11,14],
stack: 'StackB'
}, {
name: 'y',
data: [4,5,12,13],
stack: 'StackB'
},
{
name: '',
data: [0,0,0,0,0,0,0,0],
showInLegend: false,
stack: 'StackB',
xAxis: 1
}
]
});
Change your series to:-
series: [{
name: 'x',
data: [5,3,4,5]
}, {
name: 'y',
data: [3,5,4,5]
},{
name: 'x',
data: [5,3,4,5]
}, {
name: 'y',
data: [3,5,4,5]
}
]
On legendItemClick, how do I prevent subtraction of legend item value from total and instead add the value to another legend item.
E.g. I would like the 'Other Fruit' series to contain all switched off fruit series (the same with 'Other Veg' series).
Here is the Fiddle
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: ['Then', 'Now']
},
yAxis: {
min: 0,
title: {
text: 'Total 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: {
series: {
events: {
legendItemClick: function () {
//if fruit/veg is clicked then add value to other fruit/veg and keep the total unchanged
// return false;
}
}
},
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
formatter:function() {
return this.series.name+' '+this.point.y;
},
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black'
}
}
}
},
series: [{
name: 'Other Fruit',
data: [8, 13]
},{
name: 'Other Veg',
data: [16, 10]
},{
name: 'Tomatoes',
data: [3, 7]
},{
name: 'Cucumbers',
data: [5, 4]
},{
name: 'Apples',
data: [5, 3]
}, {
name: 'Bananas',
data: [3, 6]
}, {
name: 'Oranges',
data: [3, 4]
}]
});
});
Things we need to do
Series should be categorized as fruit and vegetables, so that we know which others series("Other Fruit" or "Other Veg") to add/subtract value from.
When the legend item is clicked, check if it's a fruit or a veggie and add the value to others.
When clicked again, subtract the values from others.
We should not be able to hide the others series.
series: [{
name: 'Other Fruit',
data: [{y:8}, {y:13}],
},{
name: 'Other Veg',
data: [{y:16}, {y:10}]
},{
name: 'Tomatoes',
data: [{y:3}, {y:7}],
fruit: false
},{
name: 'Cucumbers',
data: [{y:5}, {y:4}],
fruit: false
},{
name: 'Apples',
data: [{y:5}, {y:3}],
fruit: true
},{
name: 'Bananas',
data: [{y:3}, {y:6}],
fruit: true
},{
name: 'Oranges',
data: [{y:3}, {y:4}],
fruit: true
}]
Added a property "fruit" to all series except "Other Fruit" and "Other Veg".
legendItemClick: function () {
var isFruit = this.options.fruit;
if(isFruit == undefined){ //property undefined for "Other fruit" and "Other Veg"
return false; //returning false prevents hiding the series
}
var chart = this.chart;
var othersSeries;
if(isFruit){
othersSeries = chart.series[0]; //if it's a fruit, get "Other Fruit" series
}
else{
othersSeries = chart.series[1]; //else get "Other Veg" series
}
updateOthersData(this, othersSeries);
}
function updateOthersData(currentSeries, othersSeries){
var othersData = othersSeries.options.data;
if(currentSeries.visible){ //add values only when the series is already visible and is to be hidden
othersData[0].y += currentSeries.options.data[0].y;
othersData[1].y += currentSeries.options.data[1].y;
}
else{ //subtract values only when data is already hidden and is to be shown
othersData[0].y -= currentSeries.options.data[0].y;
othersData[1].y -= currentSeries.options.data[1].y;
}
othersSeries.update({data:othersData}); //update the series
}
Here is the fiddle.
Im creating a stacked Highcharts bar chart. Within each bar, I want to have custom text. However, highcharts is only displaying the data number.
The fiddle is here.
My code is:
$(function () {
$('#container').highcharts({
chart: {
type: 'bar'
},
title: {
text: 'Stacked bar chart'
},
xAxis: {
categories: ['Apples', 'Oranges']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
}
},
legend: {
reversed: true
},
plotOptions: {
series: {
stacking: 'normal'
},
bar: {
dataLabels: {
enabled: true
}
}
},
series: [{
name: 'John',
data: [['test 1', 5], ['test 2', 3]]
}, {
name: 'Jane',
data: [['test 3', 2], ['test 4', 2]]
}]
});
});
I want 'test 1', 'test 2' etc is appear within the bar chart (they do appear on the popover). But instead, the data numbers, i.e. 5, 3, 2, ans 2, appears there. Can this be done?
See working fiddle with your data here
Use formatter function :
bar: {
dataLabels: {
formatter: function(){
return this.point.name
},
enabled: true
}
}
I'd like to have the lines linking each data block, like the attached screenshot from Excel. Even better would be if the line could change color based on it's angle. I can't seem to find anything in the documentation to create this style chart. Any ideas?
JSFiddle - Same Bar Chart (without connectors)
$(function () {
$('#container').highcharts({
chart: {
type: 'bar'
},
title: {
text: 'Stacked bar chart'
},
xAxis: {
categories: ['Row1', 'Row2']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
}
},
legend: {
reversed: false
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
name: 'Data1',
data: [9, 4]
}, {
name: 'Data2',
data: [12, 6]
}, {
name: 'Data3',
data: [15, 7]
}, {
name: 'Data4',
data: [16, 8]
}, {
name: 'Data5',
data: [19, 7]
}]
});
});
I am trying to create a Column chart using Highcharts that show multiple series for one point in time only and I would like to show show the name of the series on the x-axis as well as being able to hide and show each series using the legend.
The closest I have been able to get to what I'm trying to achieve is by adding the categories and having multiple series.
xAxis: {
categories: [
'Tokyo',
'New York',
'London',
'Berlin'
]
}
and then adding multiple series with only one data point in each series
series: [{
name: 'Tokyo',
data: [49.9, null,null,null]
}, {
name: 'New York',
data: [null, 83.6,null,null]
}, {
name: 'London',
data: [null, null, 48.9,null]
}, {
name: 'Berlin',
data:[null, null, null, 42.4]
}]
The problem is that while this only shows one series for each point on the x-axis, Highcharts allocates space for each of the other series and when hiding a series only the series will be hidden not the label on the x-axis.
link to jsfiddle is here: http://jsfiddle.net/md2zk/
Set grouping: false in plotOptions, see: http://jsfiddle.net/Fusher/md2zk/5/
it's possible to hide Category along with the column.please go through the link given below . hope this will help.
http://jsfiddle.net/md2zk/633/
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Monthly Average Rainfall'
},
subtitle: {
text: 'Source: WorldClimate.com'
},
xAxis: {
type: 'category',
},
yAxis: {
min: 0,
title: {
text: 'Rainfall (mm)'
},
},
plotOptions: {
series: {
grouping: false,
events: {
legendItemClick: function () {
debugger;
if (this.visible) {
this.setData([], false)
}
else {
this.setData([this.chart.series[this.index].userOptions], true);
}
}
},
borderWidth: 0,
dataLabels: {
enabled: true,
//style: {
// color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
//},
},
},
},
series: [{
name: 'Tokyo',
data: [{name : 'Tokyo',y:49.9}],
y: 49.9
}, {
name: 'New York',
data: [{name : 'New York',y:83.6}],
y: 83.6
}, {
name: 'London',
data: [{name : 'London',y:48.9}],
y: 48.9
}, {
name: 'Berlin',
data:[{name : 'Berlin',y: 42.4}],
y: 42.4
}],
navigation: {
buttonOptions: {
enabled: true
}
}
});
});