How do you show stacks on Highchart legend rather than series? - javascript

I'm making a chart of attendance data for a project I'm working on. The data is grouped by week with a stacked column for each event. The columns are stacked by people-group (Adults, Children).
As this graph will be populated by user generated data, with no upper limit on number of people-groups, I've opted to keep the colours the same for all stacks within a column rather than generate a new colour for each new stack.
I want to be able to have the legend display the stack names [Sunday 10.30am, Sunday 6pm etc] with the associated colour, rather than the series names [Adults, Children].
Is this possible, and can it be done in such a way that hovering over each stack in the legend highlights the whole column?
Codepen
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Attendance This Month'
},
xAxis: {
categories: ['04-Apr-2021', '11-Apr-2021', '18-Apr-2021', '25-Apr-2021', '02-May-2021']
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Attendance'
}
},
tooltip: {
formatter: function () {
var stackName = this.series.userOptions.stack;
return '<b>' + stackName + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal'
}
},
colors: ['#e64980', '#e64980', '#be4bdb', '#be4bdb', '#18AABF', '#18AABF'],
series: [{
name: 'Adults',
data: [103, 110, 107, 100, 100],
stack: 'Sunday 10.30am'
}, {
name: 'Children',
data: [41, 50, 49, 32, 100],
stack: 'Sunday 10.30am'
},{
name: 'Adults',
data: [100, 108, 105, 96, 75],
stack: 'Sunday 6pm'
}, {
name: 'Children',
data: [20, 31, 29, 3, 50],
stack: 'Sunday 6pm'
},{
name: 'Adults',
data: [0, 0, 0, 0, 5],
stack: 'Wednesday 12pm'
}, {
name: 'Children',
data: [0, 0, 0, 0, 25],
stack: 'Wednesday 12pm'
}]
});
Thanks for your help!

Related

how to add new value in the tooltip?

I want to add a new value in the tooltip, but I don't want to show the value in the chart. I searched but i did not find any solution. for example:
{
show: false,
name: '利润',
type: 'bar',
label: {
show: true,
position: 'inside'
},
data: [20, 17, 24, 24]
},
{
name: '收入',
type: 'bar',
stack: '总量',
label: {
show: true
},
data: [320, 302, 341, 374]
},
{
name: '支出',
type: 'bar',
stack: '总量',
label: {
show: true,
position: 'left'
},
data: [120, 132, 101, 134]
}
can i add show:false or different things?
my echarts version is ^3.8.5.
Actually this can be done by reformatting your series data and customize tooltip formatter function. You can take a look at this case and make your own adjustment.
For example, data with higher dimension can be added like this:
data: [
['Mon', 120, 0],
['Tue', 200, 1],
['Wed', 150, 2],
['Thu', 80, 3],
['Fri', 70, 4],
['Sat', 110, 5],
['Sun', 130, 6],
],
Data with dimension index 0 and 1 will be plotted in the series, but dimension 2 will not shown.
Then make custom tooltip formatter function. For example:
formatter: function(params) {
return `
${params.seriesName}:<br />
Day: ${params.value[0]}<br />
Value: ${params.value[1]}<br />
New Value: ${params.value[2]}<br />
`
}
Complete example:
option = {
xAxis: {
type: 'category',
},
yAxis: {
type: 'value'
},
tooltip: {
trigger: 'item',
formatter: function(params) {
return `
${params.seriesName}:<br />
Day: ${params.value[0]}<br />
Value: ${params.value[1]}<br />
New Value: ${params.value[2]}<br />
`
}
},
series: [{
data: [
['Mon', 120, 0],
['Tue', 200, 1],
['Wed', 150, 2],
['Thu', 80, 3],
['Fri', 70, 4],
['Sat', 110, 5],
['Sun', 130, 6],
],
name: 'MySeries',
type: 'bar'
}]
};
Result:
See on Imgur
maybe custom series it worked but i couldn't find examples about bar chart. there is an example in the site but the example is about gantt chart.
You cannot find this one or similar settings because they should not exist. It's breaking the main dataviz concept: visualization should simplify rather than complicate the perception of data. You cannot to hide the same data for one place and show it in the another in common context. User don't understand what is the reason of this inconsistence and will stop to trusting your chart.
But if you insist, then make the desired like this:
legend: {
data: [{
name: '直接访问',
textStyle: {
color: 'red'
}
},
{
name: '邮件营销',
textStyle: {
color: 'green'
}
}
// [...]
]
}
and for hidden series:
series: [
{
name: '直接访问',
type: 'bar',
data: [0, 0, 0, 0, 0, 0, 0],
},
// {...}
]
var myChart = echarts.init(document.getElementById('main'));
var option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: [{
name: '直接访问',
textStyle: {
color: 'red'
}
},
{
name: '邮件营销',
textStyle: {
color: 'green'
}
}
// [...]
],
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'value'
},
yAxis: {
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
},
series: [{
name: '直接访问',
type: 'bar',
data: [0, 0, 0, 0, 0, 0, 0],
},
{
name: '邮件营销',
type: 'bar',
stack: '总量',
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: '联盟广告',
type: 'bar',
stack: '总量',
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: '视频广告',
type: 'bar',
stack: '总量',
data: [150, 212, 201, 154, 190, 330, 410]
},
{
name: '搜索引擎',
type: 'bar',
stack: '总量',
data: [820, 832, 901, 934, 1290, 1330, 1320]
}
]
};
myChart.setOption(option);
<script src="https://cdn.jsdelivr.net/npm/echarts#4.8.0/dist/echarts.min.js"></script>
<div id="main" style="width: 600px;height:400px;"></div>

