Highcharts - Synchronized heat maps - javascript

Let's say we have two high charts - heat maps (can be more in future). Check it like below jsfiddle.
http://jsfiddle.net/xzq5bzy5/1/
<div id="container" style="height: 400px; min-width: 310px; max-width: 800px; margin: 0 auto"></div>
<div id="container2" style="height: 400px; min-width: 310px; max-width: 800px; margin: 0 auto"></div>
What I want if I hover on first cell of first high charts. It should simultaneously hover the second high chart first cell and both should show data in their respective tool-tips.
I have tried to search but I didn't find anything. Let me know if I need to add anymore information.

Here is a basic example using synchronised-charts highchars demo:
/*
The purpose of this demo is to demonstrate how multiple charts on the same page can be linked
through DOM and Highcharts events and API methods. It takes a standard Highcharts config with a
small variation for each data set, and a mouse/touch event handler to bind the charts together.
*/
/**
* In order to synchronize tooltips and crosshairs, override the
* built-in events with handlers defined on the parent element.
*/
$('#container').bind('mousemove touchmove touchstart', function(e) {
var chart,
point,
i,
event;
for (i = 0; i < Highcharts.charts.length; i = i + 1) {
chart = Highcharts.charts[i];
event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
point = chart.series[0].searchPoint(event, true); // Get the hovered point
if (point) {
point.highlight(e);
}
}
});
/**
* Override the reset function, we don't need to hide the tooltips and crosshairs.
*/
Highcharts.Pointer.prototype.reset = function() {
return undefined;
};
/**
* Highlight a point by showing tooltip, setting hover state and draw crosshair
*/
Highcharts.Point.prototype.highlight = function(event) {
this.onMouseOver(); // Show the hover marker
this.series.chart.tooltip.refresh(this); // Show the tooltip
this.series.chart.xAxis[0].drawCrosshair(event, this); // Show the crosshair
};
for (var i = 0; i < 2; ++i) {
$('<div class="chart">')
.appendTo('#container')
.highcharts({
chart: {
type: 'heatmap',
marginTop: 40,
marginBottom: 80,
plotBorderWidth: 1
},
title: {
text: 'Sales for Feb'
},
xAxis: {
categories: ['Alexander', 'Marie', 'Maximilian', 'Sophia', 'Lukas', 'Maria', 'Leon', 'Anna', 'Tim', 'Laura']
},
yAxis: {
categories: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
title: null
},
colorAxis: {
min: 0,
minColor: '#FFFFFF',
maxColor: Highcharts.getOptions().colors[0]
},
legend: {
align: 'right',
layout: 'vertical',
margin: 0,
verticalAlign: 'top',
y: 25,
symbolHeight: 280
},
tooltip: {
formatter: function() {
return '<b>' + this.series.xAxis.categories[this.point.x] + '</b> sold <br><b>' +
this.point.value + '</b> items on <br><b>' + this.series.yAxis.categories[this.point.y] + '</b>';
}
},
series: [{
name: 'Sales per employee',
borderWidth: 1,
data: [
[0, 0, 10],
[0, 1, 19],
[0, 2, 8],
[0, 3, 24],
[0, 4, 67],
[1, 0, 92],
[1, 1, 58],
[1, 2, 78],
[1, 3, 117],
[1, 4, 48],
[2, 0, 35],
[2, 1, 15],
[2, 2, 123],
[2, 3, 64],
[2, 4, 52],
[3, 0, 72],
[3, 1, 132],
[3, 2, 114],
[3, 3, 19],
[3, 4, 16],
[4, 0, 38],
[4, 1, 5],
[4, 2, 8],
[4, 3, 117],
[4, 4, 115],
[5, 0, 88],
[5, 1, 32],
[5, 2, 12],
[5, 3, 6],
[5, 4, 120],
[6, 0, 13],
[6, 1, 44],
[6, 2, 88],
[6, 3, 98],
[6, 4, 96],
[7, 0, 31],
[7, 1, 1],
[7, 2, 82],
[7, 3, 32],
[7, 4, 30],
[8, 0, 85],
[8, 1, 97],
[8, 2, 123],
[8, 3, 64],
[8, 4, 84],
[9, 0, 47],
[9, 1, 114],
[9, 2, 31],
[9, 3, 48],
[9, 4, 91]
],
dataLabels: {
enabled: true,
color: '#000000'
}
}]
})
}
Live example:
http://jsfiddle.net/atkf70cv/

