Highcharts dataLabel overlap - javascript

I have a highcharts stacked barchart that has a few values that are extremely low. This causes the two dataLabels to overlap, like this fiddle: http://jsfiddle.net/cerjps88/
What is the best means to ensure that the labels can't overlap?
Here's my highchart code:
function getCostStackedColumnChart(series) {
function costFilterPluck(costCollection, propertyName) {
return _.chain(costCollection)
.filter(function (f){
return Math.abs(f.metric_mean_patient_cost) > 0 && Math.abs(f.metric_mean_patient_cost_rx) > 0
})
.pluck(propertyName)
.take(10)
.value();
}
function shapeCostData(costCollection) {
return [
{
name: 'RxCost Per Prescription',
color: '#1aadce',
data: costFilterPluck(series, 'metric_mean_patient_cost_rx')
},
{
name: 'Retail Price Per Prescription (2014)',
color: '#00FFFF',
data: costFilterPluck(series, 'metric_drug_price_rx')
}
];
}
return {
options: {
chart: {
type: 'column'
},
tooltip: {
formatter: function () {
var format = d3.format(",.2f");
var chart = this.point.series.chart;
var index = chart.xAxis[0].categories.indexOf(this.x);
var series1 = this.point.series;
return '<b>' + this.x + '</b><br/>' +
series1.name + ': $' + format(this.y);
}
},
showInLegend: true,
plotOptions: {
column: {
grouping: true,
stacking: 'normal',
dataLabels: {
enabled: true,
allowOverlap: false,
format: '${y:,.2f}',
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'black',
style: {
fontWeight: 'bold',
textShadow: '0 0 3px white'
},
}
}
}
},
xAxis: {
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
},
categories: costFilterPluck(series, 'aedrug_label'),
title: {text: 'Drug'}
},
yAxis: {
min: 0,
title: {
text: 'Total Cost Per Prescription'
}
},
tooltip: {
shared: true
},
title: {
text: drugGroupName + ' RxCost'
},
series: shapeCostData(series)
};
}

The newest version of highcharts automatically hides overlapping labels. After upgrading the new version, the issue was resolved.

Related

Stuck on the final bits of a multi series line chart

