Highchart - Area chart: customize tooltip - javascript

I am trying to customize the tooltip of area chart. I am using Highchart for this.
I am plotting 3 series in area chart. My requirement is to show tooltip at fixed location in chart which is top center. Now, when i put cursor at any point then tooltip should show all series name and their current value where the cursor is. Refer below image:
Currently i am able to show tooltip on top - center and putting mouse at any point is showing current series name and data but it is showing current series name in all 3 places.
Highchart option:
Highcharts.chart('container', {
chart: {
type: 'area'
},
title: {
text: 'ACCUMULATED WEALTH'
},
xAxis: {
categories: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
tickmarkPlacement: 'on',
crosshair: {
width: 1,
color: "#ccc"
},
title: {
enabled: false
}
},
yAxis: {
title: {
text: false
},
opposite: true,
labels: {
formatter: function() {
return '$' + this.value + 'k';
}
},
},
tooltip: {
backgroundColor: 'none',
borderWidth: 0,
shadow: false,
useHTML: true,
shared: true,
padding: 0,
split: false,
headerFormat: "",
pointFormat: '<table><tr><td>{point.y}</td><td>{point.y}</td><td>{point.y}</td></tr>' +
'<tr><td>{series.name}</td><td>{series.name}</td><td>{series.name}</td></tr></table>',
footerFormat: "",
positioner: function () {
return { x: 250, y: 25 };
}
},
plotOptions: {
area: {
stacking: 'normal',
lineColor: '#666666',
lineWidth: 1,
marker: {
lineWidth: 1,
lineColor: '#666666'
}
}
},
series: [{
name: 'Cash Flow',
data: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
}, {
name: 'Appreciation',
data: [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
}, {
name: 'Principal',
data: [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33]
}]
});
Here is what i have tries so far:
https://jsfiddle.net/2pdossk7/13/
Please help. Thanks in advance!

It might be difficult to achieve the desired result without tooltip.formatter.
This is how you can build tooltip text in a formatter:
formatter: function(tooltip) {
const points = this.points;
let str = '<table><tr>';
points.forEach(point => {
str += '<td style="text-align:center">' + point.y + '</td>';
});
str += '</tr><tr>';
points.forEach(point => {
str += '<td><span style="font-size:20px;color:' + point.color + '">●</span> ' + point.series.name + '</td>';
});
str += '</tr></table>';
return str;
},
And position it in the center of the chart:
positioner: function () {
const chart = this.chart;
return { x: (chart.plotWidth + chart.marginRight - this.label.getBBox().width) / 2, y: chart.plotTop + 10 };
}
Example and output
https://jsfiddle.net/eb3ou25v/

You can achieve desired result using pointFormat method
This is how you can use this
pointFormat: '<table style="text-align:center; display: inline-block; background: white;"><tr><td>{point.y}</td></tr>' +
'<tr><td><span style="font-size:20px;color:{series.color}">●</span> {series.name}</td></tr></table>',
positioner: function () {
const chart = this.chart;
return { x: (chart.plotWidth + chart.marginRight - this.label.getBBox().width) / 2, y: chart.plotTop - 20 };
}
for jsfiddle example click here

Related

How not to round values in apexchart

I need the graph to display the values without rounding, the same as shown in the tooltip
In your chart options dataLabels use the formatter to define the display value, e.g.
dataLabels: {
formatter: function(val) {
return val.toFixed(2);
}
}
Full example with demo chart taken from official docs and added custom label:
var options = {
series: [{
name: 'Marine Sprite',
data: [44, 55, 41, 37, 22, 43, 21]
}, {
name: 'Striking Calf',
data: [53, 32, 33, 52, 13, 43, 32]
}, {
name: 'Tank Picture',
data: [12, 17, 11, 9, 15, 11, 20]
}, {
name: 'Bucket Slope',
data: [9, 7, 5, 8, 6, 9, 4]
}, {
name: 'Reborn Kid',
data: [25, 12, 19, 32, 25, 24, 10]
}],
chart: {
type: 'bar',
height: 350,
stacked: true,
stackType: '100%'
},
plotOptions: {
bar: {
horizontal: true,
},
},
stroke: {
width: 1,
colors: ['#fff']
},
title: {
text: '100% Stacked Bar'
},
xaxis: {
categories: [2008, 2009, 2010, 2011, 2012, 2013, 2014],
},
dataLabels: {
formatter: function(val) {
return val.toFixed(2);
}
},
tooltip: {
y: {
formatter: function(val) {
return val + "K"
}
}
},
fill: {
opacity: 1
},
legend: {
position: 'top',
horizontalAlign: 'left',
offsetX: 40
}
};
var chart = new ApexCharts(document.querySelector("#chart"), options);
chart.render();
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<div id="chart"></div>

Trying to change background color in chart js filter

I am new to development and trying to do a project where I creating a webpage which have price range filter and there is a chart linked to that price range filter. What I am trying to do is change the background color of my labels of chartJs according to ranger filter. I want only labels in given range to show orange color and other labels should show light pink color, but here when I change background color after giving a condition all the labels' color get changed but i want only labels falling under filter range change the color.
trying to achieve range filter in this
let canvasElement = document.getElementById("productChart");
const dataPoints = [21, 0, 19, 3, 5, 0, 2, 3, 10, 4, 6, 7, 2, 0, 0, 0, 24, 30, 32, 45, 44, 22,
21, 10, 7, 5, 4, 3, 1, 0, 0];
const labels = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31]
const backgroundColor = 'rgba(255, 99, 71, 0.3)';
const newBackgroundColor = 'rgba(255, 99, 71, 1)';
let config =
{
type: 'bar',
data: {
labels: labels,
datasets: [{
barPercentage: 0.5,
barThickness: 5,
maxBarThickness: 12,
minBarLength: 2,
// label: 'Number of Phones',
data: dataPoints, //price
backgroundColor: backgroundColor,
borderColor: [
'rgba(255, 99, 71, 0.2)',
],
borderWidth: 1,
borderRadius: 5,
// borderSkipped: false,
}]
},
options: {
responsive: true,
scales: {
x: {
ticks: {
display: false, //this will remove only the label
},
grid: {
display:false,
borderColor: 'black', // <-- this line is answer to initial question
borderWidth:2,
}
},
y: {
display: false, //this will remove only the label
},
},
plugins: {
legend: {
display: false,
},
tooltip: {
enabled: false,
displayColors: false,
padding: 10,
yAlign: 'top',
},
},
}
}
let productChart = new Chart(canvasElement, config)
const start = document.getElementById('start')
const end = document.getElementById('end')
function updateMin(range) {
const minValue = labels.slice(range.value - 1, end.value);
let newLabels = productChart.config.data.labels
for(let i = 0; i < newLabels.length; i++){
value = newLabels[i];
if (minValue.includes(value)){
productChart.config.data.datasets[0].backgroundColor=newBackgroundColor;
}
}
end.min = range.value
productChart.update();
}
You could use a scriptable options for backgroundColor options. Based on the argument, context.index (see here the doc: https://www.chartjs.org/docs/latest/general/options.html#scriptable-options) you can decide at runtime which color to use.
In the below snippet, changing the stepper values, the chart will change the background colors.
I have used part of your code. Instead of using the stepper, you can use your slider or what you are using.
const dataPoints = [21, 0, 19, 3, 5, 0, 2, 3, 10, 4, 6, 7, 2, 0, 0, 0, 24, 30, 32, 45, 44, 22,
21, 10, 7, 5, 4, 3, 1, 0, 0];
const labels = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 30, 31]
const backgroundColor = 'rgba(255, 99, 71, 0.3)';
const newBackgroundColor = 'rgba(255, 99, 71, 1)';
const from = document.getElementById("from");
const to = document.getElementById("to");
const ctx = document.getElementById("myChart");
const myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
//barPercentage: 0.5,
//barThickness: 5,
//maxBarThickness: 12,
//minBarLength: 2,
data: dataPoints,
backgroundColor(ctx) {
const fromValue = parseFloat(from.value);
const toValue = parseFloat(to.value);
const value = ctx.index + 1;
if (value >= fromValue && value <= toValue) {
return newBackgroundColor;
}
return backgroundColor;
},
borderColor: 'rgba(255, 99, 71, 0.2)',
borderWidth: 1,
borderRadius: 5,
}]
},
options: {
responsive: true,
scales: {
x: {
ticks: {
display: false,
},
grid: {
display:false,
}
},
y: {
display: false,
},
},
plugins: {
legend: {
display: false,
},
tooltip: {
enabled: false,
},
},
}
});
from.addEventListener('click', function() {
myChart.update();
});
to.addEventListener('click', function() {
myChart.update();
});
.myChartDiv {
max-width: 600px;
max-height: 400px;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.9.1/dist/chart.min.js"></script>
<html>
<body>
<div class="myChartDiv">
<canvas id="myChart" width="600" height="400"/>
</div>
From:
<input type="number" id="from" min="1" max="31" value="1"/>
To:
<input type="number" id="to" min="1" max="31" value="31"/>
</body>
</html>

jQuery slider range with HighCharts y-Axis

I am trying to add a jQuery slider range bar on a HighCharts line chart to zoom in/out vertically.
Here is how I have done this
var ymax = 0.0;
var pSliderUnit = 0;
$(function() {
$('#lineChart').highcharts({
chart: {
type: 'line',
zoomType: 'xy'
},
title: {
text: ''
},
credits: {
enabled: false
},
xAxis: {
type: 'datetime',
reversed: true
},
yAxis: [{
events: {
afterSetExtremes: function(e) {
$("#pSliderBar").slider("values", 0, e.min);
$("#pSliderBar").slider("values", 1, e.max);
}
},
minRange: 1,
showEmpty: false,
labels: {
format: '{value}'
},
title: {
text: '\xB5g/m\xB3'
},
plotLines: []
},
{
events: {
afterSetExtremes: function(e) {
$("#pSliderBar").slider("values", 0, e.min);
$("#pSliderBar").slider("values", 1, e.max);
}
},
minRange: 1,
showEmpty: false,
labels: {
format: '{value}'
},
title: {
text: 'mtr/sec'
},
opposite: true,
plotLines: []
},
{
events: {
afterSetExtremes: function(e) {
$("#pSliderBar").slider("values", 0, e.min);
$("#pSliderBar").slider("values", 1, e.max);
}
},
minRange: 1,
showEmpty: false,
labels: {
format: '{value}'
},
title: {
text: 'degrees'
},
plotLines: []
},
],
series: [{
type: 'spline',
name: 'Value 1',
yAxis: 0,
tooltip: {
valueSuffix: '\xB5g/m\xB3'
},
data: [
[Date.UTC(2018, 4, 14, 16, 20, 0), 20.4],
[Date.UTC(2018, 4, 14, 16, 30, 0), 17.6],
[Date.UTC(2018, 4, 14, 16, 40, 0), 18.8],
[Date.UTC(2018, 4, 14, 16, 50, 0), 18.9]
]
},
{
type: 'spline',
name: 'Value 2',
yAxis: 0,
tooltip: {
valueSuffix: '\xB5g/m\xB3'
},
data: [
[Date.UTC(2018, 4, 14, 16, 20, 0), 11.2],
[Date.UTC(2018, 4, 14, 16, 30, 0), 10.5],
[Date.UTC(2018, 4, 14, 16, 40, 0), 11.2],
[Date.UTC(2018, 4, 14, 16, 50, 0), 10.9]
]
},
{
type: 'spline',
name: 'Value 3',
yAxis: 0,
tooltip: {
valueSuffix: '\xB5g/m\xB3'
},
data: [
[Date.UTC(2018, 4, 14, 16, 20, 0), 5.71],
[Date.UTC(2018, 4, 14, 16, 30, 0), 5.77],
[Date.UTC(2018, 4, 14, 16, 40, 0), 5.69],
[Date.UTC(2018, 4, 14, 16, 50, 0), 5.91]
]
},
{
type: 'spline',
name: 'Value 4',
yAxis: 0,
tooltip: {
valueSuffix: '\xB5g/m\xB3'
},
data: [
[Date.UTC(2018, 4, 14, 16, 20, 0), 3.07],
[Date.UTC(2018, 4, 14, 16, 30, 0), 3.04],
[Date.UTC(2018, 4, 14, 16, 40, 0), 3.03],
[Date.UTC(2018, 4, 14, 16, 50, 0), 3.03]
]
},
{
type: 'spline',
name: 'Wind Speed',
yAxis: 1,
tooltip: {
valueSuffix: 'mtr/sec'
},
data: [
[Date.UTC(2018, 4, 14, 16, 20, 0), 0.5],
[Date.UTC(2018, 4, 14, 16, 30, 0), 0.4],
[Date.UTC(2018, 4, 14, 16, 40, 0), 0.2],
[Date.UTC(2018, 4, 14, 16, 50, 0), 0.1]
]
},
{
type: 'spline',
name: 'Wind Direction',
yAxis: 2,
tooltip: {
valueSuffix: 'degrees'
},
data: [
[Date.UTC(2018, 4, 14, 16, 20, 0), 170.0],
[Date.UTC(2018, 4, 14, 16, 30, 0), 90.0],
[Date.UTC(2018, 4, 14, 16, 40, 0), 130.0],
[Date.UTC(2018, 4, 14, 16, 50, 0), 65.0]
]
}
]
}, function(chart) {
$("#pSliderBar").slider({
range: true,
orientation: "vertical",
min: chart.yAxis[pSliderUnit].min,
max: chart.yAxis[pSliderUnit].max,
values: [chart.yAxis[pSliderUnit].min, chart.yAxis[pSliderUnit].max],
slide: function(event, ui) {
chart.yAxis[pSliderUnit].setExtremes(ui.values[0], ui.values[1])
}
});
});
$('#selectSliderUnit').change(function() {
console.log("value:" + this.value);
pSliderUnit = this.value;
});
});
<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>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.0/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
<table width="100%">
<tr>
<td width="95%">
<div id="lineChart" style="min-width: 600px; height: 500px;"></div>
</td>
<td width="5%" valign="top" align="center">
<select id="selectSliderUnit" style="width: 20px;">
<option value="0">ug/m^3</option>
<option value="1">mtr/sec</option>
<option value="2">degrees</option>
</select><br><br>
<div id="pSliderBar" style="height: 400px;"></div>
</td>
</tr>
</table>
but there are some issues, it does not seem to be working correctly.
It needs to refresh the slider ranges on select change.
Sometimes it throws 'Uncaught TypeError: Cannot read property 'toggleClass' of undefined' exception, when I hide the lines.
Another problem is when zooming in slider goes back to top/bottom.
Can someone please help?
JSFiddle
Thanks in advance
There are some issues that result in this not being a smooth slider.
You are not refreshing the slider after you have changed unit, the slider is initialized when the chart is loaded in the callback, but never called again. So min, max, values and slide, all use the initial settings. API REF
You have set minRange: 1 for all 3 series, this does not work well for the second series which has a total range less than 1 and causes the slider to behave erratically.
You have not set startOnTick and endOnTick false, this causes the chart to jump from tick to tick.
To solve these issues, I made a function for the slider, that is called every time you select another option. I set minRange to 0.1 in the second series, and I set the step of the slider explicitly. I also disabled startOnTick and endOnTick.
var ymax = 0.0;
var pSliderUnit = 0;
$(function() {
var chart = Highcharts.chart('lineChart', {
chart: {
type: 'line',
zoomType: 'xy'
},
title: {
text: ''
},
credits: {
enabled: false
},
xAxis: {
type: 'datetime',
reversed: true
},
yAxis: [{
startOnTick: false,
endOnTick: false,
events: {
afterSetExtremes: function(e) {
$("#pSliderBar").slider("values", [e.min, e.max]);
}
},
minRange: 1,
showEmpty: false,
labels: {
format: '{value}'
},
title: {
text: '\xB5g/m\xB3'
},
plotLines: []
},
{
startOnTick: false,
endOnTick: false,
events: {
afterSetExtremes: function(e) {
$("#pSliderBar").slider("values", [e.min, e.max]);
}
},
minRange: 0.1,
min: 0,
max: 1,
showEmpty: false,
labels: {
format: '{value}'
},
title: {
text: 'mtr/sec'
},
opposite: true,
plotLines: []
},
{
startOnTick: false,
endOnTick: false,
events: {
afterSetExtremes: function(e) {
$("#pSliderBar").slider("values", [e.min, e.max]);
}
},
minRange: 1,
showEmpty: false,
labels: {
format: '{value}'
},
title: {
text: 'degrees'
},
plotLines: []
},
],
series: [{
type: 'spline',
name: 'Value 1',
yAxis: 0,
tooltip: {
valueSuffix: '\xB5g/m\xB3'
},
data: [
[Date.UTC(2018, 4, 14, 16, 20, 0), 20.4],
[Date.UTC(2018, 4, 14, 16, 30, 0), 17.6],
[Date.UTC(2018, 4, 14, 16, 40, 0), 18.8],
[Date.UTC(2018, 4, 14, 16, 50, 0), 18.9]
]
},
{
type: 'spline',
name: 'Value 2',
yAxis: 0,
tooltip: {
valueSuffix: '\xB5g/m\xB3'
},
data: [
[Date.UTC(2018, 4, 14, 16, 20, 0), 11.2],
[Date.UTC(2018, 4, 14, 16, 30, 0), 10.5],
[Date.UTC(2018, 4, 14, 16, 40, 0), 11.2],
[Date.UTC(2018, 4, 14, 16, 50, 0), 10.9]
]
},
{
type: 'spline',
name: 'Value 3',
yAxis: 0,
tooltip: {
valueSuffix: '\xB5g/m\xB3'
},
data: [
[Date.UTC(2018, 4, 14, 16, 20, 0), 5.71],
[Date.UTC(2018, 4, 14, 16, 30, 0), 5.77],
[Date.UTC(2018, 4, 14, 16, 40, 0), 5.69],
[Date.UTC(2018, 4, 14, 16, 50, 0), 5.91]
]
},
{
type: 'spline',
name: 'Value 4',
yAxis: 0,
tooltip: {
valueSuffix: '\xB5g/m\xB3'
},
data: [
[Date.UTC(2018, 4, 14, 16, 20, 0), 3.07],
[Date.UTC(2018, 4, 14, 16, 30, 0), 3.04],
[Date.UTC(2018, 4, 14, 16, 40, 0), 3.03],
[Date.UTC(2018, 4, 14, 16, 50, 0), 3.03]
]
},
{
type: 'spline',
name: 'Wind Speed',
yAxis: 1,
tooltip: {
valueSuffix: 'mtr/sec'
},
data: [
[Date.UTC(2018, 4, 14, 16, 20, 0), 0.5],
[Date.UTC(2018, 4, 14, 16, 30, 0), 0.4],
[Date.UTC(2018, 4, 14, 16, 40, 0), 0.2],
[Date.UTC(2018, 4, 14, 16, 50, 0), 0.1]
]
},
{
type: 'spline',
name: 'Wind Direction',
yAxis: 2,
tooltip: {
valueSuffix: 'degrees'
},
data: [
[Date.UTC(2018, 4, 14, 16, 20, 0), 170.0],
[Date.UTC(2018, 4, 14, 16, 30, 0), 90.0],
[Date.UTC(2018, 4, 14, 16, 40, 0), 130.0],
[Date.UTC(2018, 4, 14, 16, 50, 0), 65.0]
]
}
]
}, Slider)
function Slider(chart, pSliderUnit) {
if (typeof pSliderUnit == 'undefined') {
pSliderUnit = 0
}
$("#pSliderBar").slider({
range: true,
orientation: "vertical",
min: Math.round(chart.yAxis[pSliderUnit].getExtremes().min * 100) / 100,
max: Math.round(chart.yAxis[pSliderUnit].getExtremes().max * 100) / 100,
step: (chart.yAxis[pSliderUnit].getExtremes().max - chart.yAxis[pSliderUnit].getExtremes().min) / 100,
values: [Math.round(chart.yAxis[pSliderUnit].getExtremes().min * 100) / 100, Math.round(chart.yAxis[pSliderUnit].getExtremes().max * 100) / 100],
slide: function(event, ui) {
chart.yAxis[pSliderUnit].setExtremes(ui.values[0], ui.values[1], true, false)
}
});
};
$('#selectSliderUnit').change(function() {
console.log("value:" + this.value);
Slider(chart, this.value);
});
});
<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>
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.0/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
<table width="100%">
<tr>
<td width="95%">
<div id="lineChart" style="min-width: 600px; height: 500px;"></div>
</td>
<td width="5%" valign="top" align="center">
<select id="selectSliderUnit" style="width: 20px;">
<option value="0">ug/m^3</option><option value="1">mtr/sec</option><option value="2">degrees</option>
</select><br><br>
<div id="pSliderBar" style="height: 400px;"></div>
</td>
</tr>
</table>
There is one more issue that I can't figure out of, when you set max slider for the first time without changing which option you are adjusting, it jumps.
Working example: https://jsfiddle.net/ewolden/9aqnq71n/4/

Highcharts how to show certain tooltips and don't show others

I need to show tooltips for only the last two series when hovering the mouse over the graph. In this example the idea will be to show only the tool tips for the values 1699 and 1750. The rest of the values can't show any tooltips when hovering the mouse. How can I achive that? I haven't found any way to do so. Is it possible? Thanks in advance.
(function () {
var categories= ['1350', '1400', '1450', '1500', '1550', '1699', '1750'];
Highcharts.chart('grafica1', {
chart: {
type: 'area',
},
title: {
text: ' '
},
xAxis: {
labels: {
enabled: true,
formatter: function () {
return categories[this.value];
}
},
tickmarkPlacement: 'on',
title: {
enabled: false
}
},
yAxis: {
title: {
text: 'Percent'
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.percentage:.1f}%</b> ({point.y:,.0f} millions)<br/>',
split: true
},
plotOptions: {
area: {
stacking: 'percent',
lineColor: '#ffffff',
lineWidth: 1,
marker: {
lineWidth: 1,
lineColor: '#ffffff',
}
}
},
series: [{
name: 'Africa',
data: [502, 635, 809, 947, 1402, 3634, 5268]
}, {
name: 'L. America',
data: [106, 107, 111, 133, 221, 767, 1766]
}, {
name: 'Oceania',
data: [163, 203, 276, 408, 547, 729, 628]
}, {
name: 'S-E. Asia',
data: [18, 31, 54, 156, 339, 818, 1201]
}, {
name: 'Japan',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'China',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'Near East',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'Asian CIS',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'Russia',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'East Europe',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'Central Europe',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'W. Europe - Nordic',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'Nordic',
data: [2, 2, 2, 6, 13, 30, 46]
}, {
name: 'N. America',
data: [2, 2, 2, 6, 13, 30, 46]
}]
});
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="grafica1" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
You can use the formatter like this :
tooltip: {
formatter: function() {
if(this.points[0].key < (this.points[0].series.xData.length -2)){
return false;
}
var s = [];
s.push(this.x);
this.points.forEach(function(point) {
s.push('<b>' + point.series.name + '</b>: ' + point.y);
});
return s;
},
split: true
},
Fiddle
Not the cleanest code (there still an error in the console) but it's work.
Edit
Following Deep 3015 comment, code and fiddle updated
You can wrap tooltip.prototype.renderSplit method to show the tooltip only if the points have certain x values.
Highcharts.wrap(Highcharts.Tooltip.prototype, 'renderSplit', function (p, labels, points) {
if (!this.options.showOnLastTwo) {
return p.call(this, labels, points)
}
const point = points[0]
if (point) {
const allowedXs = point.series.xData.slice(-2)
if (allowedXs.includes(point.x)) {
return p.call(this, labels, points)
}
}
this.destroy()
})
And set in tooltip options showOnLastTwo flag to true:
tooltip: {
split: true,
showOnLastTwo: true
},
The flag is not necessary but the wrap changes Highcharts globally so it will affect every chart - the flag will prevent this.
live example: http://jsfiddle.net/sLvekuht/1/

Issues with series.data in highcharts

I'm using a column chart with a slider that redraws the chart after slide operation is invoked. I'm storing each data array in a javascript object and the chart renders according to the slider option. After assigning the initial values for the first slider option, the chart renders correctly but when I slide back to the first position, the chart won't render. And the weird part is when I assign the initial values to a separate variable and the data option is assigned with this variable, the chart renders correctly at every position.
Here's the code:
var data = {
"jan": [0, 10, 25, 30, 25, 10, 0,30, 25, 10, 0],
"feb": [0, 5, 25, 35, 30, 10, 0, 10, 25, 30, 25],
"mar": [0, 30, 18, 4, 18, 30, 0, 20, 30, 25, 15],
"apr": [0, 20, 30, 25, 15, 10, 0, 10, 15, 25, 30],
"may": [0, 10, 15, 25, 30, 20, 0, 35, 123, 978, 43],
"jun": [54, 5, 546, 77, 34, 3, 2, 567, 567, 7, 57],
"jul": [56, 324, 768, 578, 124, 154, 90, 150, 125, 258, 312],
"aug": [67, 76, 4, 76, 23, 2, 24, 10, 15, 546, 30],
"sep": [6, 5, 35, 123, 978, 4, 32, 10, 15, 546, 30],
"oct": [97, 56, 7, 567, 567, 7, 57, 10, 15, 25, 30],
"nov": [56, 4, 65, 25, 6, 565, 56, 10, 15, 546, 30],
"dec": [0, 10, 15, 546, 30, 33, 0, 10, 15, 546, 30]
};
var someData = [0, 10, 25, 30, 25, 10, 0,30, 25, 10, 0];
var chart = new Highcharts.chart({
chart: {
renderTo: 'container',
type: 'column',
marginTop: 50,
marginLeft: 100,
marginBottom: 50
},
title: false,
exporting: {enabled: false},
xAxis: {
crosshair: true,
tickColor: '#7F7F7F',
lineColor: '#7F7F7F',
tickWidth: 0,
labels: {
step: 5
},
title: {
text: 'x-axis',
align: "left",
x: -10,
rotation: 0,
style: {
"font-size" : "15px"
}
}
},
yAxis: {
min: 0,
title: {
text: 'y-axis',
align: 'high',
rotation: 0,
y: -10,
offset: 0,
style: {
"font-size" : "15px"
}
},
gridLineColor: 'transparent',
lineColor: '#7F7F7F',
lineWidth: 1,
tickWidth: 1,
tickColor: '#7F7F7F',
gridLineWidth: 0,
minorGridLineWidth: 0,
labels: {
step: 2,
formatter: function(){
if(this.value > 999)
return Math.round(this.value/1000) + 'k';
return this.value;
}
}
},
tooltip: {
enabled: false
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
},
series: {
colorByPoint: true
}
},
series: [{
showInLegend: false,
data: someData
}],
credits: false
});
$('#slider_bar').on("slide", function () {
chart.series[0].setData(data[document.getElementById('value').innerHTML]);
});
The initial position of the slider is at jan and the chart renders correctly when I slide back to jan. I'd like to know why the chart won't render when I assign series.data as:
data: data.jan
Any suggestions?
Highchart series.data expects a key value pair, or an array of arrays like
[[x1,y1],[x2,y2]]
or
{
y: [x1,x2]
}
now when you do data = data.jan Highchart is not able to find the Y value because data.jan is a simple array
Found the solution:
instead of writing
data: data.jan
write
data: data.jan.slice()
The slice function does not directly returns the reference of the array, instead it returns a copy of the array. I still wonder why we need to use the slice function in the first place, for this particular situation but it works.

Categories