Highcharts PieChart Legend paging faulty - javascript

Creating a few pie charts using Highcharts which render fine, however the legend does not swap between pages. It updates the page number (E.g. 1/4 -> 2/4 -> 3/4) but the contents of the legend does not change.
I have used code from http://jsfiddle.net/qegmnsm7/ and simply passed my own data into it; giving this code:
var areaOptions = {
chart: {
renderTo: 'areaPie',
defaultSeriesType: 'pie',
width: 900,
height: 600
},
title: {
text: "Test Pie Chart."
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
y: 30,
navigation: {
activeColor: '#3E576F',
animation: true,
arrowSize: 12,
inactiveColor: '#CCC',
style: {
fontWeight: 'bold',
color: '#333',
fontSize: '12px'
}
}
},
exporting: {
buttons: {
printButton: {
enabled: false
}
}
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
color: '#000000',
connectorColor: '#000000',
formatter: function () {
return Math.round(this.percentage) + '% (' + this.y + ')';
}
},
showInLegend: true
, point: {
events: {
legendItemClick: function () {
filterList(this);
this.select();
return false;
},
click: function () { filterList(this); }
}
}
},
series: [{
type: 'pie',
name: 'Banana',
data: []
}]
}
};
areaOptions.series = #Html.Raw(ViewBag.Area);
var areaChart = new Highcharts.Chart(areaOptions);
areaChart.render();
Giving this:
However upon clicking the 'down' arrow, the legend stays exactly the same - apart from 1/2 changes to 2/2.
I have used the example code linked above in my application and it works perfectly; therefore I expected simply updating the data input to work. However something is messing it up and I can't find any other users' questions or google links to help.
What am I doing wrong that stops the legend from paging properly?
Edit: Here is a JSFiddle showing exactly what I mean.

areaChart.render(); is not a part of official API and is causing the problem with legend paging. Removing this part of code will fix you issue.
Fixed code in JSFiddle: https://jsfiddle.net/kfdoxscx/9/

Related

Is it possible to display the label of each bar outside the upper bound of a bar chart using react-apexcharts?

I am editing a bar chart that should display the values ​​above each bar. I need the values ​​to be displayed outside the upper limit of the chart. I managed to get this graph:
chart i have
However, I need the values ​​to be displayed as if it were a double x-axis (my understanding is that apexchart only has double-axis implemented for the y-axis). In a nutshell, I need this:
chart i need
I managed to move the labels to the top using "offsety" inside "datalabels" in my chart options, but they stay inside the chart, sitting right on the line of the maximum value of the y-axis (and I need them to be located above this line ).
These are my chart options:
const options = {
grid: {
position: 'front'
},
legend:{
position: "bottom",
horizontalAlign: "right",
offsetY: 10
},
colors:["#59ad30","#134E32","#3A7B05","#59AD31"],
chart: {
toolbar:{show:false},
type: 'bar',
height: 350
},
plotOptions: {
bar: {
dataLabels: {
position: 'top',
},
columnWidth: `${categorias.length*13}%`,
},
},
dataLabels: {
enabled: true,
formatter: function (val, opts) {
return `${val.toFixed(1)} Lt`
},
offsetY: -1000,
style: {
fontSize: '11px',
fontFamily: 'Roboto, Helvetica, Arial, sans-serif',
fontWeight: undefined,
colors: ["#000000"]
},
},
stroke: {
show: true,
width: 2,
colors: ['transparent']
},
xaxis: {
categories: categorias,
labels:{
style: {
fontWeight: "bold",
},
}
},
yaxis: {
labels: {
formatter: function(val) {
return `${Math.floor(val)} Lt`
}
}
},
fill: {
opacity: 1
},
tooltip: {
y: {
formatter: function (val) {
return `${val} lts`
}
}
}
};
apexcharts version: "^3.35.3"
react-apexcharts version: "^1.4.0"

In Highcharts, my dataLabels disappear when re-enabling the rightmost element of my chart