I built a multi series Highcharts https://www.highcharts.com/ line chart with irregular time data. It's almost there, but I'm doing something wrong with the data and/or data formatting. Anyone have a hint or two to throw my way?
The date from the database was converted from '02/03/2009' to javascript time in php using
$date = strtotime($data['As of Date'])*1000;
The other value is a dollar amount.
I haven't yet added the filtered data for 3MO, 6MO, 1YR, 5YR, 10YR
Here is the jsfiddle https://jsfiddle.net/madmichael/th41g4yt/
$( document ).ready(function() {
createChart();
});
function createChart(chartingOptions) {
var options = {
chart: {
renderTo: 'container',
type: 'line',
zoomType: 'xy',
events: {
load: function(event) {
var total = 0; // get total of data
for (var i = 0, len = this.series[0].yData.length; i < len; i++) {
total += this.series[0].yData[i];
}
var text = this.renderer.text(
'Total: $' + Highcharts.numberFormat(total, 0, '.', ','),
this.plotLeft,
this.plotTop + 20
).attr({
zIndex: 5
}).add() // write it to the upper left hand corner
}
}
},
navigator: {
enabled: false
},
scrollbar: {
enabled: false
},
rangeSelector: {
inputEnabled: false,
allButtonsEnabled: true,
/* buttons: [[]], */
buttons: [
{
type: 'all',
text: 'All'
}, {
type: 'month',
count: 3,
text: '3MO'
}, {
type: 'month',
count: 6,
text: '6MO'
}, {
type: 'year',
text: '1YR',
count: 1
}, {
type: 'year',
text: '5YR',
count: 5
}, {
type: 'year',
text: '10YR',
count: 10
}],
buttonTheme: {
width: 60
},
selected: 0
},
tooltip: {
backgroundColor: null,
borderWidth: 0,
shadow: false,
useHTML: true,
style: {
padding: 0
},
pointFormat: '$' + '{point.y:,.0f}'
/* formatter: function() {
return Highcharts.dateFormat('%b %d, %Y', point.x) + ': $
{point.y:,.1f}';
} */
},
xAxis: {
type: 'datetime',
labels: {
formatter: function() {
return Highcharts.dateFormat('%b-%Y', this.value);
}
}
},
yAxis: {
type: 'linear',
labels: {
formatter: function () {
if(this.value >= 0 ){
return '$' + this.value / 1000+'k';
}else{
return '-$' + this.value / 1000*-1+'k';
}
}
}
},
series: [{name: 'Investment Fund (A)',fundtype: 'Load',data: [[1483164000000,37149],[1451541600000,37247],[1420005600000,37071],[1388469600000,33407],[1356933600000,19881],[1325311200000,14132],[1293775200000,21541],[1262239200000,18343],[1480485600000,36659],[1448863200000,39677],[1417327200000,38070],[1385791200000,32212],[1354255200000,18197],[1322632800000,14132],[1291096800000,20173],[1259560800000,17399],[1477890000000,34171],[1446267600000,39069],[1414731600000,36522],[1383195600000,30429],[1351659600000,18468],[1320037200000,14848],[1288501200000,20250],[1256965200000,15703],[1475211600000,36503],[1443589200000,36071],[1412053200000,34602],[1380517200000,29214],[1348981200000,17752],[1317358800000,13048],[1285822800000,19287],[1254286800000,17861],[1472619600000,35249],[1440997200000,38775],[1409461200000,36542],[1377925200000,27548],[1346389200000,16784],[1314766800000,15642],[1283230800000,16994],[1251694800000,16821],[1469941200000,32741],[1438318800000,42537],[1406782800000,34230],[1375246800000,28273],[1343710800000,16203],[1312088400000,17674],[1280552400000,18478],[1249016400000,14335],[1467262800000,29782],[1435640400000,40245],[1404104400000,36150],[1372568400000,26157],[1341032400000,16861],[1309410000000,19707],[1277874000000,17013],[1246338000000,13083],[1496206800000,41636],[1464670800000,33015],[1433048400000,40656],[1401512400000,34720],[1369976400000,26850],[1338440400000,16010],[1306818000000,20963],[1275282000000,19441],[1243746000000,12563],[1493528400000,40010],[1461992400000,32603],[1430370000000,39814],[1398834000000,33779],[1367298000000,25205],[1335762000000,17229],[1304139600000,21233],[1272603600000,21426],[1241067600000,10732],[1490936400000,39794],[1459400400000,33054],[1427778000000,39304],[1396242000000,34798],[1364706000000,24063],[1333170000000,17771],[1301547600000,21021],[1270011600000,20983],[1238475600000,8940],[1456725600000,30977],[1330495200000,17307],[1488261600000,40696],[1425103200000,39285],[1393567200000,34955],[1362031200000,22011],[1298872800000,21233],[1267336800000,19268],[1235800800000,7534],[1233640800000,9422],[1485842400000,37149],[1454220000000,30233],[1422684000000,35856],[1391148000000,33603],[1359612000000,22108],[1327989600000,15990],[1296453600000,21021],[1264917600000,18459]]},{name: 'Investment Fund (A)',fundtype: 'No Load',data: [[1483164000000,39428],[1451541600000,39532],[1420005600000,39345],[1388469600000,35456],[1356933600000,21101],[1325311200000,14999],[1293775200000,22863],[1262239200000,19468],[1480485600000,38908],[1448863200000,42111],[1417327200000,40406],[1385791200000,34188],[1354255200000,19314],[1322632800000,14999],[1291096800000,21411],[1259560800000,18466],[1477890000000,36267],[1446267600000,41466],[1414731600000,38763],[1383195600000,32295],[1351659600000,19601],[1320037200000,15759],[1288501200000,21493],[1256965200000,16667],[1475211600000,38742],[1443589200000,38284],[1412053200000,36725],[1380517200000,31006],[1348981200000,18841],[1317358800000,13848],[1285822800000,20470],[1254286800000,18957],[1472619600000,37411],[1440997200000,41154],[1409461200000,38784],[1377925200000,29238],[1346389200000,17814],[1314766800000,16601],[1283230800000,18037],[1251694800000,17853],[1469941200000,34749],[1438318800000,45147],[1406782800000,36330],[1375246800000,30008],[1343710800000,17197],[1312088400000,18759],[1280552400000,19611],[1249016400000,15215],[1467262800000,31609],[1435640400000,42714],[1404104400000,38368],[1372568400000,27762],[1341032400000,17896],[1309410000000,20916],[1277874000000,18057],[1246338000000,13885],[1496206800000,44190],[1464670800000,35040],[1433048400000,43151],[1401512400000,36850],[1369976400000,28498],[1338440400000,16992],[1306818000000,22249],[1275282000000,20634],[1243746000000,13333],[1493528400000,42464],[1461992400000,34604],[1430370000000,42256],[1398834000000,35851],[1367298000000,26751],[1335762000000,18286],[1304139600000,22536],[1272603600000,22740],[1241067600000,11391],[1490936400000,42236],[1459400400000,35082],[1427778000000,41716],[1396242000000,36933],[1364706000000,25539],[1333170000000,18862],[1301547600000,22311],[1270011600000,22270],[1238475600000,9489],[1456725600000,32878],[1330495200000,18368],[1488261600000,43192],[1425103200000,41695],[1393567200000,37099],[1362031200000,23361],[1298872800000,22536],[1267336800000,20450],[1235800800000,7996],[1233640800000,10000],[1485842400000,39428],[1454220000000,32087],[1422684000000,38056],[1391148000000,35664],[1359612000000,23464],
[1327989600000,16971],[1296453600000,22311],[1264917600000,19591]]},],
plotOptions: {
series: {
events: {
show: function () {
var chart = this.chart,
series = chart.series,
i = series.length,
otherSeries;
while (i--) {
otherSeries = series[i];
if (otherSeries != this && otherSeries.visible)
{
otherSeries.hide();
}
}
},
legendItemClick: function() {
if(this.visible){
return false;
}
}
}
},
line: {
marker: {
enabled: false
},
/* color: '".$attributes["line_color"]."',
*/ }
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -150,
y: 100,
floating: true,
borderWidth: 1,
backgroundColor: (Highcharts.theme &&
Highcharts.theme.legendBackgroundColor) || '#FFFFFF'
},
credits: {
enabled: false
},
};
/* options.series[5] = {
name: '5 Yrs',
data: processed_five_years,
visible: false
};
*/
var chart = new Highcharts.stockChart(options);
Highcharts.setOptions({
lang: {
decimalPoint: '.',
thousandsSep: ','
}
});
};

