Updating Y-Axis of Highcharts line graph causes vertical line - javascript

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

Related

Highcharts: Duplicate X-Axis Labels when dataGrouping is enabled (by Month)

I'm experiencing an issue when grouping data by month. I believe it to be a bug with the size of the dataset (January 1, 2018 - April 30, 2018) that I'm using but perhaps there is a better way of utilizing dataGrouping. The issue that I'm experiencing is that the X-Axis labels are not correct.
For a date range of January 1, 2018 to April 30, 2018:
Expected X-Axis to Be:
"Jan, '18" "Feb, '18" "Mar, '18" "Apr, '18"
Actual X-Axis:
"Jan, '18" "Feb, '18" "Mar, '18" "Mar, '18" "Apr, '18"
In my example (jsfiddle), I'm conditionally enabling dataGrouping on line 76: data.dataGrouping.enabled = (e.target.value === 'month');
Any insight would be greatly appreciated.
I think I found the solution: Use HighStocks and not HighCharts
I have an updated fiddle with the result. Summary:
Use HighScocks and just turn off some features to make it appear like a Highstock chart:
var chart = Highcharts.stockChart('myChart', {
chart: {
type: 'column',
width: null
},
xAxis: {
labels: {
enabled: true,
formatter: function() {
if (grouping === 'date') {
return Highcharts.dateFormat('%b %e, \'%y', this.value);
} else {
return Highcharts.dateFormat('%b, \'%y', this.value);
}
}
}
},
navigator: {
enabled: false
},
scrollbar: {
enabled: false
},
rangeSelector: {
enabled: false
},
yAxis: {
title: {
text: null
}
},
title: {
text: null
},
legend: {
enabled: false
},
plotOptions: {
series: {
color: 'white'
}
},
tooltip: {
backgroundColor: '#0E7BBA',
style: {
color: 'white'
},
formatter: function() {
var s = ''
if (grouping === 'date') {
s = '<b>' + Highcharts.dateFormat('%A, %b %e, %Y', this.x) + '</b>';
} else {
s = '<b>' + 'Date: ' + Highcharts.dateFormat('%A, %b %e, %Y', this.x) + '<br />' +
'<b>Month: ' + Highcharts.dateFormat('%B %Y', this.x) + '</b>';
}
s += '<br />' + this.points[0].series.name + ': ' + this.y;
return s;
}
},
credits: {
enabled: false
},
series: []
}
);

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/

Highcharts: Adding extra text to legend

Hi all I have a pie chart with the legend format like this:
{
enabled: true,
labelFormatter: function() {
return this.name + ' (Gesamt: ' + this.y + ' - ' + this.percentage.toFixed(1) + '%)' ;
},
borderWidth: 1
};
In some specific cases, I need to add an extra text which I defined as text = 'Extra' to this legend box. The rest legends I still keep them in the box. How can I do that ?
My jsfiddle code: http://jsfiddle.net/wjnnt28p/
You can add some if condition and display text like you want.
e.g.
labelFormatter: function() {
var p = this.name + ' (Gesamt: ' + this.y + ' - ' + this.percentage.toFixed(1) + '%)';
if (this.name == 'Chrome') { // Test the name
return p + ' Other Text for Chrome';
} else {
return p;
}
}
Full example :
$(function () {
$(document).ready(function () {
var text = 'Extra';
// 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>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
}
},
legend: {
enabled: true,
labelFormatter: function () {
var p = this.name + ' (Gesamt: ' + this.y + ' - ' + this.percentage.toFixed(1) + '%)';
if (this.name == 'Chrome') { // Test the name
return p + ' Other Text for Chrome';
} else {
return p;
}
},
borderWidth: 1
},
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
}]
}]
});
});
});
<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="min-width: 310px; height: 400px; max-width: 600px; margin: 0 auto"></div>
Update 2 fiddle with empty series,extra legend (Latest with datalabel enabled)
you are almost there, use this >> put a field like "extra" in your series data .
Updated
labelFormatter: function() {
if(this.extra !=null){
return this.name + ' ('+this.extra+': ' + this.y + ' - ' + this.percentage.toFixed(1) + '%)' ;
}else{
return this.name + '(' + this.y + ' - ' + this.percentage.toFixed(1) + '%)' ;
}}
See the fiddle here
put a if condition to get rid of undefined .
As per comment below
create a empty series with the name "Extra" OR do like following
labelFormatter: function() { if(this.y ==null) return "Extra Legend"; jsfiddle.net/wjnnt28p/4
the catch is , as you are formatting legend,if y don't have any value it will show undefined text. (Empty series case) for that write conditional logic there.
Second solution is to return "Extra label" but click of this legend won't have data,so legendclick could be override .

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 Bar Chart: possible to combine datapoints inside dataLabels?

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;
},

Categories

Resources