Highcharts Bar Chart: possible to combine datapoints inside dataLabels? - javascript

I have a Highcharts horizontal bar chart with two series. Is it possible to combine the grouped data points into each data label so that they appear together, e.g. 1.00 / 2.3?
CODE:
var labels = [
'AAA/Aaa',
'AA+/Aa1',
'AA/Aa2',
'AA-/Aa3',
'A+/A1',
'A/A2',
'A-/A3'
];
var theData = [
{
name: 'Company 1',
data: [0.576,7.617,12.101,18.839,18.022,7.644,9.72]
},
{
name: 'Company 2',
data: [4.123,12.862,14.561,13.754,12.226,11.135,7.51]
}
];
HIGHCHARTS CONFIG:
$(function () {
$('#container').highcharts({
chart: {
type: 'bar'
},
legend: {
align: 'center',
layout: 'horizontal',
verticalAlign: 'bottom'
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
formatter: function() {
var out = '<span class="col-chart-label">';
out += this.y + ' / ' + this.y;
out += '</span>'
return out;
},
useHTML: true
}
}
},
series: theData,
tooltip: {
enabled: false
},
xAxis: {
categories: labels,
labels: {
formatter: false,
overflow: 'justify',
rotation: false
},
reversed: true
}
});
});
The demo is here:
http://jsfiddle.net/dylanmac/RungW/2/
To reiterate, there should be one data label per pair of bars with the top bar as the first value and the bottom bar as the second value, separated by "/"
Thanks a lot.

You can loop through all series and sum values for a specific category, see: http://jsfiddle.net/RungW/3/
formatter: function() {
var out = '<span class="col-chart-label">',
series = this.point.series.chart.series,
p1 = series[0].yData[this.point.x],
p2 = series[1].yData[this.point.x];
out += this.y + ' / ' + (p1 + p2);
out += '</span>'
return out;
},

Related

Highcharts bar with negative stack: how to show different tooltip for left and right

