Highcharts Showing negative values on tooltip - angularjs

I have set min:0, in y-axis. But in tooltip i want to show negative values also and also it should start with value y=0 only.
if i will remove min:0 in y axis it will show negative values with tooltip in chart. But i only want to see negative values on tooltip not on chart.
but it is not allowing me to show negative values.
below is sample code.
$(id).highcharts({
chart: {
zoomType: 'xy',
marginLeft: 45,
marginRight: rightval - 10
},
title: { text: title },
exporting: { enabled: false },
credits: { enabled: false },
legend: { enabled: false, align: 'left', x: 10, verticalAlign: 'bottom', y: 3, shadow: false },
xAxis: {
min: minimum,
max: maximum,
scrollbar: {
enabled: scroobarVal
},
fontWeight: 'bold',
categories: Data['categories'],
labels: {
y: 20,
rotation: 0,
style: {
color: 'gray',
//fontSize:'1px !important;'
}
}
},
yAxis: [{
min: 0,
allowDecimals: false,
endOnTick: false,
gridLineWidth: 0,
labels: {
formatter: function () {
if (optionSelected == 'Day') {
return this.value;
} else {
return this.value / 1000000 + 'M';
}
},
style: {
color: '#767676'
}
},
offset: -10,
title: {
text: 'Inv ' + val_qty,
"textAlign": 'top',
"rotation": 0,
x: 60,
y: yaxisVal,
style: {
color: '#767676',
fontWeight: 'bold'
}
}
}, {
allowDecimals: false,
min: 0,
endOnTick: false,
gridLineWidth: 0,
title: {
text: y2axisname,
"textAlign": 'top',
"rotation": 0,
x: -75,
y: yaxisVal,
style: {
color: '#767676',
fontWeight: 'bold'
}
},
offset: -10,
labels: {
format: '{value}',
style: {
color: '#767676'
}
},
opposite: true
}],
labels: {
items: [{
html: ' ',
style: {
color: (Highcharts.theme && Highcharts.theme.textColor) || 'black'
}
}]
},
tooltip: {
style: { fontSize: '7pt' },
formatter: function () {
var s = '<b>' + this.x + '</b>';
$.each(this.points, function (i, point) {
s += '<br/><span style="color:' + point.series.color + '">\u25CF</span> ' + point.series.name + ': <b>' + CurrencySymbol + '</b>' + point.y.toString().replace(/,/g, "").replace(/\B(?=(\d{3})+(?!\d))/g, ", ");
});
return s;
},
shared: true
},
series: Data['series'],
});

