Highcharts angular.js custom tooltip - angularjs

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']
}]

Related

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>

Highcharts Showing negative values on tooltip

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/

custom ticks based on selected range from rangeSelector in Highstock

I am trying to get my Highcharts/Highstock chart to display a custom tick when the rangeSelector is set to All, I have it setup this way, but is throwing me errors when I try to use the interactive portion of the graph
Received below answer from Highstock Change tick interval on range selector change
componentDidMount() {
// Timezone Offset for PST standard is UTC timezone
Highcharts.setOptions({
global: {
timezoneOffset: 8 * 60
},
lang: {
thousandsSep: ','
}
});
Highcharts.stockChart('chart', {
chart: {
backgroundColor:'rgba(255, 255, 255, 0.0)',
height: 400,
zoomType: 'xy'
},
title: {
text: 'Bitcoin Chart',
style: {
color: 'white'
}
},
navigator: {
trigger: "navigator",
triggerOp: "navigator-drag",
rangeSelectorButton: undefined,
handles: {
backgroundColor: 'white',
borderColor: 'black'
}
},
scrollbar: {
enabled: false
},
rangeSelector: {
buttons: [{
type: 'day',
count: 1,
text: '1d'
}, {
type: 'day',
count: 7,
text: '7d'
}, {
type: 'month',
count: 1,
text: '1m'
}, {
type: 'month',
count: 3,
text: '3m'
}, {
type: 'year',
count: 1,
text: '1y'
}, {
type: 'all',
text: 'All'
}],
selected: 6,
// styles for the buttons
buttonTheme: {
fill: 'black',
// stroke: 'none',
'stroke-width': 0,
r: 8,
style: {
color: 'white',
fontWeight: 'bold'
},
states: {
hover: {
},
select: {
fill: 'white',
style: {
color: 'black'
}
}
}
},
// Date Selector box
inputBoxBorderColor: 'black',
inputBoxWidth: 120,
inputBoxHeight: 18,
inputStyle: {
color: 'black',
fontWeight: 'bold'
},
labelStyle: {
color: 'silver',
fontWeight: 'bold'
},
},
series: [{
name: 'Bitcoin Price',
color: 'black',
data: this.props.data.all_price_values,
type: 'area',
threshold: null,
tooltip: {
valuePrefix: '$',
valueSuffix: ' USD',
valueDecimals: 2
}
}],
plotOptions: {
series: {
fillColor: {
linearGradient: [0, 0, 0, 0],
stops: [
[0, '#FF9900'],
[1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
]
}
}
},
xAxis: {
events: {
setExtremes: function(e) {
if (e.trigger === "rangeSelectorButton" && e.rangeSelectorButton.text === "All") {
var range = e.max - e.min;
// ticks spaced by one day or one hour
var ticksSpacing = range >= 86400 * 1000 ? 86400 : 3600;
this.update({
tickPositioner: function() {
var positions = [],
info = this.tickPositions.info;
for (var x = this.dataMin; x <= this.dataMax; x += ticksSpacing * 1000) { // Seconds * 1000 for ticks
positions.push(x);
};
positions.info = info;
return positions;
}
}, false);
}
}
},
title: {
enabled: true,
text: 'Date (Timezone: PST)',
style: {
color: 'white'
}
},
labels: {
style: {
color: 'white'
}
},
type: 'datetime',
dateTimeLabelFormats: {
day: '%b %e, %Y'
},
tickInterval: 1
},
yAxis: {
floor: 0,
labels: {
formatter: function () {
return '$' + this.axis.defaultLabelFormatter.call(this);
},
format: '{value:,.0f}',
align: 'left',
style: {
color: 'white'
},
},
},
// Mobile Design
responsive: {
rules: [{
condition: {
maxWidth: 600
},
chartOptions: {
chart: {
height: 400
},
subtitle: {
text: null
},
navigator: {
enabled: false
}
}
}]
}
});
}
I am talking about the blue highlighted section, when I move it, it throws an error
I am trying to get the charts to have 2 plots per day on ALL rangeSelector, displaying the first point in the day and the last point in a day. What am I doing wrong?
EDIT 1 : Updated to full config, X Axis is now being disrupted by the original answer, ticks on custom range selector is still in works. Added images to show what's going on
The setExtremes event is raised each time you change the range to be displayed on the graph. It can have several origins:
A button click in the range selector
An handle drag in the navigator
etc..
The actual properties of the event depend on its origin. If you output the event with console.log(e), you'll see that it's not the same for these two origins:
Button click in the range selector
{
trigger: "rangeSelectorButton",
rangeSelectorButton: {
text: "2Hour",
type: "hour",
count: 2,
},
...
}
Handle drag in the navigator
{
trigger: "navigator",
triggerOp: "navigator-drag",
rangeSelectorButton: undefined
}
If you drag the handle in the navigator, there's no rangeSelectorButton attached to the event, because it doesn't make sense: in that case, no button is pressed.
To fix your error, you can add a check on the trigger property:
xAxis: {
events: {
setExtremes: function(e) {
if (e.trigger === "rangeSelectorButton" && e.rangeSelectorButton.text === "All") {
...
}
}
}
How to solved the actual issue
Now, the REAL issue. You want to change the ticks based on what is displayed: either the beginning and end of each day, or hours if not a complete day. You can do that with e.min and e.max, that represent the selected time range.
Like so:
setExtremes: function(e) {
var range = e.max - e.min;
// ticks spaced by one day or one hour
var ticksSpacing = range >= 86400 * 1000 ? 86400 : 3600;
this.update({
tickPositioner: function() {
var positions = [],
info = this.tickPositions.info;
for (var x = this.dataMin; x <= this.dataMax; x += ticksSpacing * 1000) { // Seconds * 1000 for ticks
positions.push(x);
};
positions.info = info;
return positions;
}
}, false);
}

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

Highmaps scroll down when page load - Angular SPA

I m developing report page. In this page I m using highcharts and highmaps together. At first load there is no more problem but when user click the another page, then back to again this report page highmaps area scroll down.
I have single page application, so every link using ajax call.
I found this solution, but this way I cannot store any rootscope element. Also I dont want to use cookies or localstorage.
$('#mapsmaps').highcharts('Map', {
title : {
text : 'City Lived',
style: {
color: '#008bff'
}
},
subtitle : {
text : ''
},
legend: {
title: {
text: ' ',
style: {
color: (Highcharts.theme && Highcharts.theme.textColor) || 'black'
}
},
floating: true,
valueDecimals: 0,
valueSuffix: '',
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || 'rgba(255, 255, 255, 0.85)',
symbolRadius: 0,
symbolHeight: 10,
},
mapNavigation: {
enabled: false,
buttonOptions: {
verticalAlign: 'bottom'
}
},
tooltip: {
// backgroundColor: 'none',
// borderWidth: 0,
// shadow: false,
useHTML: true,
padding: 0,
pointFormat: '<span class="f32"></span>'
+ ' {point.name}'
},
colorAxis: {
dataClasses: [{
from: 1,
to: 1000,
color: "#5FA08F"
}, {
from: 1000,
to: 2000,
color: "#82A970"
}, {
from: 2000,
to: 3000,
color: "#E5AF47"
}, {
from: 3000,
to: 4000,
color: "#EC8A37"
}, {
from: 4000,
to: 5000,
color: "#F55126"
}, {
from: 5000,
color: "#F30505"
}]
},
series : [{
data : data,
mapData: Highcharts.maps['countries/en/en-all'],
joinBy: 'hc-key',
name: 'City',
states: {
hover: {
color: '#BADA55'
}
},
animation: {
duration: 1000
},
dataLabels: {
enabled: false,
format: '{point.name}'
}
}],
navigation: {
buttonOptions: {
enabled: false
}
}
});
}

Resources