Highcharts display percentage of hidden series

I am working with one of the Highcharts examples trying to get it to display percentage values of a hidden series.
Highcharts.chart('container', {
chart: {
type: 'area'
},
title: {
text: 'Historic and Estimated Worldwide Population Distribution by Region'
},
subtitle: {
text: 'Source: Wikipedia.org'
},
xAxis: {
categories: ['1750', '1800', '1850', '1900', '1950', '1999', '2050'],
tickmarkPlacement: 'on',
title: {
enabled: false
}
},
yAxis: {
title: {
text: 'Percent'
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.percentage:.1f}%</b><br/>',
split: true
},
plotOptions: {
area: {
stacking: 'percent',
lineColor: '#ffffff',
lineWidth: 1,
marker: {
lineWidth: 1,
lineColor: '#ffffff'
}
}
},
series: [{
name: 'Total',
data: [1000, 2000, 3000, 4000, 5000, 6000, 10500],
visable: false
}, {
name: 'Asia',
data: [502, 635, 809, 947, 1402, 3634, 5268]
}, {
name: 'Africa',
data: [106, 107, 111, 133, 221, 767, 1766]
}, {
name: 'Europe',
data: [163, 203, 276, 408, 547, 729, 628]
}, {
name: 'America',
data: [18, 31, 54, 156, 339, 818, 1201]
}, {
name: 'Oceania',
data: [2, 2, 2, 6, 13, 30, 46]
}]
});
For example in the sample code I would like to display the percentage values of Asia, Africa, Europe, America, and Oceania in terms of the series Total. So the first point for Asia would read: "Asia: 50.2%". I would also like the Total series to be completely hidden i.e. not visible in the legends on the bottom. Note that the total does not have to be a series if there is a better way of doing it, it is just the most convenient place to put it.
I think that what you are look for :
...
tooltip: {
shared:true,
formatter:function(){
var myTooltip = '<b>' + this.x + '</b>',
value,
total = 0; // Total will be calculeted from series values
(this.points).forEach(function(item){
total+=item.y; // Total incrementing
});
(this.points).forEach(function(item){
value = ((item.y / total) * 100).toFixed(2);
myTooltip += '<br/>' + item.series.name + ': ' + value + ' %';
});
myTooltip += '<br/><b>Total : ' + total +'</b>'; // Adding total to the tooltip
return myTooltip;
}
},
...
Fiddle
I got what I was looking for using some of what Core972 did. Here it is
tooltip: {
split: true,
formatter:function(){
var myTooltip = '<b>' + this.x + '</b>',
value,
total = [1000, 2000, 3000, 4000, 5000, 6000, 10500];
(this.points).forEach(function(item){
value = ((item.y / total[item.series.data.indexOf( item.point )]) * 100).toFixed(2);
myTooltip += '<br/>' + item.series.name + ': <b>' + value + '%</b>';
});
return myTooltip;
}
},

How can i show image on group columns highcharts?