highcharts / highstock column doesn't show all datalabels

I have a highstock column chart which doesn't show all of the values - I've tried to simplify it as much as possible for this example. I'm using highstock because I need a horizontal scroll bar on the column.
$('#container').highcharts({
tooltip: {
formatter: function () {
if (this.y === '' && this.y !== 0) {
return this.series.name + '<br/>' + this.x + ': NO DATA';
}
return this.series.name + '<br/>' + this.x + ': ' + this.y;
}
},
chart: {
type: 'column'
},
title: {
text: null
},
subtitle: {
text: null
},
xAxis: {
categories: labels,
title: {
text: null
},
labels: {
style: {
color: '#000',
}
},
lineWidth: 2,
lineColor: '#000',
tickWidth: 2,
tickLength: 12,
tickColor: '#000',
startOnTick: true,
},
yAxis: {
title: {
text: 'test',
align: 'middle',
style: {
color: '#000',
}
},
labels:{enabled: false},
style: {
color: '#000',
},
gridLineColor: 'transparent',
lineWidth: 2,
lineColor: '#000',
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
}
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: 0,
y: 100,
floating: false,
borderWidth: 0,
backgroundColor: ((Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF'),
shadow: true
},
credits: {
enabled: false
},
series: series
});
Here is a fiddle: https://jsfiddle.net/ypw4gx1h/
Some data labels are not showing because they would be overlapping nearby data labels. With a column chart dataLabels.allowOverlap is set to false by default. You could change this to true in your code like this (JSFiddle example):
plotOptions: {
series: {
dataLabels: {
enabled: true,
allowOverlap: true
}
}
}

HighChart Stacked Column label issue

I have a chart with values that are uneven, ie: First value is 1315 and second value is 1, and so on, and when displaying the chart the labels are being overlapped. I have already searched in multiple forums but no one had the exact same problem. Here's a fiddle to see the problem: http://jsfiddle.net/6LutjLc3/
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: ['Issue']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit 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: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black'
}
}
}
},
series: [{
name: 'John',
data: [1235]
}, {
name: 'Toto',
data: [2]
}, {
name: 'Matt',
data: [1]
}, {
name: 'Jane',
data: [72]
}, {
name: 'Joe',
data: [3]
}]
});
});
What I need to code is to give the value 1 one box where the label fits in as like any other example in highchart.
Thanks in advance for your help!
If your client demands use of this style of graph you can get better looking results by modifying your dataLabel settings. Setting overflow to false and adding a formatter function that only returns a value if it's let's say at least 7% (or whatever percentage works best for you) of the current total will help. See the following:
dataLabels: {
enabled: true,
overflow: false,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black'
},
formatter: function () {
if (this.percentage >= 7) return this.y;
}
}
Fiddle here: http://jsfiddle.net/6LutjLc3/4/

