Responsive Highchart legend position - javascript

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/

Related

How do I center a semi-circle doughnut chart?

I'm trying to display a doughnut or semi-circle chart inside a materialize card, which is a responsive div.
I need to display simple data and use the chart as a progress bar. I started from the example in the HighCharts documentation.
Now I need to position the plot at the bottom, but remove the white space from the top. If I set the position at center:[50%,50%] there is a white space at the bottom of the container.
Is there a way to crop the height of the container and keeping the aspect ratio?
This is the code I'm using:
var data = [
{
name: 'Done',
y: 76.1,
color: "#ff6666",
dataLabels: {
enabled: false
}
},
{
name: 'To do',
y: 23.9,
color:"#dddddd",
dataLabels: {
enabled: false
}
}
];
Highcharts.chart('container', {
chart: {
plotBorderWidth: 0,
height:"400px"
},
title: {
text: 'Title'
},
tooltip: {
pointFormat: '<b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
dataLabels: {
enabled: true,distance: -50,
style: {fontWeight: 'bold', color: 'white'}
},
startAngle: -90,
endAngle: 90,
center: ['50%', '100%']
}
},
series: [{type: 'pie',name: 'Value',innerSize: '70%',data: data}]
});
Here is the result I get:
You can try to play around a bit with container height, plotOptions.pie.center and plotOptions.pie.size to get the right dimensions. Please check the code below. I have changed the height of your chart to 200px, center to ['50%', '70%'] and added size of 200%.
See the sample here: https://codepen.io/anon/pen/pGVyQX?&editable=true
var data = [
{
name: 'Done',
y: 76.1,
color: "#ff6666",
dataLabels: {
enabled: false
}
},
{
name: 'To do',
y: 23.9,
color:"#dddddd",
dataLabels: {
enabled: false
}
}
];
Highcharts.chart('container', {
chart: {
plotBorderWidth: 0,
height:"200px"
},
title: {
text: 'Title'
},
tooltip: {
pointFormat: '<b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
dataLabels: {
enabled: true,
distance: -50,
style: {fontWeight: 'bold', color: 'white'}
},
startAngle: -90,
endAngle: 90,
center: ['50%', '70%'],
size: "200%"
}
},
series: [{type: 'pie',name: 'Value',innerSize: '70%',data: data}]
});
Highcharts chart consists of several HTML elements. The height option is used for setting height style for a child of the HTML element you created as a chart container.
The solution to your problem can be setting different heights:
CSS:
#container {
height: 200px;
...
}
JS:
chart: {
height: 400
},
series: [{
type: 'pie',
name: 'Value',
innerSize: '70%',
center: ['50%', '50%'],
data: data
}]
Live demo: http://jsfiddle.net/BlackLabel/du60mrgp/

Highchart pie vertical legend align right not pinned to plot correctly

I can't indent legend from right plot border properly
My config
Highcharts.chart('container', {
chart: {
type: 'pie',
plotBackgroundColor: null,
plotBorderWidth: 1,
plotShadow: false,
},
plotOptions: {
pie: {
dataLabels: {
enabled: false
},
showInLegend: true,
center: [150, 150],
},
column: {
stacking: 'percent'
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.percentage:.2f}%)<br/>',
shared: true
},
series: [{
name: "My plot",
type: 'pie',
innerSize: '70%',
data: [ ['item',4],['item2',50],['item3',8]]
}],
title: {
text: "My chart"
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth:1,
},
});
http://jsfiddle.net/69d1d22x/
I suppose that I need to align legend left and shift it to right but I did't find any hack.
Have you tried to limit your chart width size?
Like :
(...)
type: 'pie',
plotBackgroundColor: null,
plotBorderWidth: 1,
plotShadow: false,
width: 450,
(...)
Example:
http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/chart/width/
You can use chart.marginRight to give right margin to the plot. Use this code to position the legend next to it (the assumption here is that legend.align equals to 'right'):
function alignLegend(chart) {
var group = chart.legend.group;
group.attr({
translateX: chart.plotLeft + chart.plotWidth + chart.plotBox.x
});
}
Place this function in load and redraw events.
Live working example: http://jsfiddle.net/kkulig/cthaLrb3/
API references:
http://api.highcharts.com/highcharts/chart.marginRight
http://api.highcharts.com/highcharts/chart.events.load
http://api.highcharts.com/highcharts/chart.events.redraw

HighCharts and idTabs - Charts width not setting properly