i am using highcharts bar with negative stack, problem is when i hover over the left side of the chart that is in red color it shows the correct disease name that is "TB Suspect" but when i hover over the blue bar it shows the same "TB Suspect" disease which is wrong, it should show "Otitis Media"
same problem for all other diseases
Here is the code
<script>
$(function () {
if($('#disease-bar').length > 0){
// Age categories
var categories_c = [<?=$comm_disease_title?$comm_disease_title:0;?>];
var categories_nc = [<?=$non_comm_disease_title?$non_comm_disease_title:0;?>];
$(document).ready(function () {
$('#disease-bar').highcharts({
colors: ['#dd4c39', '#00a9e9', '#c61a7e', '#bd8030', '#949293', '#075290', '#7db6ed', '#009451', '#c84433'],
chart: {
type: 'bar',
backgroundColor: null
},
title: {
text: 'Top Five Communicable & Non-communicable Diseases'
},
xAxis: [{
categories: categories_c,
reversed: false,
crosshair: true,
labels: {
step: 1
}
}, { // mirror axis on right side
opposite: true,
reversed: false,
categories: categories_nc,
linkedTo: 0,
labels: {
step: 1
}
}],
yAxis: {
title: {
text: null
},
labels: {
formatter: function() {
var s = Math.abs(this.value);
if (s.toFixed(0) >= 1000000) {
return s.toFixed(0) / 1000000 + 'M';
} else {
return s.toFixed(0) / 1000 + 'K';
}
}
}
},
plotOptions: {
series: {
cursor: 'pointer',
stacking: 'normal',
//point: {
events: {
click: function () {
//alert(this.name);return;
if(this.name=="Communicable"){
var url = 'disease.php<?=$next_url;?>&module=1';
}
else {
var url = 'disease.php<?=$next_url;?>&module=2';
}
//alert(url);
location.href = url;
}
,legendItemClick: function (event) {
//console.log(event.target.visible);
if(event.target.name=='Communicable'){
if(event.target.visible){this.chart.xAxis[0].update({
labels: {
enabled: false
}
});}
else {this.chart.xAxis[0].update({
labels: {
enabled: true
}
});}
}
else {
if(event.target.visible){this.chart.xAxis[1].update({
labels: {
enabled: false
}
});}
else {this.chart.xAxis[1].update({
labels: {
enabled: true
}
});}
}
//console.log(event.target.name);
//console.log(this.chart.xAxis[0]);
}
}
// }
}
},
tooltip: {{
formatter: function () {
return '<b>' + this.point.category + '</b><br/>' +
'Diseases: <b>' + Math.abs(this.point.y) +'</b>';
}
},
exporting: {
//enabled: false
},
credits: {
enabled: false
},
series: [{
name: 'Communicable',
data: [<?=$comm_disease_value?$comm_disease_value:0;?>]
}, {
name: 'Non-communicable',
data: [<?=$non_comm_disease_value?$non_comm_disease_value:0;?>]
}]
});
});
}
});
</script>
Here is the tooltip code which i am using
tooltip: {{
formatter: function () {
return '<b>' + this.point.category + '</b><br/>' +
'Diseases: <b>' + Math.abs(this.point.y) +'</b>';
}
},
JS Fiddle : https://jsfiddle.net/hamza9/h1nrn9nu/
I was able to get the correct category from the formatter:
formatter: function() {
var subCategoryLabel = this.series.chart.xAxis[this.series._i]
.categories[this.point.index];
return '<b>' + subCategoryLabel + '</b><br/>' +
'Diseases: <b>' + Math.abs(this.point.y) + '</b>';
}
You have to modify series data as array of object, wheredd is respective categories name and y is the value
series: [{
name: 'Communicable',
data: [{y:-1489599,dd:'Acute (Upper) Respiratory Infections'}, {y:-256548,dd:'Scabies'}, {y:-157531,dd:'Diarrhoea / Dysentery < 5 yrs'}, {y:-148696,dd:'Diarrhoea / Dysentery > 5 yrs'}, {y:-86283,dd:'Worm Infestations'}]
//url: 'disease.php?frequency=m&year=2017&month=1&quarter=&fatype=&disease_cat=comm'
}, {
name: 'Non-communicable',
data: [{y:399786,dd:'Fever due to other causes'}, {y:247500,dd:'Peptic Ulcer Diseases'}, {y:196653,dd:'Hypertension'}, {y:176866,dd:'Dental Caries'}, {y:169514,dd:'Diabetes Mellitus'}]
//url: 'disease.php?frequency=m&year=2017&month=1&quarter=&fatype=&disease_cat=noncomm'
}]
In your tooltip you can access it via the "point" attribute of the object passed in:
tooltip: {
formatter: function() {
return '<b>' + this.point.dd + '</b><br/>' +
'Diseases: <b>' + Math.abs(this.point.y) + '</b>';
}
},
Fiddle demo
Simply get rid of the linkedTo property from the second xAxis and link 'Non-Communicable' series to 1 xAxis.
API Reference:
http://api.highcharts.com/highcharts/series%3Cbar%3E.xAxis
Example:
https://jsfiddle.net/yqe0kunn/

How to add data tables to dynamically generated highcharts

I want to add data tables to Charts.
I tried the implementation shown here: http://jsfiddle.net/highcharts/z9zXM/
but it didnt work for me.
I suspect its because how I instantiate highcharts.
in the example above the chart is generated by instantiating the Highcharts object.
my code:
// data from an ajax call
$.each(data, function(indicator, questions) {
indicator_type = "";
$.each(questions, function(question, value) {
dataChartType = "column";
series = [];
categories = [];
category_totals = {};
if(value.programs == null) {
return true;
}
$.each(value.programs, function(program, body) {
total = 0;
values = [];
$.each(body, function(j, k) {
if (categories.indexOf(j) == -1) {
categories.push(j);
category_totals[j] = 0;
}
if(k != 0) {
values.push(k);
} else {
values.push(null);
}
category_totals[j] += parseInt(k, 10);
total += k;
});
series.push({
data: values,
total: total,
name: program //question
});
}); // eo each program
var chartDiv = document.createElement('div');
chartDiv.className = "chart";
$('.charts_wrap').append(chartDiv);
$(chartDiv).highcharts({
events: {
load: Highcharts.drawTable
},
chart: {
type: dataChartType
},
xAxis: {
categories: categories
},
legend: {
layout: 'vertical',
backgroundColor: '#FFFFFF',
align: 'right',
verticalAlign: 'top',
y: 60,
x: -60
},
tooltip: {
formatter: function () {
return '<strong>' + this.series.name + '</strong><br/>' + this.x + ': ' + this.y;
}
},
plotOptions: {
line: {
connectNulls: true
},
column: {
stacking: 'normal',
dataLabels: {
enabled: false,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px w'
}
}
}
},
series: series,
title:{ text: indicator },
subtitle:{ text: question }
});
}); // EO each question
}); // eo each indicator
When instantiating highcharts like this:
$("#container").highcharts({ ...
The events option needs to be included inside the charts option:
$("#container").highcharts({
chart: {
type: 'column',
events: {
load: Highcharts.drawTable
},
},
...

Updating Y-Axis of Highcharts line graph causes vertical line

I am implementing a Highcharts line graph where I need to be able to drag points as well as update the y-axis of my chart. When I drag a point, and then update the y axis, a line is drawn from the original point to where I dragged: Here is a picture of what is happening.
I'd really prefer to not have all these vertical lines, for some reason it seems to be duplicating the points because I also get some triangles when testing. Does it just leave the line but not actually update the point? To update the graph I am simply doing:
planChart.yAxis[0].max = newValueY;
$('.actualPlansPlot').highcharts(planChart);
Any guidance would be much appreciated!
Here is the rest of the code:
var values = [...my values];
planChart = {
chart: {
renderTo: 'container',
animation: false
},
title: {
text: ''
},
xAxis: {
categories: startDates,
crosshair: true,
},
yAxis: [{ // Primary yAxis
labels: {
format: '{value}',
style: {
color: '#20709e'
}
},
title: {
text: 'title',
style: {
color: '#20709e'
}
},
}],
plotOptions: {
series: {
point: {
events: {
drag: function (e) {
// Returning false stops the drag and drops. Example:
/*
if (e.newY > 300) {
this.y = 300;
return false;
}
*/
$('#drag').html(
'Dragging <b>' + this.series.name + '</b>, <b>' + this.category + '</b> to <b>' + Highcharts.numberFormat(e.y, 2) + '</b>');
},
drop: function () {
$('#drop').html(
'In <b>' + this.series.options.id + '</b>, <b>' + this.category + '</b> was set to <b>' + Highcharts.numberFormat(this.y, 2) + '</b>');
}
}
},
stickyTracking: false
},
column: {
stacking: 'normal'
},
line: {
cursor: 'ns-resize'
}
},
tooltip: {
shared: true
},
credits: {
enabled: false
},
series: [{
name: 'title',
tooltip: {
pointFormat: '<span style="color:{point.color}">\u25CF</span> <b> {point.y} ' + trainingPlan.unit + '</b><br/>'
},
data: values,
//draggableX: true,
draggableY: true,
dragMinY: 0,
style: {
color: '#20709e'
}
}]
}
$('.actualPlansPlot').highcharts(planChart);
It is pretty close to the example of draggable points online
Updated
use following code :
$(document).on('click', '#updateYScale', function(e) {
var yValue = $('#newYValue')[0].value;
var chart = $('.actualPlansPlot').highcharts();
chart.yAxis[0].update({
max: yValue
});
chart.redraw();
});
See demo fiddle with your issue's fix

Total of values in HighCharts Pie Chart

Is there a way to get a grand total of values in legend or any other place in pie charts?
Here is the code with legend ,but instead of adding the total of percentage,i want to display the total of values..
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'pie',
width: 500,
borderWidth: 2
},
title: {
text: 'demo'
},
credits: {
enabled: false
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
y: 30,
labelFormat: '{name} ({percentage:.1f}%)',
navigation: {
activeColor: '#3E576F',
animation: true,
arrowSize: 12,
inactiveColor: '#CCC',
style: {
fontWeight: 'bold',
color: '#333',
fontSize: '12px'
}
}
},
tooltip: {
formatter: function() {
return Highcharts.numberFormat(this.percentage, 2) + '%<br />' + '<b>' + this.point.name + '</b><br />Rs.: ' + Highcharts.numberFormat(this.y, 2);
}
},
series: [{
data: (function () {
var names = 'Ari,Bjartur,Bogi,Bragi,Dánjal,Dávur,Eli,Emil,Fróði,Hákun,Hanus,Hjalti,Ísakur,' +
'Johan,Jóhan,Julian,Kristian,Leon,Levi,Magnus,Martin,Mattias,Mikkjal,Nóa,Óli,Pauli,Petur,Rói,Sveinur,Teitur',
arr = [];
Highcharts.each(names.split(','), function (name) {
arr.push({
name: name,
y: Math.round(Math.random() * 100)
});
});
return arr;
}()),
showInLegend: true
}]
});
});
I would use the Renderer.text to annotate the chart (and not do it in the legend since you have so many data points).
chart: {
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: ' + total,
this.plotLeft,
this.plotTop - 20
).attr({
zIndex: 5
}).add() // write it to the upper left hand corner
}
}
},
Fiddle example.
In addition to Mark's answer, to calculate the total, we do not need the for-loop statement. So, the code can be reduced.
chart: {
events: {
load: function(event) {
var total = this.series[0].data[0].total;
var text = this.renderer.text(
'Total: ' + total,
this.plotLeft,
this.plotTop - 20
).attr({
zIndex: 5
}).add() // write it to the upper left hand corner
}
}
},