Highcharts + set event click from options in jquery

I have an array options like this:
var options = {
chart: {
type: 'bar',
events: {
click: function(event) {
}
}
},
xAxis: {
categories: '',
title: {
text: null
}
},
yAxis: {
min: 0,
title: {
text: 'Aantal keer gekozen',
align: 'high'
},
labels: {
overflow: 'justify'
}
},
tooltip: {
//valueSuffix: ' aantal keer gekozen'
},
plotOptions: {
bar: {
dataLabels: {
enabled: true,
color: 'black',
formatter: function() {
if (this.y === 0) {
return null;
} else {
return this.y;
}
}
},
stacking: 'normal'
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -40,
y: 100,
floating: true,
borderWidth: 1,
backgroundColor: '#FFFFFF',
shadow: true
},
credits: {
enabled: false
},
exporting: {
enabled: true
},
series: []
}
As you can see I don't do anything on the click function.
I create the highcharts in jQuery in a foreach (so I create multiple charts).
options.chart.renderTo = 'container' + index;
chart = new Highcharts.Chart(options);
Now how can I add an event click like I did with renderTo?
You probably need to read about closures in javascript - otherwise you add the same event for each chart.
Another solution is to create array of id's for charts and then use: options.chart.events.click = function() { window.location.href = '/path/' + ids[index]; };

Highcharts duplicated code

I've created 2 pie charts using Highcharts but I have duplicated the code.
How can just have one based code - calling in a different json file.
var chart1 = {
chart: {
renderTo: 'container1'
},
title: {
text: 'Industry'
},
plotArea: {
shadow: null,
borderWidth: null,
backgroundColor: null
},
tooltip: {
formatter: function () {
return '<b>' + this.point.name + '</b>: ' + this.y.toFixed(2) + ' % / £' + this.point.mv;
}
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
showInLegend: true,
dataLabels: {
enabled: true,
formatter: function () {
return ' '+ this.y.toFixed(2) +' %';
},
color: 'black',
style: {
font: '100% Arial, Verdana, sans-serif'
}
}
}
},
credits: {
enabled: false,
text: 'Newton.co.uk'
},
legend: {
itemStyle: {
color: '#444',
fontWeight: 'normal',
fontFamily: 'Arial',
fontSize: '100%'
},
verticalAlign: 'bottom',
x: -100,
y: 0,
width: '100%',
itemWidth: 'auto',
floating: false,
labelFormatter: function () {
return this.name + ': ' + this.y.toFixed(2) + ' %';
},
borderWidth: 0,
margin: 0,
lineHeight: 50
},
series: []
}
var options = chart1;
$.getJSON(link + "/valuations/industry.json", null, function (items) {
var valuations = items.valuations;
var series = {
type: 'pie',
name: '',
data: []
};
console.log(valuations);
$.each(valuations, function (itemNo, item) {
series.data.push({
name: item.id,
y: parseFloat(item.percentageMarketValue),
mv: item.marketValue
})
});
options.series.push(series);
chart1 = new Highcharts.Chart(options);
//chart.render();
});
var chart2 = {
chart: {
renderTo: 'container2'
},
title: {
text: 'Geographic'
},
plotArea: {
shadow: null,
borderWidth: null,
backgroundColor: null
},
tooltip: {
formatter: function () {
return '<b>' + this.point.name + '</b>: ' + this.y.toFixed(2) + ' % / £' + this.point.mv;
}
},
credits: {
enabled: false,
text: 'Newton.co.uk'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
showInLegend: true,
dataLabels: {
enabled: true,
formatter: function () {
return ' '+ this.y.toFixed(2) +' %';
},
color: 'black',
style: {
font: '100% Arial, Verdana, sans-serif'
}
}
}
},
legend: {
itemStyle: {
color: '#444',
fontWeight: 'normal',
fontFamily: 'Arial',
fontSize: '100%'
},
verticalAlign: 'bottom',
x: -100,
y: 0,
width: '100%',
itemWidth: 'auto',
floating: false,
labelFormatter: function () {
return this.name + ': ' + this.y.toFixed(2) + ' %';
},
borderWidth: 0,
margin: 0,
lineHeight: 50
},
series: []
}
var options2 = chart2;
$.getJSON(link + "/valuations/geographic.json", null, function (items) {
var valuations = items.valuations;
var series = {
type: 'pie',
name: '',
data: []
};
$.each(valuations, function (itemNo, item) {
series.data.push({
name: item.id,
y: parseFloat(item.percentageMarketValue),
mv: item.marketValue
})
});
options2.series.push(series);
chart2 = new Highcharts.Chart(options2);
//chart.render();
});
Highcharts.setOptions({
colors: ['#9E8F6C', '#7BA1CD', '#666666', '#A2B021', '#DC7000', '#336666', '#FF9655', '#999999']
});
$('#export').click(function() {
Highcharts.exportCharts([chart1, chart2]);
});
});
See code comments:
// Define a default set of chart options
var defaultChart = {
chart: {
renderTo: 'chart'
},
title: {
text: 'Chart'
},
plotArea: {
shadow: null,
borderWidth: null,
backgroundColor: null
},
tooltip: {
formatter: function() {
return '<b>' + this.point.name + '</b>: ' + this.y.toFixed(2) + ' % / £' + this.point.mv;
}
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
showInLegend: true,
dataLabels: {
enabled: true,
formatter: function() {
return ' ' + this.y.toFixed(2) + ' %';
},
color: 'black',
style: {
font: '100% Arial, Verdana, sans-serif'
}
}
}
},
credits: {
enabled: false,
text: 'Newton.co.uk'
},
legend: {
itemStyle: {
color: '#444',
fontWeight: 'normal',
fontFamily: 'Arial',
fontSize: '100%'
},
verticalAlign: 'bottom',
x: -100,
y: 0,
width: '100%',
itemWidth: 'auto',
floating: false,
labelFormatter: function() {
return this.name + ': ' + this.y.toFixed(2) + ' %';
},
borderWidth: 0,
margin: 0,
lineHeight: 50
},
series: []
};
// Create a function that will fetch the data and create the chart based on passed options
function makeChart( url, chart, options ) {
$.getJSON(link + url, null, function(items) {
var valuations = items.valuations;
var series = {
type: 'pie',
name: '',
data: []
};
$.each(valuations, function(itemNo, item) {
series.data.push({
name: item.id,
y: parseFloat(item.percentageMarketValue),
mv: item.marketValue
})
});
options.series.push(series);
chart = new Highcharts.Chart(options);
//chart.render();
});
}
//Set up chart1's custom options
var chart1 = {
chart: {
renderTo: 'container1'
},
title: {
text: 'Industry'
}
}
// Call our new function to make the chart
makeChart( "/valuations/industry.json", chart1, $.extend(true, {}, default_chart, chart1) );
// Setup chart2's custom options
var chart2 = {
chart: {
renderTo: 'container2'
},
title: {
text: 'Geographic'
}
}
// Call our new function to make the chart
makeChart( "/valuations/geographic.json", chart2, $.extend(true, {}, default_chart, chart2) );
Highcharts.setOptions({
colors: ['#9E8F6C', '#7BA1CD', '#666666', '#A2B021', '#DC7000', '#336666', '#FF9655', '#999999']
});
$('#export').click(function() {
Highcharts.exportCharts([chart1, chart2]);
});

Categories

Resources