I have a group chart
I want to show images on top of each
So there are only two images, so the value in xaxis subcategories if the value is negative i want to show image2 and if value is positive show image1
I have seen this answer but cant figure out this in group chart
highchart: add images to top of chart on every column
My group chart Fiddle
http://jsfiddle.net/KWPsv/90/
My Code:
Highcharts.setOptions({
colors: [
'#5a9bd4',
'#faa75b',
'#7ac36a',
'#9e67ab',
'#f15a60',
'#ce7058',
'#d77fb4'
]
});
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'column'
},
title: {
text: 'Chart Title'
},
credits: {
enabled: false
},
legend: {},
tooltip: {
shared: true,
formatter: function() {
var s = [],
xAxis = this.points[0].series.xAxis,
categoryIndex = xAxis.categories.indexOf(this.x),
title = this.x,
subTitle = xAxis.options.subtitles[categoryIndex];
s.push(title + '<br>');
s.push(subTitle + '<br>');
$.each(this.points, function(i, point) {
s.push('<span style="color:#D31B22;font-weight:bold;">' + point.series.name + ' : ' +
point.y + '<span>');
});
return s.join(' and ');
},
},
plotOptions: {
series: {
shadow: false,
borderWidth: 0,
pointPadding: 0
}
},
xAxis: {
subtitles: ['2', '-1', '4', '-3', '7'],
categories: ['MainTask 1', 'MainTask2', 'MainTask3', 'MainTask4', 'MainTask5'],
lineColor: '#999',
lineWidth: 1,
tickColor: '#666',
tickLength: 3,
title: {
text: 'X Axis Title',
style: {
color: '#333'
}
}
},
yAxis: {
lineColor: '#999',
lineWidth: 1,
tickColor: '#666',
tickWidth: 1,
tickLength: 3,
gridLineColor: '#ddd',
title: {
text: 'Y Axis Title',
rotation: 0,
margin: 50,
style: {
color: '#333'
}
}
},
series: [{
y: 0,
mydata: 10,
name: 'Designation 1',
data: [7, 12, 16, 32, 64]
}, {
y: 0,
mydata: 20,
name: 'Designation 2',
data: [16, 32, 64, 7, 12]
}, {
y: 0,
mydata: 30,
name: 'Designation 3',
data: [32, 64, 7, 12, 16],
}, {
mydata: 13,
name: 'Designation 4',
data: [7, 12, 16, 32, 64]
}, {
y: 0,
mydata: 23,
name: 'Designation 5',
data: [16, 32, 64, 7, 12]
}, {
y: 0,
mydata: 22,
name: 'Designation 6',
data: [32, 64, 7, 12, 16]
}]
});
Simply use Renderer.image to add an image on a chart. You can do that for example on load event.
API Reference:
http://api.highcharts.com/highcharts/chart.events.load
http://api.highcharts.com/highcharts/Renderer.image
Example:
http://jsfiddle.net/kudxL3kh/

Highcharts grouped bar charts with multiple axes