Related

Highcharts Heatmap - How to get blocks next to each other when separated by more then '1' in value

Attached is an image of the problem I'm currently having.
Attached is an example of the issue manually created with JSFiddle
https://jsfiddle.net/ekjrLsz2/
My goal is to have each of the blocks be next to each other without all the space in-between like the default demos for the heatmap show.
I can get it to work correctly if the data is going 1 by 1, for example; 1,2,3,4,5,6
But if the data is going 5,10,15,20, etc... then you get what you see in my attached image.
So to be more clear the X direction is going 1 by 1 in my demo image and shows without spacing, the Y direction however has the large spacing since the data does not have numbers 21,22,23,24 or the space inbetween every 5 so to speak.
Below is the code I use to generate the chart.
Highcharts.setOptions({
lang: {
decimalPoint: '.',
thousandsSep: ','
}
});
Highcharts.chart('heatmap-container', {
chart: {
type: 'heatmap',
marginTop: 40,
marginBottom: 80,
plotBorderWidth: 1
},
title: {
text: 'Report Data'
},
xAxis: {
//categories: ['1%', '2%', '3%', '4%', '5%', '6%', '7%', '8%', '9%', '10%'],
title: {text:$('#x-values').val()},
//showEmpty:true,
},
yAxis: {
categories: ['5', '10', '15', '20', '25'],
title: {text:$('#y-values').val()},
reversed: false,
//visible: true,
//showEmpty:true,
},
colorAxis: {
max: goodColorVal,
min: badColorVal,
reversed: false,
tickInterval: 1,
//min: -150,
//minColor: '#FFFFFF',
//maxColor: '#00FF00',//Highcharts.getOptions().colors[4]
stops: [
[0.0,'#FF0000'],
[0.5,'#FFFFFF'],
[1.0,"#00FF00"]]
},
legend: {
align: 'right',
layout: 'vertical',
margin: 0,
verticalAlign: 'top',
y: 25,
symbolHeight: 280,
reversed:true
},
tooltip: {
headerFormat: '',
pointFormat: `<b style="text-transform:capitalize;">${$("#x-values option:selected").text()}</b>:{point.x:,.2f} - <b style="text-transform:capitalize;">${$("#y-values option:selected").text()}</b>:{point.y:,.2f} - <b style="text-transform:capitalize;">${$("#z-values option:selected").text()}</b>:{point.value:,.2f}`
// formatter: function () {
// return '<b>' + getPointCategoryName(this.point, 'x') + '</b> sold <br><b>' +
// this.point.value + '</b> items on <br><b>' + getPointCategoryName(this.point, 'y') + '</b>';
// }
},
series: [{
name: 'Report Data For Input 1',
borderWidth: 1,
//data: [[0, 0, 10], [0, 1, 19], [0, 2, 9], [0, 3, 24], [0, 4, 67], [1, 0, 92], [1, 1, 58], [1, 2, 78], [1, 3, 117], [1, 4, 48], [2, 0, 35], [2, 1, 15], [2, 2, 123], [2, 3, 64], [2, 4, 52], [3, 0, 72], [3, 1, 132], [3, 2, 114], [3, 3, 19], [3, 4, 16], [4, 0, 38], [4, 1, 5], [4, 2, 8], [4, 3, 117], [4, 4, 115], [5, 0, 88], [5, 1, 32], [5, 2, 12], [5, 3, 6], [5, 4, 120], [6, 0, 13], [6, 1, 44], [6, 2, 88], [6, 3, 98], [6, 4, 96], [7, 0, 31], [7, 1, 1], [7, 2, 82], [7, 3, 32], [7, 4, 30], [8, 0, 85], [8, 1, 97], [8, 2, 123], [8, 3, 64], [8, 4, 84], [9, 0, 47], [9, 1, 114], [9, 2, 31], [9, 3, 48], [9, 4, 91]],
data: arraydata, //[[0,0,-87],[1,0,22],[2,0,33],[3,0,55]],
dataLabels: {
enabled: false,
color: '#000000'
}
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
yAxis: {
labels: {
formatter: function () {
return this.value.charAt(0);
}
}
}
}
}]
}
});
I have tried pointInterval and tickInterval with no luck so far.
The simplest way to have your points next to each other (without any spaces) is to give them x attributes without skipping any number, e.g 1,2,3,4...
Why don't you try to do it this way?
Demo:
https://jsfiddle.net/BlackLabel/39vx468s/
To skip the empty spaces between points you can use breaks functionality.
API references:
https://api.highcharts.com/highcharts/xAxis.breaks
Demo:
https://jsfiddle.net/BlackLabel/et4kryvz/
xAxis: {
breaks: [{
from: 0.5,
to: 1.5,
breakSize: 0
}]
}
There is also another solution, which uses colsize and rowsize properties. Thanks to that you can avoid using the breaks altogether this way and it even works with floating-point data.
Demo: https://jsfiddle.net/87tL3ogh/1/

