i try to make negative value show in pie chart , and it success but when i use exporting 'downloadXLS' and 'viewData' the value its always show possitive, i know when use pie chart the data value must be possitive, but there is any method when export to 'downloadXLS' and 'viewData' can edit value data to negative ?
this is jsfiddle when i try to make the chart https://jsfiddle.net/zhpnos50/3/
Highcharts.chart('container', {
chart: {
type: 'pie',
},
title: {
text: 'Chart'
},
credits: {
enabled: false
},
tooltip: {
pointFormatter: function () {
if (this.y === null) {
return this.name + ': 0%';
} else {
return this.name + ': ' + (this.negative ? '-'+ this.y : this.y) + '%';
}
},
useHTML: true
},
legend: {
itemStyle: {
fontSize: '11px',
},
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || 'rgba(255,255,255,0.25)',
labelFormatter: function () {
if (this.y === null) {
return this.name + ': 0%';
} else {
return this.name + ': ' + (this.negative ? '-'+ this.y : this.y) + '%';
}
},
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
showInLegend: true,
dataLabels: {
formatter() {
let neg = this.point.negative,
value = this.point.negative ? -this.y : this.y,
negativeColor = Highcharts.defaultOptions.colors[0];
return '<b>'+this.point.name+'</b>: '+value+' %'
}
}
},
series: {
cursor: 'pointer',
}
},
series: [{
name: 'Value',
data: [{
name: 'A',
y: 106.733600
}, {
name: 'B',
y: 0.725800
}, {
name: 'C',
y: 0.000000
}, {
name: 'D',
y: 7.530000,
negative: true
}, {
name: 'E',
y: 0.070500
}]
}],
exporting: {
sourceHeight: 800,
sourceWidth: 800,
scale: 1,
buttons: {
contextButton: {
menuItems: ['printChart', 'downloadPNG', 'downloadJPEG', 'downloadPDF', 'downloadXLS','viewData']
}
}
}
});
<script src="https://github.highcharts.com/gantt/highcharts-gantt.src.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<div id="container"></div>
You can add the below plugin to modify exported values:
(function(H) {
H.addEvent(H.Chart, 'exportData', function(e) {
const dataRows = e.dataRows;
this.series[0].points.forEach(point => {
if (point.options.negative) {
// +2 to skip title rows
dataRows[point.index + 2][1] = -point.y;
}
});
});
}(Highcharts));
Live demo: https://jsfiddle.net/BlackLabel/ert78shL/
Docs: https://api.highcharts.com/highcharts/exporting.csv
Related
The date displayed on the highcharts xaxis label is showing non-existent dates, not actual data. What should be set on the xaxis label to show the existing date values?
My code is below.
Highcharts.stockChart('dataChart', {
credits: {
enabled: false
},
rangeSelector: {
selected: 5
},
title: {
text: result[0].chartRptCdNm
},
xAxis: {
type: "datetime",
labels: {
formatter: function() {
return Highcharts.dateFormat('%Y-%m-%d', this.value);
}
}
},
yAxis: {
title: {
text: result[0].graphYaxis
},
opposite: false,
lineWidth: 1,
margin: 0,
labels: {
format: '{value}' + result[0].graphYaxisUnit,
align: "right",
y: -5,
x: -5
}
},
tooltip: {
headerFormat: "",
useHTML: true,
valueDecimals: 2,
split: true,
formatter: function () {
var s = "";
$.each(this.points, function() {
s += '<span style="color:' + this.series.color + ';">\u25CF</span><b>' + this.series.name + '</b><br/>';
s += '<span style="font-size: 13px"> 일자 : ' + Highcharts.dateFormat('%Y-%m-%d', new Date(this.x)) + '</span><br/>';
s += '<span style="font-size: 13px"> 금리 : ' + (Math.floor(this.y * 100) / 100) + '</span><br/>';
});
return s;
}
},
series: seriesArr
});
I am making a chart using a single line series.
I'm trying to draw a chart where categories can be filtered, and it's working pretty nicely, I used this to do it.
Problem is : my last category is the total of the others, and so is taller. I want that when the "total" checkbox is unchecheck the chart resize, but it doesn't and resize only if I also uncheck the "class7" checkbox.
you can try it here : https://jsfiddle.net/4rfdgvum/
var chart=null;
$(function() {
var chart = new Highcharts.Chart('container', {
chart: {
type: 'column',
shadow: true
},
title: {
text: 'My Title'
},
xAxis: {
categories: [{"class":"class1","name":"cat1"},{"class":"class2","name":"cat2"},{"class":"class3","name":"cat3"},{"class":"class4","name":"cat4"},{"class":"class5","name":"cat5"},{"class":"class6","name":"cat6"},{"class":"class7","name":"cat7"},{'class': 'total','name':'total'}],
labels: {
formatter: function() {
return this.value.name;
},
useHTML: true
}
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Numbers'
}
},
legend: {
enabled: true
},
tooltip: {
formatter: function () {
return '<b>' + this.x.name + '</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',
formatter: function(){
return Highcharts.numberFormat(this.percentage,0) + '%';
}
}
}
},
series: [{
name: 'Ok',
color: 'green',
stack: 'a',
data: [
223,174,139,27,17,6,3,589 ]
},
{
name: 'Not Ok',
color: 'red',
stack: 'a',
data: [
21,29,26,14,15,11,11,127 ]
},
{
name: 'Partialy Ok',
color:'orange',
stack: 'a',
data: [
5,11,25,1,1,3,0,46 ]
},
{
name: 'Not usable',
color:'grey',
stack: 'a',
data: [
20,70,67,160,163,170,168,818 ]
},
{
name: 'Not done',
color:'brown',
stack: 'a',
data: [
173,158,185,240,246,252,260,1514 ]
}
]
}, function() {
$('input[type=checkbox]').bind('click', function() {
togglePointsByClass(this.value, $(this).is(':checked'), chart)
});
});
var visibleArr = [0,1,2,3,4,5,6,7];
function togglePointsByClass(className, shouldShow, chart) {
var isChartDirty = false;
if (shouldShow) {
chart.xAxis[0].userOptions.categories.forEach(function(category, i) {
if (category.class === className) {
visibleArr.push(i);
}
});
} else {
chart.xAxis[0].userOptions.categories.forEach(function(category, i) {
if (category.class === className && visibleArr.indexOf(i) > -1) {
visibleArr.splice(visibleArr.indexOf(i), 1);
}
});
}
if (visibleArr.length) {
chart.xAxis[0].update({
min: Math.min.apply(null, visibleArr),
max: Math.max.apply(null, visibleArr)
})
}
}
$('#container').highcharts().redraw();
});
Thanks
You can use axis.setExtremes() for setting max of the yAxis.
if (visibleArr.length) {
chart.xAxis[0].update({
min: Math.min.apply(null, visibleArr),
max: Math.max.apply(null, visibleArr)
}, false, false);
const max = visibleArr.reduce((a, b) => Math.max(chart.yAxis[0].stacks.columna[b].total, a), -Infinity)
chart.yAxis[0].setExtremes(0, max);
}
example: https://jsfiddle.net/mw7euo1a/
How can i update my tooltip when i clicked on toggle button?
I tried to add this (this.tooltip[0].update) on my button.toggle.onclickfunction():-
onclick: function () {
this.yAxis[0].update({
labels: {
formatter: function() {
return Highcharts.numberFormat((this.value / 1000000000).toFixed(2), 0, ',');
}
},
title: {
text: '<b>RM Billion</b>',
}
});
this.tooltip[0].update({
tooltip: {
formatter: function() {
return '<b>' + this.x + '</b><br> ' + this.series.name + ' : RM <b>' + Highcharts.numberFormat((this.y / 1000000).toFixed(2), 0, ',') + '</b>';
}
}
});
}
I thought by adding this.tooltip[0].update would change/update the tooltip as coded above, but nothing change. How can i do this?
Below are my current codes:-
Highcharts.chart('containerImport', {
title: {
text: 'Imports from ' + dataTitle['titleName'] + ', ' + dataYear[0] + ' - ' + dataYear[dataYear.length - 1],
align: 'left',
margin: 50
},
subtitle: {
text: '',
x: -20
},
lang: {
toggleButtonTitle: 'Currency Format',
contextButtonTitle: 'Print Chart'
},
xAxis: {
title: {
text: '<b>YEAR</b>',
align: 'high'
},
categories: dataYear
},
yAxis: {
title: {
text: '<b>RM Million</b>',
style: {
fontFamily: 'Arial'
},
align:'high',
rotation:0,
y: -13,
},
labels: {
formatter: function() {
return Highcharts.numberFormat((this.value / 1000000).toFixed(2), 0, ',');
}
}
},
tooltip: {
formatter: function() {
return '<b>' + this.x + '</b><br> ' + this.series.name + ' : RM <b>' + Highcharts.numberFormat((this.y / 1000000).toFixed(2), 0, ',') + '</b>';
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
series: [{
name: dataTitle['titleName'],
data: totalDataTrade
}],
exporting: {
enabled: true,
buttons: {
contextButton: {
_titleKey: 'contextButtonTitle',
},
toggle: {
_titleKey: 'toggleButtonTitle',
text: '$',
menuItems: [{
text: 'Billion',
onclick: function () {
this.yAxis[0].update({
labels: {
formatter: function() {
return Highcharts.numberFormat((this.value / 1000000000).toFixed(2), 0, ',');
}
},
title: {
text: '<b>RM Billion</b>',
}
});
}
}, {
text: 'Million',
onclick: function () {
this.yAxis[0].update({
labels: {
formatter: function() {
return Highcharts.numberFormat((this.value / 1000000).toFixed(2), 0, ',');
}
},
title: {
text: '<b>RM Million</b>',
}
});
}
}, {
text: 'Hundred Thousand',
onclick: function () {
this.yAxis[0].update({
labels: {
formatter: function() {
return Highcharts.numberFormat((this.value / 100000).toFixed(2), 0, ',');
// return Highcharts.numberFormat((this.value / 100000), 2, '.');
}
},
title: {
text: '<b>RM Hundred Thousand</b>',
}
});
}
}]
},
}
}
});
Any kind of helps would be appreciated! Thank you in advanced.
Move the tooltip property inside the series and then use Series.update()
onclick: function() {
this.series[0].update({
tooltip: {
pointFormat: 'tooltip changed'
}
});
}
example: https://jsfiddle.net/r4dfhkgy/
I plan to put the data in y-axis in a mouseover event of my x-axis labels, so that when a user hovers on an x-axis label, it will display a summary text of the values in my stack chart.
Question is how do I access y-axis data inside my x-axis:{...} code
here's my code
http://jsfiddle.net/BkxhA/3/
$(function () {
var categoryImgs = {
'AIA': '<img src="http://dummyimage.com/60x60/ff6600/ffffff"><img> ',
'AMP':'<img src="http://highcharts.com/demo/gfx/sun.png"><img> ',
'AMP RPP':'<img src="http://highcharts.com/demo/gfx/sun.png"><img> ',
'Asteron Life':'<img src="http://highcharts.com/demo/gfx/sun.png"><img> ',
'Fidelity Life':'<img src="http://highcharts.com/demo/gfx/sun.png"><img> '
};
var totals = new Array();
var stackTotals = new Array();
var i = 5, j = 0;
//totals = HighchartsAdapter
function reverse() {
totals.reverse();
}
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Premium Summary'
},
yAxis: {
min: 0,
title: {
text: ''
},
labels: {
formatter: function () {
return '$' + this.value;
}
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray',
},
formatter: function () {
totals[i++] = this.total;
return '';
},
}
},
xAxis: {
categories: ['AIA', 'AMP', 'AMP RPP', 'Asteron Life', 'Fidelity Life'],
labels: {
x: 5,
useHTML: true,
formatter: function () {
var n = totals.shift();
return '<div class="stacktotal">$' + n + '</div><div class="myToolTip" title="Hello ' + this.value + '">' + categoryImgs[this.value] + '</div>';
},
events: {
mouseover: function () {
$('#hoverboard').html('<img name="testimg" src="http://highcharts.com/demo/gfx/sun.png"><p>This should be the series y-axis data (this.series.data...something)<p>');
},
mouseout: function () {
$('#hoverboard').html('');
}
},
}
},
linkedTo: 0,
categories: ['AIA', 'AMP', 'AMP RPP', 'Asteron Life', 'Fidelity Life'],
legend: {
align: 'right',
x: -70,
verticalAlign: 'top',
y: 20,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColorSolid) || '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, 0 0 3px black'
},
format: '${y}'
}
}
},
series: [{
name: 'Policy Fee',
y:'$' + this.value,
data: [200.12, 290, 45.78, 71, 120]
}, {
name: 'WOP',
data: [150, 210.23, 150, 200, 100]
}, {
name: 'Income Protection',
data: [89, 400, 258.13, 212, 152]
}, {
name: 'Life Cover',
data: [150, 210.23, 150, 200, 100]
} ]
});
});
Looks like plugin has limitations - in event callback this is pointed to DOM element, instead of something in Highcharts.
To achieve what you need, you can add some custom attribute for created HTML tag in formatter, with info you need. For example passing index:
formatter: function () {
var axis = this.axis,
index = axis.categories.indexOf(this.value);
var n = totals.shift();
return '<div class="stacktotal" data-index="' + index + '">$' + n + '</div><div class="myToolTip" title="Hello ' + this.value + '">' + categoryImgs[this.value] + '</div>';
},
Then you can get that value in events:
mouseover: function () {
var chart = $("#container").highcharts(),
index = $(this).find('.stacktotal').attr("data-index");
console.log('Index', index); //index is index of category
var point = chart.series[0].data[index];
console.log('Point', point); // point for specific category in first series
$('#hoverboard').html('<img name="testimg" src="http://highcharts.com/demo/gfx/sun.png"><p>' + point.total + '<p>');
},
Demo with all: http://jsfiddle.net/BkxhA/4/
Here is a simplified version of the live scatter chart http://jsfiddle.net/ashwinp/z6QXW/8/
Now i am getting 0 1 2 etc like this on x-axis.i want user defined name on x axis.X axis labels should be pickup-ed from XLables array.
Same code from jsfiddle i have added here
var InfluenceCnt=0;
var QResiduals=[];
var XLables=[];
var HottelingT2=[];
var EllipseChartData;
var EllipseShift;
QResiduals.push('0.5356899');
QResiduals.push('0.5356899');
QResiduals.push('0.6356899');
QResiduals.push('0.2356899');
QResiduals.push('0.3356899');
QResiduals.push('0.1356899');
HottelingT2.push('0.1')
HottelingT2.push('0.2');
HottelingT2.push('0.3');
HottelingT2.push('0.4');
HottelingT2.push('0.5');
HottelingT2.push('0.6');
XLables.push('a')
XLables.push('b');
XLables.push('c');
XLables.push('d');
XLables.push('e');
XLables.push('f');
$(function () {
$(document).ready(function () {
Highcharts.setOptions({
global: {
useUTC: false
}
});
// Ellipse Plot
EllipseChartData = new Highcharts.Chart({
chart: {
renderTo: 'EllipseContainer',
type: 'scatter',
marginRight: 10,
zoomType: 'xy',
events: {
load: function () {
// set up the updating of the chart each second
EllipseSeries = this.series[0];
setInterval(function () {
EllipseShift = EllipseSeries.data.length > 20;
if (!isNaN(QResiduals[InfluenceCnt]) && $.isNumeric(QResiduals[InfluenceCnt]) && typeof (QResiduals[InfluenceCnt]) != "undefined") { //alert(QResiduals[InfluenceCnt]);
var x = HottelingT2[InfluenceCnt], // current time
y = parseFloat(QResiduals[InfluenceCnt]);
InfluenceCnt++;
EllipseSeries.addPoint([x, y], true, EllipseShift);
}
}, 1000);
}
}
},
title: {
text: 'Ellipse Plot'
},
xAxis: {
title: {
text: 'Sample'
},
plotLines: [{
value:2.5,
color: 'red',
dashStyle: 'shortdash',
width: 2,
label: {
text: ''
}
}]
},
yAxis: {
title: {
text: ''
},
plotLines: [{
value: 0.4,
color: 'red',
dashStyle: 'shortdash',
width: 2,
label: {
text: ''
}
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>X: ' +
Highcharts.numberFormat(this.x, 2) + '<br/> Y: ' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: true
},
series: [{
name: 'Ellipse Plot',
data: []
}]
});
});
});
The option you need is 'categories' on the xAxis. Try this:
xAxis: {
title: {
text: 'Sample'
},
categories:XLables,
http://jsfiddle.net/euVvy/
To fix the tooltip, you just need to refer to 'this.x', which will return the category name:
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>X: ' +
this.x + '<br/> Y: ' +
Highcharts.numberFormat(this.y, 2);
}
},
http://jsfiddle.net/4aDQ2/
You can use categories or labels formatter which allows to define "displayed label http://api.highcharts.com/highstock#xAxis.labels.formatter