I have a webpage with HighCharts and idTabs plugins installed. I just want to show 1 chart at time, so hi got them in multiple tabs. The html code is:
<ul class="idTabs">
<li>Points</li>
<li>Kills and deaths</li>
<li>Damage</li>
<li>Bombs</li>
</ul>
<div id="vpPointsGraphWrapper"><div id="vpPointsGraph"></div></div>
<div id="vpKillsDeathsGraphWrapper"><div id="vpKillsDeathsGraph"></div></div>
<div id="vpDamageGraphWrapper"><div id="vpDamageGraph"></div></div>
<div id="vpBombsGraphWrapper"><div id="vpBombsGraph"></div></div>
Until this point is all okey, the charts have their data, and all is okey except one thing, the width. The chart that is showed by default (vpPointsGraph) has the correct width (100% of the div that contains them), but the others take the width that correspond to the width of the monitor, overflowing out of the wrapper div. I think the problem is that they want to get the wrapper div width, but as its hidden they take the whole screen width. ¿Is there anyway to fix this?
Thanks for your answers.
Edit: I solved it, check the next answer for explanation.
Solution: http://jsfiddle.net/5kLdG/
What i have done its just getting the width of the container i want the chart to fit in, and setting it in the highcharts 'width' parameter. I don't know if its the best solution but it worked for me.
//Get wrapper width
var width = $('#wrapper').width()
//Points Graph
var pointsChart = new Highcharts.Chart({
chart: {
renderTo: 'vpPointsGraph',
type: 'line'
},
title: {
text: 'Points'
},
xAxis: {
title: {
text: 'Match'
},
categories: [1,2,3,4,5,6,7],
reversed: true
},
yAxis: {
title: {
text: 'Points'
},
},
tooltip: {
crosshairs: true,
shared: true,
valueSuffix: ''
},
plotOptions: {
line: {
marker: {
radius: 4,
lineColor: '#666666',
lineWidth: 1
}
}
},
credits: {
enabled: false
},
series: [{
name: 'Points',
data: [5,6,7,8,3,6,8]
}]
});
//KillsDeaths Graph
var killsDeathsChart = new Highcharts.Chart({
chart: {
renderTo: 'vpKillsDeathsGraph',
type: 'line',
width: width
},
title: {
text: 'Kills and Deaths per match'
},
xAxis: {
title: {
text: 'Match'
},
categories: [1,2,3,4,5],
reversed: true
},
yAxis: {
title: {
text: 'Number'
},
},
tooltip: {
crosshairs: true,
shared: true,
valueSuffix: ''
},
plotOptions: {
line: {
marker: {
radius: 4,
lineColor: '#666666',
lineWidth: 1
}
}
},
credits: {
enabled: false
},
series: [{
name: 'Kills',
data: [6,8,2,2,5]
}]
});

DataLabels in Highcharts are outside the container / not showing

I'm drawing a half-donut-pie-chart (using innersize and start-/endAngle). But my datalabels are outside the plot area (below the center point / xAxis) or not showing at all regarding my settings.
$(function () {
var chart;
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false
},
title: {
text: '',
enabled: false
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage}%</b>',
percentageDecimals: 1
},
plotOptions: {
pie: {
startAngle: -90,
endAngle: 90,
center: ['50%', '100%'],
size: '140%',
cursor: 'pointer',
dataLabels: {
enabled: true,
//crop: false,
//overflow: 'none',
//useHTML: true,
formatter: function() {
return '<b>'+ this.point.name +'</b>: '+ this.percentage +' %';
},
style: {
width: '100px' // for line wrap on long dataLabels
}
}
}
},
series: [{
type: 'pie',
name: 'Browser share',
data: [
['Firefox and this is very very very long name with some spaces etc.', 45.0],
['IE', 26.8],
{
name: 'Chrome',
y: 12.8,
sliced: true,
selected: true
},
['Safari', 8.5],
['Opera', 6.2],
['Others', 0.7]
]
}]
});
});
});
See here: jsfiddle
Using useHTML: true, useHTML: true did not work at all any positive.
Using useHTML: true would render the overflowing dataLabels inside the plot, but my long dataLabels disapeared.
So how can I accomplish this having the following things in mind?
My half-donut should always be at the bottom of my plot area and use
the space (not be too small).
It happens that I have long datalabels so defining a style.width seems to do a line-wrap if needed.
DataLabels should always be above the xAxis and not fall below the bottom of my half-donut.
DataLabels should always be shown and be outside of the chart using connectors.
Thanks in advance and best regards.
It looks like possibly bug, reported here: https://github.com/highslide-software/highcharts.com/issues/2630

HighCharts: How to put the xAxis category text inside the chart

I'm working with Highcharts and I'm not being able to accomplish something. Here is what I want:
As you can see, the text for each bar is on top of the bar.
Here is the version that I've been working on:
$(function () {
$('#container').highcharts({
chart: {
type: 'bar'
},
title: {
text: 'APPROVED SPEND TO DATE FOR FISCAL YEAR 2013: $17,360,612'
},
xAxis: {
categories: ['Intellectual Property', 'Antitrust/Competition'],
title: {
text: null
}
},
yAxis: {
min: 0,
title: {
text: 'Approved spend',
align: 'high'
},
labels: {
overflow: 'justify'
}
},
tooltip: {
valueSuffix: ' dollars'
},
plotOptions: {
bar: {
dataLabels: {
enabled: false
}
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -40,
y: 100,
floating: true,
borderWidth: 1,
backgroundColor: '#FFFFFF',
shadow: true
},
credits: {
enabled: false
},
series: [{
name: 'Year 2013',
data: [6000123, 3743653]
}]
});
});
JSFiddle: http://jsfiddle.net/WcKvz/1/
As you can see, I'm only having the text in the left side of the bar and I can't get it right.
Any ideas? Thank you
The only way I've seen this work is with stackedLabels. You can use them even if you aren't using stacked bars since you only have one series.
...
plotOptions: {
bar: {
stacking: 'normal'
}
},
yAxis: {
stackLabels: {
formatter: function() {
return this.axis.chart.xAxis[0].categories[this.x] + ': $' + this.total;
},
enabled: true,
verticalAlign: 'top',
align: 'left',
y: -5
},
...
http://jsfiddle.net/NVypa/

Categories