Problem when trying to implement a variable in a heatmap using highcharts

I am currently trying to plot the values of a thermographic (AMG8833) inside a heatmap using highcharts module. As the values update in real time, these values are being sent through a nodemcu board and received in the html file. It is very strange as when I try to plot the value by itself using: (this part of the code repeats for each pixel of the camera)
setInterval(function () {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var pixel_0 = parseFloat(this.responseText);
document.getElementById("pixel_0").innerHTML = pixel_0;
pixel_0.innerHTML = pixel_0;
}
};
xhttp.open("GET", "/pixels[0]", true);
xhttp.send();
}, 1000 );
and
<h3>"The value for pixel 0 is: " <span id="pixel_0"></span></h3>
It shows the value perfectly. The problem comes when I try to put this value inside the data for my heatmap:
$(function () {
$('#Thermographic_camera').highcharts({
chart: {
type: 'heatmap',
marginTop: 40,
marginBottom: 80,
plotBorderWidth: 8,
plotBorderColor: '#FFFFFF'
},
title: {
text: 'Thermographic camera'
},
xAxis: {
categories: ['', '', '', '', '', '', '', ''],
},
yAxis: {
categories: ['', '', '', '', '', '', '', ''],
title: null
},
colorAxis: {
//min: 0,
//minColor: '#FFFFFF',
//maxColor: Highcharts.getOptions().colors[8]
stops: [
[0, '#3060cf'],
[0.5, '#fffbbc'],
[0.9, '#c4463a']
],
min: 20,
max: 40
},
legend: {
align: 'right',
layout: 'vertical',
margin: 0,
verticalAlign: 'top',
y: 25,
symbolHeight: 280
},
series: [{
name: 'Value',
borderColor: 'white',
borderWidth: 1,
data: [[0, 0, pixel_0],
[0, 1, pixel_1],
[0, 2, pixel_2],
[0, 3, pixel_3],
[0, 4, pixel_4],
[0, 5, pixel_5],
[0, 6, pixel_6],
[0, 7, pixel_7],
[1, 0, pixel_8],
[1, 1, pixel_9],
[1, 2, pixel_10],
[1, 3, pixel_11],
[1, 4, pixel_12],
[1, 5, pixel_13],
[1, 6, pixel_14],
[1, 7, pixel_15],
[2, 0, pixel_16],
[2, 1, pixel_17],
[2, 2, pixel_18],
[2, 3, pixel_19],
[2, 4, pixel_20],
[2, 5, pixel_21],
[2, 6, pixel_22],
[2, 7, pixel_23],
[3, 0, pixel_24],
[3, 1, pixel_25],
[3, 2, pixel_26],
[3, 3, pixel_27],
[3, 4, pixel_28],
[3, 5, pixel_29],
[3, 6, pixel_30],
[3, 7, pixel_31],
[4, 0, pixel_32],
[4, 1, pixel_33],
[4, 2, pixel_34],
[4, 3, pixel_35],
[4, 4, pixel_36],
[4, 5, pixel_37],
[4, 6, pixel_38],
[4, 7, pixel_39],
[5, 0, pixel_40],
[5, 1, pixel_41],
[5, 2, pixel_42],
[5, 3, pixel_43],
[5, 4, pixel_44],
[5, 5, pixel_45],
[5, 6, pixel_46],
[5, 7, pixel_47],
[6, 0, pixel_48],
[6, 1, pixel_49],
[6, 2, pixel_50],
[6, 3, pixel_51],
[6, 4, pixel_52],
[6, 5, pixel_53],
[6, 6, pixel_54],
[6, 7, pixel_55],
[7, 0, pixel_56],
[7, 1, pixel_57],
[7, 2, pixel_58],
[7, 3, pixel_59],
[7, 4, pixel_60],
[7, 5, pixel_61],
[7, 6, pixel_62],
[7, 7, pixel_63],
],
dataLabels: {
enabled: false,
color: '#000000'
}
}]
});
});
When I do so, I obtain the answer in the heatmap that the variable i am trying to put inside the heatmap is an [object HTMLSpanElement] and it does not put the actual value of the variables of each pixel.
Any clue on what could I be doing wrong?
Thank you very much for the help