I'm using react-highcharts to draw a relatively simple column chart for some work data. The bosses wanted it set up so that hiding an item on the legend will adjust the scale, even if the element is in the middle of the chart. I followed this fiddle from the highcharts forum to make my data vanish and reappear. Great, everything works! But I have a bug I can't pin down in my code.
Whenever I remove and then return the rightmost visible element, the second-from-the-right element loses its data label.
I'm reasonably certain that the issue lies in my HighCharts options object. Here it is below:
const highChartsOptionsObject= {
chart: {
type: "column",
style: {
fontFamily: "helvetica",
},
height: 300,
},
title: {
text: null,
},
xAxis: {
allowDecimals: true,
type: "category",
crosshair: true,
},
yAxis: {
min: 0,
title: {
text: getLabel(),
},
labels: {
formatter: getLabelString()
},
},
},
credits: {
enabled: false,
},
legend: {
enabled: true,
},
tooltip: {
formatter: function () {
return `
<b>${this.point.name}</b><br />
${
getTooltip();
}
`;
},
},
plotOptions: {
column: {
stacking: "normal",
pointPadding: 0.3,
borderWidth: 0,
dataLabels: {
enabled: true,
crop: false,
overflow: "none",
formatter: function () {
const labelString = "hard coded test";
return labelString;
},
},
},
series: {
cursor: "pointer",
events: {
legendItemClick: function () {
if (this.visible) {
this.setData([], false);
} else {
let elementData = getSeries()[this.index].data[0];
this.setData([{ ...elementData }], false);
}
},
},
},
},
series: getSeries(),
};
For reference, my other highcharts options are: immutable: true and allowChartUpdate: true
Happy to provide more information if someone thinks that something else is relevant, I just need to sanitize it somewhat to go on SO.
I did some googling, and I identified my issue finally. During transitions, the data labels on the columns overlap. If you have not set allowOverlap to true for data labels, then it will default to false. Since the transition causes overlap, highcharts will set one of the datalabels to be invisible/not show up.
This can be fixed easily enough by just setting:
dataLabels:{
allowOverlap: true
}

Responsive Highchart legend position

Is there a way to have the Highcharts Pie chart to bring down the legend when the screen size is small. Please see attached image for reference.
Here is a sample image when the screen is big.
This would what it looked like when in small screen or small device
Is this possible to achieve? Thanks for your help.
You could check the window width before creating the chart and using that information to set the alignment of the legend. For example (JSFiddle):
var isBig = $(window).width() > 700;
var legendBig = {
align: 'right',
verticalAlign: 'middle',
layout: 'vertical'
};
var legendSmall = {
align: 'center',
verticalAlign: 'bottom',
layout: 'horizontal'
}
$('#container').highcharts({
legend: isBig? legendBig : legendSmall,
// ...
});
This is an old post, but since I ran into it, it's likely that someone else will at some point. I found out that since Highcharts 5 you can configure options for responsive behavior: https://www.highcharts.com/docs/chart-concepts/responsive, so this is the way to go now.
Here is the config I used to achieve this effect:
{
chart: {
type: 'pie',
},
legend: {
layout: 'vertical',
squareSymbol: false,
symbolRadius: 0,
},
plotOptions: {
pie:
showInLegend: true,
},
},
responsive: {
rules: [{
condition: {
minWidth: 700,
},
chartOptions: {
legend: {
align: 'right',
verticalAlign: 'top',
}
}
}]
},
}
Since you are asking for a responsive layout I've made a little fiddle which listens to the resize event and changes to legend attributes accordingly.
Not sure if it will work that well (the legend may need some adjusting in each position) but the spirit is the following:
$(function () {
$(document).ready(function () {
$(window).resize(function () {
var chart = $('#container').highcharts();
var isBig = chart.chartWidth > 450;
console.log(chart.chartWidth);
if (isBig) {
chart.legend.options.align = "right";
chart.legend.options.verticalAlign = "middle";
chart.legend.options.layout = "vertical";
chart.isDirtyLegend = true;
} else {
chart.legend.options.align = "center";
chart.legend.options.verticalAlign = "bottom";
chart.legend.options.layout = "horizontal";
chart.isDirtyLegend = true;
}
});
// Build the chart
$('#container').highcharts({
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'Browser market shares January, 2015 to May, 2015'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
legend: {
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
}
},
series: [{
name: 'Brands',
colorByPoint: true,
data: [{
name: 'Microsoft Internet Explorer',
y: 56.33
}, {
name: 'Chrome',
y: 24.03,
sliced: true,
selected: true
}, {
name: 'Firefox',
y: 10.38
}, {
name: 'Safari',
y: 4.77
}, {
name: 'Opera',
y: 0.91
}, {
name: 'Proprietary or Undetectable',
y: 0.2
}]
}]
});
$(window).trigger("resize");
});
});
On each resize the chart width is checked and if it's below a threshold the legend changes position attributes.
When the chart is redrawn (which it would when its container gets smaller) it the legend is drawn correctly.
Example fiddle: https://jsfiddle.net/9xfL6rz1/2/