I was unsatisfied with the answer here:
Multiple y-axes for column graph categories in highcharts
I understand that you can create multiple y-axes can select them using yAxis:0,1,2 etc. for each series. Is it possible to do this for groups of bar graphs?
In the following example, I want 3 groups (Count A, Count B, Percent) each with 4 people (John, Joe, Jane, Janet). How do I do that in addition to having the count groups on one axes and the percent group on the other?
$('#container').highcharts({
chart: { type: 'column' },
xAxis: { categories: ['Count A', 'Count B', 'Percent']},
yAxis: [{ title: { text: 'Count' } }, { title: { text: 'Percent' }, opposite: true }],
series: [{
name: 'John',
data: [5, 3, 0.4],
}, {
name: 'Joe',
data: [3, 4, 0.6],
}, {
name: 'Jane',
data: [2, 5, 0.7],
}, {
name: 'Janet',
data: [3, 0, 0.8],
}]
});
So here's my solution to your problem.
I hope this is what you are looking for and I hope you find this helpful.
When you want to put the data into three categories with two different yAxis' you'd have to split it up in series like this. The percent is linked to the series with the values.
If you want it back to a column chart, just change the chart type to column.
http://jsfiddle.net/henrikskar/j1o450z5/
series: [{
name: 'John',
id: 's1',
data: [5, 3],
},{
//Links to id s1
linkedTo: 's1',
name: 'John',
data: [
//Puts 0.4 percent to the third category which is in the second array position
//of the categories
[2, 0.4]
],
//Assigns the percent to the second yAxis
yAxis: 1,
color: Highcharts.getOptions().colors[0]
},
Yes, this is absolutely possible, and you were on the right track with your research of multiple y-axes.
Below is a code snippet based on Highcharts' demo of stacked and grouped columns. I added a second y-axis and copied some of the demo data to assign to that axis.
Per your requirements, you'll find two sets, or stacks, of data assigned to the first/default y-axis, and a third set assigned to the second/opposite y-axis.
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Total fruit consumtion, grouped by gender'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: [{
allowDecimals: false,
min: 0,
title: {
text: 'Number of fruits'
}
},{
allowDecimals: false,
min: 0, max: 100,
title: {
text: 'Percentage of fruits'
},
opposite: true
}],
tooltip: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal'
}
},
series: [{
name: 'John',
data: [5, 3, 4, 7, 2],
stack: 'number'
}, {
name: 'Joe',
data: [3, 4, 4, 2, 5],
stack: 'number'
}, {
name: 'Jane',
data: [2, 5, 6, 2, 1],
stack: 'number2'
}, {
name: 'Janet',
data: [3, 0, 4, 4, 3],
stack: 'number2'
},{
name: 'John',
data: [45, 30, 25, 70, 5],
stack: 'percentage',
yAxis: 1
}, {
name: 'Joe',
data: [25, 15, 40, 5, 5],
stack: 'percentage',
yAxis: 1
}, {
name: 'Jane',
data: [10, 50, 30, 5, 10],
stack: 'percentage',
yAxis: 1
}, {
name: 'Janet',
data: [20, 5, 5, 20, 80],
stack: 'percentage',
yAxis: 1
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="width: 600px; height: 250px; margin: 0 auto"></div>
One piece of advice: as with line charts on different axes, you need to be clear in your documentation, color choices, or chart labels so that users know which values correspond to which axis. This is particularly needed for columns, as users will naturally compare the heights of each column to its neighbor.
I hope this is helpful for you.

Want to avoid spacing between each stacked bars in highcharts?

I am working with Highcharts and have come across a little problem that I am struggling to overcome.
I have created a jsfiddle so you can see my issue:
http://jsfiddle.net/jo_pappi/0e5h8sts/3/ [A]
As you can see
I can achieve the above format in highcharts, Since this chart is rendering based on dynamic data When a single group values arrives highcharts leaves so much space between the bars. Am attaching image here
And the code
$('#container-one').highcharts({
chart: {
type: 'bar',
events: {
click: function (event) {
console.log(event.pageX + ',' + event.pageY);
}
}
},
credits: {
enabled: false
},
title: {
text: 'Total fruit consumtion, grouped by gender'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'],
minPadding: 1.1,
maxPadding: 1.1
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Number of fruits'
}
},
tooltip: {
enabled: false,
formatter: function () {
return '<b>' + this.x + '</b><br/>' + this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
// column: {
// stacking: 'normal'
// }
series: {
pointWidth: 20,
stacking: 'normal',
borderWidth: 0,
events: {
click: function (event) {
//reloadFlash();
//$('#report').html('click on yAxis title');
console.log(event.pageX + ',' + event.pageY);
}
}
}
},
series: [{
name: 'John',
color: 'rgba(89,89,89,1)',
data: [5], // data: [5, 3, 4, 7, 4],
stack: 'male',
pointPadding: -0.0,
pointPlacement: -0.0
}, {
name: 'Joe',
color: 'rgba(255,95,215,1)',
data: [3], // data: [3, 4, 4, 2, 2],
stack: 'male',
pointPadding: -0.0,
pointPlacement: -0.0
}, {
name: 'Jane',
color: 'rgba(217,116,0,1)',
data: [2], // data: [2, 5, 6, 2, 1],
stack: 'female',
pointPadding: -0.0,
pointPlacement: -0.0
}, {
name: 'Janet',
color: 'rgba(155,215,255,1)',
data: [3], // data: [3, 0, 4, 4, 3],
stack: 'female',
pointPadding: -0.0,
pointPlacement: -0.0
}]
});
how can i reduce the spaces between bars?
If changing height of the chart is one solution means how can i achieve this dynamically?
Removing "pointWidth" solved the white space between the bars. But i need the bars should be off same height in all possible cases. I have solved the problem by setting height dynamically based on the categories count. say for example if am having only one category i have set the height for the chart as "210" and for 2 categories "270" like that. and removed pointWidth.
$('#container-one').highcharts({
chart: {
type: 'bar',
height: 210,
...
.
.
plotOptions: {
bar: {
pointPadding: 0,
borderWidth: 0
},
series: {
//pointWidth: 20,
stacking: 'normal',
.
.
});
When i have two categories i have set chart height as 270
$('#container-two').highcharts({
chart: {
type: 'bar',
height: 270,
...
.
.
plotOptions: {
bar: {
pointPadding: 0,
borderWidth: 0
},
series: {
//pointWidth: 20,
stacking: 'normal',
.
.
});
and the Fiddle Link
may be what i did was wrong. But its fixed my problem. correct me if am wrong.
Thanks all
The options you can use are:
plotOptions:{
bar:{
pointPadding: 0,
groupPadding: 0,
}
}
But you also need to not force your bar point width.
Remove:
series: {
pointWidth: 20,
http://jsfiddle.net/d9f8b22x/
The API docs discuss how these options relate to each other:
http://api.highcharts.com/highcharts#plotOptions.column.pointPadding
What are you using 'pointWidth: 20' in series for ?? That is creating the problem.. Also you are giving the categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'] even if the data comes for only apples.. one solution would be to generate the categories dynamically.. say for example if data comes only for apples push only apples in the categories array. Then after that you can use :
_chart.setSize(width,height)
method to dynamically set the new height and width of the highchart. Also removing pointWidth will solve the problem ...

Categories

Resources