Highcharts and boost with multiple charts

So I have two charts on the same page and I am using boost for both of these graphs. I wish to allow zooming and if I do a zoom then the line chart disappears. The data appears to still be there as the mouse over shows the data.
See this fiddle:
https://jsfiddle.net/CaptainBli/wa7o2bL8/3/
function getData(n) {
var arr = [],
i,
x,
a,
b,
c,
spike;
for (
i = 0, x = Date.UTC(new Date().getUTCFullYear(), 0, 1) - n * 36e5;
i < n;
i = i + 1, x = x + 36e5
) {
if (i % 100 === 0) {
a = 2 * Math.random();
}
if (i % 1000 === 0) {
b = 2 * Math.random();
}
if (i % 10000 === 0) {
c = 2 * Math.random();
}
if (i % 50000 === 0) {
spike = 10;
} else {
spike = 0;
}
arr.push([
x,
2 * Math.sin(i / 100) + a + b + c + spike + Math.random()
]);
}
return arr;
}
var n = 500000,
data = getData(n);
console.time('line');
Highcharts.chart('container', {
chart: {
zoomType: 'x'
},
title: {
text: 'Highcharts drawing ' + n + ' points'
},
subtitle: {
text: 'Using the Boost module'
},
tooltip: {
valueDecimals: 2
},
xAxis: {
type: 'datetime'
},
series: [{
data: data,
lineWidth: 0.5,
name: 'Hourly data points'
}]
});
console.timeEnd('line');
Highcharts.chart('heatcont', {
chart: {
type: 'heatmap',
marginTop: 40,
marginBottom: 80,
plotBorderWidth: 1
},
title: {
text: 'Sales per employee per weekday'
},
xAxis: {
categories: ['Alexander', 'Marie', 'Maximilian', 'Sophia', 'Lukas', 'Maria', 'Leon', 'Anna', 'Tim', 'Laura']
},
yAxis: {
categories: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
title: null
},
colorAxis: {
min: 0,
minColor: '#FFFFFF',
maxColor: Highcharts.getOptions().colors[0]
},
legend: {
align: 'right',
layout: 'vertical',
margin: 0,
verticalAlign: 'top',
y: 25,
symbolHeight: 280
},
tooltip: {
formatter: function () {
return '<b>' + this.series.xAxis.categories[this.point.x] + '</b> sold <br><b>' +
this.point.value + '</b> items on <br><b>' + this.series.yAxis.categories[this.point.y] + '</b>';
}
},
series: [{
name: 'Sales per employee',
boostThreshold: 1,
borderWidth: 1,
data: [[0, 0, 10], [0, 1, 19], [0, 2, 8], [0, 3, 24], [0, 4, 67], [1, 0, 92], [1, 1, 58], [1, 2, 78], [1, 3, 117], [1, 4, 48], [2, 0, 35], [2, 1, 15], [2, 2, 123], [2, 3, 64], [2, 4, 52], [3, 0, 72], [3, 1, 132], [3, 2, 114], [3, 3, 19], [3, 4, 16], [4, 0, 38], [4, 1, 5], [4, 2, 8], [4, 3, 117], [4, 4, 115], [5, 0, 88], [5, 1, 32], [5, 2, 12], [5, 3, 6], [5, 4, 120], [6, 0, 13], [6, 1, 44], [6, 2, 88], [6, 3, 98], [6, 4, 96], [7, 0, 31], [7, 1, 1], [7, 2, 82], [7, 3, 32], [7, 4, 30], [8, 0, 85], [8, 1, 97], [8, 2, 123], [8, 3, 64], [8, 4, 84], [9, 0, 47], [9, 1, 114], [9, 2, 31], [9, 3, 48], [9, 4, 91]],
dataLabels: {
enabled: true,
color: '#000000'
}
}]
});