I don't think there is a simple way to do this on Highchart.
One hacky way I found (don't judge me!) is to have a "ghost" series and set the tooltip.shared option to true.
Check it here: http://jsfiddle.net/arryx9rf/

Related

Highcharts column chart with target and color gradient

Is below chart possible in highchart
Column with high, low and target
Color gradient with denser on target and lighter away
Data table for low, high and target
Managed to get some bits, but not full functionality
https://jsfiddle.net/z9u5hgod/2/
TIA
[
{
type: 'bullet',
dataLabels: [
{ format: '{point.y}' } ,
{format: '{point.target}',
inside: true},
{
inside: true,
verticalAlign: 'bottom',
align: 'center',
format: '{point.low}'
}
],
data: [
{
low: 250,
y: 1650,
target: 750,
color: {
linearGradient: [0, '70%', 0, '50%'],
stops: [
[0, 'green'],
[1, 'orange']
]
}
},
{
low: 100,
y: 2000,
target: 1500
}
]
},
{
data: [{
low: 600,
y: 2350,
target: 2100
}, {
low: 450,
y: 1700,
target: 1250
}]
}]
Response from higcharts developer
https://jsfiddle.net/BlackLabel/xbvp8he7/
const chart = Highcharts.chart('container', {
chart: {
type: 'bullet',
events: {
load() {
const firstSeries = this.series[0];
firstSeries.data.forEach(point => {
const {
low,
y,
target
} = point,
gradientPoint = (y - target) / (y - low);
point.update({
color: {
linearGradient: {
x1: 0,
x2: 0,
y1: 0,
y2: 1
},
stops: [
[0, 'blue'],
[gradientPoint, 'purple'],
[1, 'blue']
],
}
})
})
}
}
},
plotOptions: {
series: {
pointPadding: 0.2,
groupPadding: 0.1,
targetOptions: {
borderWidth: 0,
height: 3,
color: 'red',
width: '100%'
}
}
},
xAxis: {
categories: ['Alex ar', 'Cairo ar']
},
series: [
{
type: 'bullet',
dataLabels: [{
enabled: true,
}, {
enabled: true,
verticalAlign: 'top',
align: 'center',
color: 'white',
useHTML: true,
formatter() {
const point = this.point,
target = point.targetGraphic,
targetY = target.getBBox().y - point.shapeArgs.y - 25;
return `
<div class="datalabelInside" style="position: relative; top: ${targetY}px">${point.target}</div>
`;
}
}, {
verticalAlign: 'bottom',
inside: true,
y: 20,
format: '{point.low}',
enabled: true
}, ],
data: [{
low: 250,
y: 1650,
target: 750
},
{
low: 100,
y: 2000,
target: 1500
}
]
},
{
data: [{
low: 600,
y: 2350,
target: 2100
}, {
low: 450,
y: 1700,
target: 1250
}]
}
],
tooltip: {
pointFormat: '<b>{point.y}</b> (with target at {point.target})'
}
});

How to set X coordinate for each bar with react chart js 2?

I want to make a chart with min and max vertical lines and bars between them. I can't find information how to set bars' X coordinate or make custom line plot with vertical 'bars' instead of points.
And also I don't understand how to scale X axis, why MAX is left-side MIN? Min=22.5, Max=24.5
let plot_options = {
showScale: true,
pointDot: true,
showLines: true,
maintainAspectRatio: false,
annotation: {
annotations: [
{
type: 'line',
mode: 'vertical',
scaleID: 'y-axis-0',
value: min,
borderColor: 'red',
borderWidth: 2,
label: {
backgroundColor: 'red',
content: 'Min',
enabled: true,
},
},
{
type: 'line',
mode: 'vertical',
scaleID: 'y-axis-0',
value: max,
borderColor: 'red',
borderWidth: 2,
label: {
backgroundColor: 'red',
content: 'MAX',
enabled: true,
},
},
]
},
title: {
display: true,
text: plotHeader,
},
responsive: true,
legend: {
display: false,
},
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: labelx
},
ticks: {
min: min,
max: max
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: labely
},
ticks: {
beginAtZero: true,
},
}]
},
}
data = {
barPercentage: 0.5,
barThickness: 6,
maxBarThickness: 8,
minBarLength: 2,
labels: labels,
datasets: [{
data: values,
borderColor: BLUE,
backgroundColor: BLUE
}]
}
<Bar options={plot_options} data={data} plugins={ChartAnnotation} />
That's what I expect:
This solution is based on this answer for the positioning of the bars on a linear x-axis.
You can further use the Plugin Core API to draw the vertical min and max lines with their labels directly on the canvas. The API offers a number of hooks that can be used to perform custom code. In your case, you could use the afterDraw hook together with CanvasRenderingContext2D.
Please take a look at the runnable code below and see how it works. It should not be too hard to make similar code work with react-chartjs-2.
new Chart("chart", {
type: 'bar',
plugins: [{
afterDraw: chart => {
let ctx = chart.chart.ctx;
ctx.save();
let xAxis = chart.scales['x-axis-0'];
let yAxis = chart.scales['y-axis-0'];
let dataset = chart.data.datasets[0];
[dataset.min, dataset.max].forEach((v, i) => {
var x = xAxis.getPixelForValue(+v * 1000);
ctx.fillStyle = 'red';
ctx.font = '14px Arial';
ctx.textAlign = 'center';
ctx.fillText(i == 0 ? 'Min' : 'Max', x, yAxis.top + 14);
ctx.fillStyle = 'gray';
ctx.font = '12px Arial';
ctx.fillText(v, x, yAxis.bottom + 20);
ctx.beginPath();
ctx.moveTo(x, yAxis.top + 20);
ctx.strokeStyle = 'red';
ctx.lineTo(x, yAxis.bottom + 3);
ctx.stroke();
});
ctx.restore();
}
}],
data: {
datasets: [{
min: 22.5,
max: 24.5,
data: [
{ x: '22.83', y: 18 },
{ x: '23.17', y: 15 },
{ x: '23.44', y: 13 },
{ x: '24.32', y: 20 }
],
borderColor: 'blue',
backgroundColor: 'blue',
barThickness: 20
}]
},
options: {
legend: {
display: false,
},
scales: {
xAxes: [{
offset: true,
type: 'time',
time: {
parser: 'X',
unit: 'millisecond',
displayFormats: {
millisecond: 'X'
}
},
ticks: {
source: 'data',
min: '22.5',
callback: (v, i, values) => values[i].value / 1000
},
gridLines: {
display: false
},
}],
yAxes: [{
ticks: {
beginAtZero: true,
max: 22,
stepSize: 2
}
}]
}
}
});
canvas {
max-width: 500px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.bundle.min.js"></script>
<canvas id="chart" height="200"></canvas>

React HighCharts Custom Legend

I'm trying to customise my chart's legend. My current legend needs to look like this legend.
Basically I need to make the circular icons rectangular and change the legend text color to correspond with the icon.
I've looked everywhere in the docs but I'm not finding a solution. This is how I configured the graph below (legend > itemStyle):
useEffect(() => {
Highcharts.chart(chart.current, {
chart: {
type: 'column',
style: {
fontFamily: '"Roboto", sans-serif',
},
height: 312,
},
credits: {
enabled: false,
},
title: {
text: null,
},
xAxis: {
categories,
labels: {
step: 1,
style: {
fontSize: '8px',
color: '#808992',
},
useHTML: true,
formatter() {
const day = this.value.format('D');
if (moment().isSame(this.value, 'd')) {
return `<strong style="font-weight: 900; color: #0E2C47;">${day}</strong>`;
}
return day;
},
},
gridLineWidth: 1,
},
yAxis: {
min: 0,
title: {
text: `Collections ${showValue ? 'value' : 'count'}`,
style: {
color: '#0E2C47',
fontWeight: '500',
fontSize: '12px',
letterSpacing: '0.3px',
lineHeight: '14.4px',
},
},
labels: {
style: {
fontSize: '8px',
color: '#808992',
},
useHTML: true,
formatter() {
// eslint-disable-next-line react/no-this-in-sfc
const collection = this.value;
const format = Math.abs(collection) > 999 ? `${Math.sign(collection) * ((Math.abs(collection) / 1000).toFixed(1))}K` : Math.sign(collection) * Math.abs(collection);
return `${format}`;
},
},
useHTML: true,
},
legend: {
title: {
text: 'Status',
style: {
fontSize: '12px',
letterSpacing: '0.3px',
color: '#0A1944',
fontWeight: '500',
},
},
itemStyle: {
fontSize: '10px',
letterSpacing: '0.25px',
fontWeight: '500',
color: '#0A1944',
},
reversed: 'true',
layout: 'vertical',
align: 'right',
verticalAlign: 'bottom',
itemMarginBottom: 8,
x: -30,
y: -2,
},
plotOptions: {
series: {
stacking: 'normal',
},
},
tooltip: {
formatter() {
// eslint-disable-next-line react/no-this-in-sfc
return `<b>${this.y} ${this.series.name}</b><br/>${this.x.format('D MMM YYYY')}`;
},
},
series: [{
name: 'Draft',
data: chartData.draft, // [...times(() => null, 30), ...times(random, 31)],
color: collectionStateColors.draft, // processed
legendIndex: 0,
}, {
name: 'Approved',
data: chartData.approved,
color: collectionStateColors.approved, // orange
legendIndex: 1,
}, {
name: 'Expired',
data: chartData.expired,
color: collectionStateColors.expired, // purple
legendIndex: 2,
}, {
name: 'Submitted',
data: chartData.submitted,
color: collectionStateColors.submitted, // purple
legendIndex: 3,
}, {
name: 'Tracking',
data: chartData.tracking,
color: collectionStateColors.tracking, // light blue
legendIndex: 4,
}, {
name: 'Processed',
data: chartData.processed,
color: collectionStateColors.processed, // dark blue
legendIndex: 5,
}],
});
});

Highcharts angular.js custom tooltip

I am working on following example https://jsfiddle.net/neelkamal0666/6737c2q5/
Highcharts.chart('container', {
chart: {
type: 'column'
},
colors: ["rgb(241,198,64)", "#0091ea"],
title: {
text: ' ',
useHTML : true
},
xAxis: {
categories: ['Sowing', 'Activity', 'Application', 'Harvest']
},
yAxis: {
min: 0,
title :'',
stackLabels: {
enabled: false,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'right',
x: -30,
verticalAlign: 'top',
y: 25,
floating: true,
backgroundColor: 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
credits: {
enabled: false
},
tooltip: {
shared: false,
backgroundColor: 'black',
borderColor: 'black',
borderRadius: 10,
color: 'white',
useHTML :true,
borderWidth: 3,
headerFormat: '<b style="color: #fff;">{point.x}</b><br/>',
pointFormat: '<b style="color: #fff;">{series.name}: {point.y}</b><br/><b style="color: #fff;">Total(%): {point.stackTotal}</b><br />',
/*formatter: function () {
var s = '<b>' + this.x + '</b>';
angular.forEach(this.points, function () {
s += '<br/>' + this.series.name + ': ' +
this.y + 'm';
});
return s;
} */
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: false,
color: 'white',
style: {
textShadow: ''
}
}
},
series: {
pointWidth: 50, //width of the column bars irrespective of the chart size
additional : ["Sowing Area", "Activity", "Application", "Harvest"]
}
},
series: [{
name: 'Pending(%)',
data: [60, 40, 20, 80],
}, {
name: 'Completed(%)',
data: [40, 60, 80, 20],
}]
});
On tooltips I want to display different values
e.g if user clicks on sowing it will show
Pending : 60
Total : 100
Sowing Area : 4500 H
Plots Audited : 1200 H
And when user clicks on activities, it will show
Pending : 40,
Completed : 60,
Total : 100,
Total Activities : 200
Closed Activities : 125
When user clicks on Application, it will show
Pending :20,
Completed :80
Total :100,
Per acre usage : 200
And When user clicks on Harvest, it will show
Pending :80,
Completed :20
Total :100,
Volume Forcast : 100MT
I read the documentation of Highchart and went through lot of examples but still unable to figure out how can I achieve this.
Can someone help?
To change tooltip display you could add more info per data point and later access it and set it in tooltip's formatter.
Example: https://jsfiddle.net/woo70ers/
It might be easier to have all extra info in another array - easier too loop, whatever the additional into is.
Simple example: http://jsfiddle.net/am5ynoLg/
tooltip: {
formatter: function() {
var ret = 'x: ' + this.x + ', y: ' + this.y;
Highcharts.each(this.point.extraForTooltip, function(info) {
ret += '<br/>' + info[0] + ': ' + info[1];
});
return ret;
}
},
series: [{
data: [
[0, 1, [['opt1',123],['opt2','nice']] ],
[1, 2, [['opt2','bueno'],['opt3','ESP_#42']] ]
],
keys: ['x', 'y', 'extraForTooltip']
}]

highchart datalabel one value is missing in label

i have highchart graph api similar to pasted fiddle link, the problem
is number is missing in few stacked column( example in fiddle decission line one label value is missing) could anyone help on this why
this is happening
$(function () {
$('#container').highcharts({
chart: {
type: 'column',
inverted:true,
height: 200
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: ['Pending', 'Further', 'Decision']
},
yAxis: {
min: 0,
//max:100,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'center',
x: -30,
verticalAlign: 'top',
y: 25,
floating: false,
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
crop:false,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
style: {
textShadow: '0 0 3px black'
}
}
}
},
series: [{
data:[3, 2, 1],
name:'Today'
}, {
data:[2, 2, 19],
name:'1 Day'
}, {
data:[14, 2, 22],
name:'2 Days'
},{
data:[6, 2, 18],
name:'3 Days'
},{
data:[10, 2, 537],
name:'>3 Days'
}]
});
});
http://jsfiddle.net/g6wsd1hm/
If I change stacking to percent ,all labels are visible. minPointLength is set to make minimum column stacks width for a relatively less number
use following :
plotOptions: {
column: {
stacking: 'percent',
minPointLength:10 //this needs to added
}
}
Fiddle Here

Resources