Highcharts : yAxis, values rounded to a maximum of two decimal places

The code of my graph is this (take data from a php page and then adds some series):
$('#grafico_1').highcharts({
chart: {
type: 'line',
zoomType: 'xy',
animation : false,
events: {
selection: function(event) {
if(event.resetSelection){
setTimeout(function(e){
var chart = $('#grafico_1').highcharts();
var extreme = chart.yAxis[0].getExtremes();
var mio_min = parseFloat(proprieta_temperatura_aperto[34]);
var mio_max = parseFloat(proprieta_temperatura_aperto[35]);
if(extreme.dataMin < mio_min){
mio_min = extreme.dataMin;
}
if(extreme.dataMax > mio_max){
mio_max = extreme.dataMax;
}
chart.yAxis[0].setExtremes(mio_min,mio_max);
$("#temperatura_min_max_rilevato").html("Min "+extreme.dataMin+"°C - Max "+extreme.dataMax+"°C");
//console.log("zoom - ");
}, 10);
}else{
setTimeout(function(e){
var chart = $('#grafico_1').highcharts();
var extreme = chart.yAxis[0].getExtremes();
$("#temperatura_min_max_rilevato").html("Min "+extreme.dataMin+"°C - Max "+extreme.dataMax+"°C");
//console.log("zoom + "+JSON.stringify(extreme));
}, 50);
}
}
},
},
credits : {
enabled : false
},
title: {
text: 'Grafico di Oggi'
},
xAxis: {
type: 'datetime',
title: {
text: false
}
},
yAxis: [
{
title: {
text: false
},
labels: {
format: '{value}°C',
},
//ceiling : parseFloat(proprieta_temperatura_aperto[35]),
//floor: parseFloat(proprieta_temperatura_aperto[34]),
max : parseFloat(proprieta_temperatura_aperto[35]),
min: parseFloat(proprieta_temperatura_aperto[34]),
},
{
title: {
text: false
},
min: 0,
max : 1,
ceiling:1,
floor : 0,
//tickLength : 1,
opposite: true,
tickInterval: 1,
labels: {
formatter: function() {
if (this.value == 0 || this.value == 1){
return this.value;
}else{
return null;
}
}
}
}
],
tooltip: {
formatter: function() {
var s = '<b>Data</b> '+Highcharts.dateFormat('%H:%M:%S', this.x) + '<br><b>Temperatura</b> ' + this.y + '°C<br/>';
$.each(this.points, function(i, point) {
if(point.series.name != "Temperatura"){
s += '<b>' + point.series.name +'</b> : '+ point.y + '<br>';
}
});
return s;
},
shared: true,
backgroundColor: '#FCFFC5'
},
plotOptions: {
line : {
turboThreshold: 0,
},
series: {
animation: false,
marker: {
enabled: false
}
}
},
series: []
});
the problem occurs when run one (or more) zoom on the graphs , and on the y-axis the values ​​are listed with more than two decimal places. I would like to limit to two the maximum number of decimal places.
I think i have to change this field (format)
yAxis: [
{
labels: {
format: '{value}°C',
},
but I do not know how.
Try to write the value as {value:.2f}, as proposed here: link

Categories

Resources