Highchart legend has clipped text

I've a heat map using Highcharts where I'm facing some issues with text clippings.
When I add a label on the colorAxis the text gets clipped:
colorAxis: {
min: 0,
minColor: '#FFFFFF',
maxColor: Highcharts.getOptions().colors[0],
labels: {
format: '{value} test test test'
},
}
I've only added the colorAxis.labels.format property.
See my example here:
http://jsfiddle.net/dennismadsen/7sp8ddpq/1/
It's based/forked on this official Highchart sample:
http://jsfiddle.net/highcharts/4aqhB/
HighCharts does have its quirks in the legend layout. You have to explicitly set the width, i.e.
legend: {
...
width: 140,
...
},
Found a way to make it dynamic, based on a post by TorsteinHonsi on GitHub. The code basically measures the width of the label and redraws the chart. See if it suits your needs.
$(function () {
var leg = 'Whatever';
var aChart = new Highcharts.Chart({
chart: {
type: 'heatmap',
marginTop: 40,
marginBottom: 40,
renderTo: 'container'
},
title: {
text: 'Sales per employee per weekday'
},
xAxis: {
categories: ['Alexander', 'Marie', 'Maximilian', 'Sophia', 'Lukas', 'Maria', 'Leon', 'Anna', 'Tim', 'Laura']
},
yAxis: {
categories: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
title: null
},
colorAxis: {
min: 0,
minColor: '#FFFFFF',
maxColor: Highcharts.getOptions().colors[0],
labels: {
format: '{value} ' + leg,
style: {
textOverflow: "clip",
overflow: "visible",
whiteSpace: "nowrap"
}
},
},
legend: {
align: 'right',
layout: 'vertical',
margin: 0,
verticalAlign: 'top',
y: 25,
symbolHeight: 320
},
tooltip: {
formatter: function () {
return '<b>' + this.series.xAxis.categories[this.point.x] + '</b> sold <br><b>' +
this.point.value + '</b> items on <br><b>' + this.series.yAxis.categories[this.point.y] + '</b>';
}
},
series: [{
name: 'Sales per employee',
borderWidth: 1,
data: [[0, 0, 10], [0, 1, 19], [0, 2, 8], [0, 3, 24], [0, 4, 67], [1, 0, 92], [1, 1, 58], [1, 2, 78], [1, 3, 117], [1, 4, 48], [2, 0, 35], [2, 1, 15], [2, 2, 123], [2, 3, 64], [2, 4, 52], [3, 0, 72], [3, 1, 132], [3, 2, 114], [3, 3, 19], [3, 4, 16], [4, 0, 38], [4, 1, 5], [4, 2, 8], [4, 3, 117], [4, 4, 115], [5, 0, 88], [5, 1, 32], [5, 2, 12], [5, 3, 6], [5, 4, 120], [6, 0, 13], [6, 1, 44], [6, 2, 88], [6, 3, 98], [6, 4, 96], [7, 0, 31], [7, 1, 1], [7, 2, 82], [7, 3, 32], [7, 4, 30], [8, 0, 85], [8, 1, 97], [8, 2, 123], [8, 3, 64], [8, 4, 84], [9, 0, 47], [9, 1, 114], [9, 2, 31], [9, 3, 48], [9, 4, 91]],
dataLabels: {
enabled: true,
color: 'black',
style: {
textShadow: 'none'
}
}
}]
});
Highcharts.Legend.prototype.update = function (options) {
this.options = Highcharts.merge(this.options, options);
this.chart.isDirtyLegend = true;
this.chart.isDirtyBox = true;
this.chart.redraw();
};
aChart.legend.update({
width: 50 + $('.highcharts-axis-labels tspan').outerWidth()
});
});