Highcharts 3D Pie color rendering

I facing a strange problem while generating a 3D-Pie chart using highcharts. The colors on different slices are not loading initially and are displaying only after mouse hover.
Code snippet:
module.pieChart = function (divid, title, subTitle, seriesData) {
//seriesData is in form of json
window[divid] = new Highcharts.Chart({
chart: {
renderTo: divid,
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
credits: {
enabled: false
},
title: {
text: title
},
subtitle: {
text: subTitle
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
}, legend: {
enabled: true
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
color: '#000000',
connectorColor: '#000000',
formatter: function () {
return '<b>' + this.point.name + '</b>: ' + this.percentage.toFixed(2) + ' %';
}
},
showInLegend: true
}
},
series: [{
type: 'pie',
name: title,
data: seriesData
}]
}, NodataMessage);
};
If anyone have any suggestions or solution to it.?
EDIT
DEMO
Its about Highcharts.getOptions().colors. This function generate 10 colors, and after tenth, colors list is null. And you try to push color like this:
// there is no color for i > 9
color:data[i].color;
Highcharts.getOptions().colors output is : ["#7cb5ec", "#434348", "#90ed7d", "#f7a35c", "#8085e9", "#f15c80", "#e4d354", "#8085e8", "#8d4653", "#91e8e1"]
So, you should remove it from your options, or manually define it.
and working example:
DEMO
The problem is as #AliRıza Adıyahşi said - length of colors array. Simple solution is to take width of colors array, then instead of colors[i] use colors[i % colors.length]. See live demo: http://jsfiddle.net/nQ8k8/4/
Or just don't set colors, let Highcharts do that for you: http://jsfiddle.net/nQ8k8/5/

Justify stack labels

I am having problems with my stack labels. I have them rotated -90 degrees and I have set align to left and vertical align to bottom. But for some reason the label is aligned to the bottom of each column but not as I expected it to do. The center of the text label is align to the bottom, not the first letter of the label. Is there a way to accomplish what I want without manually calculating the y offset for each individual stack label? And if not, how would I best do that tiresome calculation?
See attached fiddle:
$(function () {
$('#container').highcharts({
chart: { type: 'column' },
title: { text: '' },
xAxis: { categories: [""] },
yAxis: [{
title: { text: '', style: { color: '#4572A7'} },
labels: {
formatter: function () { return Highcharts.numberFormat(this.value, 0) + " USD" },
style: { color: '#4572A7' }
},
stackLabels: {
enabled: true,
style: { fontSize: '1.5em', fontWeight: 'bold', color: 'black' },
formatter: function () { return this.stack; },
rotation: -90, x: -5,
verticalAlign: 'bottom',
align: 'left'
}}],
legend: { borderWidth: 1, shadow: false },
plotOptions: {
column: { stacking: 'normal' },
series: { shadow: false}
},
series: [{ data: [34, 34, 54, 12, 23], stack: 'Stack 1' }]
});
});
http://jsfiddle.net/Zprjn/6/
Cheers!
EDIT
This is a simplified version of what I actually have. In my real chart I have dynamic content so there are different texts in the stack labels and the columns have various heights. None of this I know beforehand and thus I need to, somehow, dynamically adjust the stack labels to the bottom (and to the left of) of the columns regardless of the length of the text in the actual label.
Thanks again!
You can change:
verticalAlign: 'middle'
Example: http://jsfiddle.net/Zprjn/7/
or if you want at bottom, add:
y: -40
Example: http://jsfiddle.net/Zprjn/8/
I just figured it out! I had to specify
textAlign: 'left'
as well and that fixed it!
See the updated jsFiddle:
http://jsfiddle.net/Zprjn/9/

Categories