Highcharts show all categories even when no data

I am working with high charts, I have a set of controls on a web page that allows the user to select months and locations. The issue is if they select a location that has no data. So lets say they select January and Hawaii but there is no data for Hawaii in January. Nothing will be displayed at all, but I would like the axis to appear along with the labels.
NOTE: I am trying to create a heatmap so I don't want to see the minimun color when there is no data.
A value of null seems to work. You can change your tooltip to not display if the value is null too: http://jsfiddle.net/SheldonNeilson/95um4x0q/1/
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/heatmap.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="height: 400px; min-width: 310px; max-width: 800px; margin: 0 auto"></div>
$(function () {
$('#container').highcharts({
chart: {
type: 'heatmap',
marginTop: 40,
marginBottom: 80
},
title: {
text: 'Sales per employee per weekday'
},
xAxis: {
categories: ['Alexander', 'Marie', 'Maximilian', 'Sophia', 'Lukas', 'Maria', 'Leon', 'Anna', 'Tim', 'Laura']
},
yAxis: {
categories: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],
title: null
},
colorAxis: {
min: 0,
minColor: Highcharts.getOptions().colors[0],
maxColor: '#FFFFFF'
},
legend: {
align: 'right',
layout: 'vertical',
margin: 0,
verticalAlign: 'top',
y: 25,
symbolHeight: 280
},
tooltip: {
formatter: function () {
if(this.point.value == null){
return 'No data' ;
}else{
return '<b>' + this.series.xAxis.categories[this.point.x] + '</b> sold <br><b>' +
this.point.value + '</b> items on <br><b>' + this.series.yAxis.categories[this.point.y] + '</b>';
}
}
},
series: [{
name: 'Sales per employee',
borderWidth: 1,
data: [[0, 0, null], [0, 1, 19], [0, 2, 8], [0, 3, 24], [0, 4, 67], [1, 0, 92], [1, 1, 58], [1, 2, 78], [1, 3, 117], [1, 4, 48], [2, 0, 35], [2, 1, 15], [2, 2, 123], [2, 3, 64], [2, 4, 52], [3, 0, 72], [3, 1, 132], [3, 2, 114], [3, 3, 19], [3, 4, 16], [4, 0, 38], [4, 1, 5], [4, 2, 8], [4, 3, 117], [4, 4, 115], [5, 0, 88], [5, 1, 32], [5, 2, 12], [5, 3, 6], [5, 4, 120], [6, 0, 13], [6, 1, 44], [6, 2, 88], [6, 3, 98], [6, 4, 96], [7, 0, 31], [7, 1, 1], [7, 2, 82], [7, 3, 32], [7, 4, 30], [8, 0, 85], [8, 1, 97], [8, 2, 123], [8, 3, 64], [8, 4, 84], [9, 0, 47], [9, 1, 114], [9, 2, 31], [9, 3, 48], [9, 4, 91]],
dataLabels: {
enabled: true,
color: '#000000'
}
}]
});
});

Categories

Resources