Highcharts VU Meter Gauge numeric display disapears - highcharts

An interesting little "quirk" using the sample of the VU gauge. When I try to reposition the gauge pane, the numeric display will just disappear. If I keep the position <= 100%, the display will show, anything > 100% and the numeric display is gone.
I have repeatedly tried to force the display back into a position where it can be seen, but no luck. Any ideas? Here is the latest test fiddle:
VU Meter Fiddle
Adjusting the elements is easy, use the pane: section to move the entire gauge with the display pane, use the datalabel: section to move the numeric display.
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'gauge',
plotBorderWidth: 1,
plotBackgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, '#FFF4C6'],
[0.3, '#FFFFFF'],
[1, '#FFF4C6']
]
},
plotBackgroundImage: null,
height: 200
},
title: {
text: 'Efficiencies'
},
/***
in order to move the gauge up or down in the pane, adjust the 'Y' element in
the center array. Adjusting this above 100% (to move the gauge DOWN)
will cause the numeric display to disappear
***/
pane: [{
startAngle: -45,
endAngle: 45,
background: null,
center: ['25%', '100%'],
size: 200
}, {
startAngle: -45,
endAngle: 45,
background: null,
center: ['75%', '105%'],
size: 200
}],
yAxis: [{
min: 0,
max: 110,
minorTickPosition: 'outside',
tickPosition: 'outside',
labels: {
rotation: 'auto',
distance: 20
},
plotBands: [{
from: 0,
to: 70,
color: '#DF5353', // red
innerRadius: '100%',
outerRadius: '105%'
}, {
from: 70,
to: 95,
color: '#DDDF0D', // yellow
innerRadius: '100%',
outerRadius: '105%'
}, {
from: 95,
to: 110,
color: '#55BF3B', // green
innerRadius: '100%',
outerRadius: '105%'
}],
pane: 0,
title: {
text: '<span style="font-size:10px">OEE %</span><br/><span style="font-size:8px">Machine 001</span>',
y: -30
}
}, {
min: 0,
max: 110,
minorTickPosition: 'outside',
tickPosition: 'outside',
labels: {
rotation: 'auto',
distance: 20
},
plotBands: [{
from: 0,
to: 70,
color: '#DF5353', // red
innerRadius: '100%',
outerRadius: '105%'
}, {
from: 70,
to: 95,
color: '#DDDF0D', // yellow
innerRadius: '100%',
outerRadius: '105%'
}, {
from: 95,
to: 110,
color: '#55BF3B', // green
innerRadius: '100%',
outerRadius: '105%'
}],
pane: 1,
title: {
text: '<span style="font-size:10px">Cycle Eff %</span><br/><span style="font-size:8px">Machine 001</span>',
y: -30
}
}],
plotOptions: {
gauge: {
/***
Adjusting the position of the numeric display is also easy
Change the y: component more negative move the display UP,
decreasing the value move the display DOWN
***/
dataLabels: {
enabled: true,
x: 0,
y: -120
},
dial: {
radius: '110%'
}
}
},
series: [{
data: [80],
yAxis: 0
}, {
data: [80],
yAxis: 1
}]
},
// Let the music play
function(chart) {
setInterval(function() {
var left = chart.series[0].points[0],
right = chart.series[1].points[0],
leftVal,
//inc = (Math.random() - 0.5) * 30;
inc1 = Math.random() * (30) + 70;
inc2 = Math.random() * (30) + 70;
leftVal = left.y + inc1;
rightVal = right.y + inc2; // / 3;
if (leftVal < 0 || leftVal > 110) {
//leftVal = left.y - inc;
leftVal = 110 - inc1;
}
if (rightVal < 0 || rightVal > 110) {
rightVal = 110 - inc2;
}
left.update(parseInt(leftVal),false);
right.update(parseInt(rightVal), false);//, false);
chart.redraw();
}, 1500);
});
});

If you use the dataLabels.crop = false option it will show up. But based on the API description it will also show up if the data label is outside the plot area as well, which you may not want. The behavior by highcharts is weird though because it looks at whether the series is outside the plot area and not where the datalabel is when hiding the labels, so I agree that it is a bug.
http://api.highcharts.com/highcharts#plotOptions.series.dataLabels.crop

Related

Highcharts afterAnimate in combination with xAxis max

We are developing some charts using Highcharts.
And we are using the series.events.afterAnimate in combination with an xAxis.max value.
But when we have for example points from Januari until September, but with an xAxis.max value until December the afterAnimate function is called when it reached December we guess..
But we would like have a callback when all the valid points are drawn, and not we it reaches its max value...
is this possible?
That happens because the clipPath width is by default equal width of the plot area. To change it you can overwrite Highcharts.Series.animate method and set clipPath width equal width of the particular series.
EDIT:
Also, note that when the width of the clipPath is shorter and the duration of the animation is the same the animation will be much slower. To make it look better the time has to be shortened - it can be calculated depending on series width and updated in chart load event.
Check demo and code posted below:
Code:
(function(H) {
H.Series.prototype.animate = function(init) {
var series = this,
chart = series.chart,
clipRect,
animation = H.animObject(series.options.animation),
sharedClipKey;
// Initialize the animation. Set up the clipping rectangle.
if (init) {
series.setClip(animation);
// Run the animation
} else {
sharedClipKey = this.sharedClipKey;
clipRect = chart[sharedClipKey];
if (clipRect) {
clipRect.animate({
width: series.group.getBBox().width,
x: 0
}, animation);
}
if (chart[sharedClipKey + 'm']) {
chart[sharedClipKey + 'm'].animate({
width: chart.plotSizeX + 99,
x: 0
}, animation);
}
// Delete this function to allow it only once
series.animate = null;
}
}
})(Highcharts);
Highcharts.setOptions({
chart: {
events: {
load: function() {
var chart = this,
series = chart.series[0],
seriesWidth = series.graph.getBBox().width,
duration = (seriesWidth / chart.plotWidth) * series.options.animation.duration;
chart.series[0].update({
animation: {
duration: duration
}
});
}
}
},
plotOptions: {
series: {
animation: {
duration: 2000
}
}
}
});
Highcharts.chart('container', {
title: {
text: 'Chart with half data but with max data'
},
subtitle: {
text: 'A label should appear when all points are drawn'
},
xAxis: {
type: 'datetime',
min: Date.UTC(2019, 0, 1),
max: Date.UTC(2019, 11, 31),
tickInterval: 2592000000, // month
},
plotOptions: {
series: {
events: {
afterAnimate: function() {
this.chart.renderer.label(this.name + ' has appeared', 100, 70)
.attr({
padding: 10,
fill: Highcharts.getOptions().colors[0]
})
.css({
color: 'white'
})
.add();
}
}
}
},
series: [{
data: [{
x: Date.UTC(2019, 0, 1),
y: 29.9
},
{
x: Date.UTC(2019, 1, 1),
y: 139.9
},
{
x: Date.UTC(2019, 2, 1),
y: 59.9
},
{
x: Date.UTC(2019, 3, 1),
y: 19.9
},
]
}]
});
Highcharts.chart('container2', {
title: {
text: 'Chart with full data'
},
subtitle: {
text: 'A label should appear on the plot area after animate'
},
xAxis: {
type: 'datetime',
min: Date.UTC(2019, 0, 1),
max: Date.UTC(2019, 11, 31),
tickInterval: 2592000000, // month
},
plotOptions: {
series: {
events: {
afterAnimate: function() {
this.chart.renderer.label(this.name + ' has appeared', 100, 70)
.attr({
padding: 10,
fill: Highcharts.getOptions().colors[0]
})
.css({
color: 'white'
})
.add();
}
}
}
},
series: [{
data: [{
x: Date.UTC(2019, 0, 1),
y: 29.9
},
{
x: Date.UTC(2019, 1, 1),
y: 139.9
},
{
x: Date.UTC(2019, 2, 1),
y: 59.9
},
{
x: Date.UTC(2019, 3, 1),
y: 19.9
},
{
x: Date.UTC(2019, 4, 1),
y: 29.9
},
{
x: Date.UTC(2019, 5, 1),
y: 139.9
},
{
x: Date.UTC(2019, 6, 1),
y: 59.9
},
{
x: Date.UTC(2019, 7, 1),
y: 19.9
},
{
x: Date.UTC(2019, 8, 1),
y: 29.9
},
{
x: Date.UTC(2019, 9, 1),
y: 139.9
},
{
x: Date.UTC(2019, 10, 1),
y: 59.9
},
{
x: Date.UTC(2019, 11, 1),
y: 19.9
},
]
}]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
<div id="container2" style="height: 400px"></div>
Demo:
https://jsfiddle.net/BlackLabel/gj7eqkv8/
API reference:
https://api.highcharts.com/highcharts/chart.events.load

Highcharts Solid Gauge: Remove Wasted Space in Pane

I am currently laying out a page that uses multiple charts and I can't seem to remove the wasted space from a Highcharts Solid Gauge. I am only using 50% of the chart from range -90 to 90 yet the pane size is for 100% of the arc drawn. How can I reuduce the wasted space?
Current:
Desired:
I am using the following container:
<div id="container-ping" style="height: 20vh; width: 33.33%; float: left"></div>
These are the Solid Gauge parameters:
// Create the ping chart
$('#container-ping').highcharts({
chart: {
type: 'solidgauge'
},
tooltip: {
enabled: false
},
yAxis: {
min: 0,
max: 500,
stops: [
[0.1, '#55BF3B'], // green
[0.5, '#DDDF0D'], // yellow
[0.9, '#DF5353'] // red
],
lineWidth: null,
tickLength: 0,
tickPositions: [0, 500],
minorTickLength: 0,
minorTickInterval: null,
tickAmount: 2,
title: {
y: 0
},
labels: {
enabled: true,
distance: 15,
align: 'center'
}
},
plotOptions: {
solidgauge: {
dataLabels: {
y: 0,
borderWidth: 0,
useHTML: true
}
}
},
pane: {
center: ['50%', '50%'],
size: '100%',
startAngle: -90,
endAngle: 90,
background: {
backgroundColor: 'none',
borderColor: '#aaa',
innerRadius: '60%',
outerRadius: '100%',
shape: 'arc'
}
},
credits: {
enabled: false
},
title: {
text: processedData[0]['name']
},
series: [{
data: [processedData[0]['data'][0]],
dataLabels: {
format: '<div style="text-align:center"><span style="font-size:12px;color:' +
((Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black') + '">{y}</span><br/>'
}
}]
});
User ppotaczek mentioned a way to resize the chart using another function. This helped me look in the right direction in adding the height to the chart settings. This sizes the chart how I needed and did not require a redraw.
chart: {
type: 'solidgauge',
height: (70) + '%',
},
As mentioned in the comment above, you should use height option for the chart. Also, you can use center and size properties to optimize the space occupied by the chart.
pane: {
center: ['50%', '85%'],
size: '140%',
startAngle: -90,
endAngle: 90
}
Live demo: http://jsfiddle.net/BlackLabel/eo47dyam/
API Reference: https://api.highcharts.com/highcharts/pane.center

Highcharts Solid Gauge (Thermometer) ... Color from -30 to +60

how I can the yAxis Stops values adjust so that the shows me different colors depending on the temperature value?
The best would be as follows:
-30 to 0 = blue
0 to 12 = light blue
12 to 25 = green
25 to 30 = orange
30 to 60 = red
Here my Code:
$(function () {
var gaugeOptions = {
chart: {type: 'solidgauge'},
title: null,
pane: {
size: '90%',
startAngle: -180,
endAngle: 90,
background: {
backgroundColor: '#EEE',
innerRadius: '95%',
outerRadius: '100%',
shape: 'arc'
}
},
tooltip: {enabled: false},
// the value axis
yAxis: {
stops: [
[0.1, '#00f'],
[0.2, '#0f0'],
[0.3, '#f00']
],
lineWidth: 0,
minorTickInterval: 0,
tickPixelInterval: 50,
tickWidth: 1,
labels: {
enabled: true,
distance: 10
}
},
plotOptions: {
solidgauge: {
innerRadius: '95%',
dataLabels: {
y: 5,
borderWidth: 0,
useHTML: true
}
}
}
};
$('#temp001').highcharts(Highcharts.merge(gaugeOptions, {
yAxis: {
min: -30,
max: 60
},
credits: {
enabled: false
},
series: [{
name: 'inTemp',
data: [-15.5], /////// Temp Value //////////
dataLabels: {
format: '<div style="text-align:center"><span style="font-size:25px;color:' +((Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black') + '">{y} °C</span><br/>' + '<span style="font-size:12px;color:silver">abcde</span></div>'
}
}]
}));
});
Sorry for my Bad English....German ist better
Here you can find API about yAxis.stops:
http://api.highcharts.com/highcharts#yAxis.stops
The values in stops are between 0 and 1, where 0 is the min value of your axis and 1 is the max value. The values between 0 and 1 are proportional to values of axis.
If you are having axis with min value of -30 and max value of 60 and you want to have stop from 30, the value for stop will be
60/(60-(-30))
You should set your colors in RGB format of "#XXYYZZ" if you want to have smooth transition between colors of your stops.
stops: [
[0, '#000088'],
[29 / 90, '#000088'],
[30 / 90, '#5555ff'],
[41 / 90, '#5555ff'],
[42 / 90, '#00ff00'],
[54 / 90, '#00ff00'],
[55 / 90, '#ff8c00'],
[59 / 90, '#ff8c00'],
[60 / 90, '#ff0000']
],
example:
http://jsfiddle.net/izothep/o35xLwbk/6/

Using the VU Guage: add the numeric value below needle

In the Highcharts samples, I am seeing that the speedometer has a numeric indicator below the needle pivot (http://jsfiddle.net/radi8/kbvC3/497/). I am going to use the VU gauge but would like to add this numeric indicator to this gauge view. Playing with the fiddle (http://jsfiddle.net/radi8/Z2s77/1/), I cannot seem to get this element to display.
Any suggestions?
My VU from jsFiddle
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'gauge',
plotBorderWidth: 1,
plotBackgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, '#FFF4C6'],
[0.3, '#FFFFFF'],
[1, '#FFF4C6']
]
},
plotBackgroundImage: null,
height: 200
},
title: {
text: 'Efficiencies'
},
pane: [{
startAngle: -45,
endAngle: 45,
background: null,
center: ['25%', '145%'],
size: 300
}, {
startAngle: -45,
endAngle: 45,
background: null,
center: ['75%', '145%'],
size: 300
}],
yAxis: [{
min: 0,
max: 110,
minorTickPosition: 'outside',
tickPosition: 'outside',
labels: {
rotation: 'auto',
distance: 20
},
plotBands: [{
from: 0,
to: 70,
color: '#DF5353', // red
innerRadius: '100%',
outerRadius: '105%'
}, {
from: 70,
to: 95,
color: '#DDDF0D', // yellow
innerRadius: '100%',
outerRadius: '105%'
}, {
from: 95,
to: 110,
color: '#55BF3B', // green
innerRadius: '100%',
outerRadius: '105%'
}],
pane: 0,
title: {
text: 'OEE %<br/><span style="font-size:8px">Machine 001</span>',
y: -40
}
}, {
min: 0,
max: 110,
minorTickPosition: 'outside',
tickPosition: 'outside',
labels: {
rotation: 'auto',
distance: 20
},
plotBands: [{
from: 0,
to: 70,
color: '#DF5353', // red
innerRadius: '100%',
outerRadius: '105%'
}, {
from: 70,
to: 95,
color: '#DDDF0D', // yellow
innerRadius: '100%',
outerRadius: '105%'
}, {
from: 95,
to: 110,
color: '#55BF3B', // green
innerRadius: '100%',
outerRadius: '105%'
}],
pane: 1,
title: {
text: 'Cycle Eff %<br/><span style="font-size:8px">Machine 001</span>',
y: -40
}
}],
plotOptions: {
gauge: {
dataLabels: {
enabled: false
},
dial: {
radius: '100%'
}
}
},
series: [{
data: [80],
yAxis: 0
}, {
data: [80],
yAxis: 1
}]
},
// Let the music play
function(chart) {
setInterval(function() {
var left = chart.series[0].points[0],
right = chart.series[1].points[0],
leftVal,
//inc = (Math.random() - 0.5) * 30;
inc1 = Math.random() * (30) + 70;
inc2 = Math.random() * (30) + 70;
leftVal = left.y + inc1;
rightVal = right.y + inc2; // / 3;
if (leftVal < 0 || leftVal > 110) {
//leftVal = left.y - inc;
leftVal = 110 - inc1;
}
if (rightVal < 0 || rightVal > 110) {
rightVal = 110 - inc2;
}
left.update(leftVal,false);
right.update(rightVal);//, false);
chart.redraw();
}, 1500);
});
});
You have to enable and position dataLabels (now you have dataLabels: {enabled: false}).
See: http://api.highcharts.com/highcharts#plotOptions.gauge.dataLabels

highcharts Gauge live data with ajax

I have used highcharts library in my project and i have to update Gauge every 1 second with data creating by PHP file .
The highcharts Gauge Example have some code to make it trigger every 1 second , but i cant found some thing like This Link to get data from PHP file with Ajax Technic .
Anyone have any idea to implement this scenario and apply Ajax to this chart ?
You not found example because it is generic, see how it can be done with $.post():
http://jsfiddle.net/oceog/zpwdp/
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'gauge',
plotBackgroundColor: null,
plotBackgroundImage: null,
plotBorderWidth: 0,
plotShadow: false
},
title: {
text: 'Speedometer'
},
pane: {
startAngle: -150,
endAngle: 150,
background: [{
backgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, '#FFF'],
[1, '#333']
]
},
borderWidth: 0,
outerRadius: '109%'
}, {
backgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, '#333'],
[1, '#FFF']
]
},
borderWidth: 1,
outerRadius: '107%'
}, {
// default background
}, {
backgroundColor: '#DDD',
borderWidth: 0,
outerRadius: '105%',
innerRadius: '103%'
}]
},
// the value axis
yAxis: {
min: 0,
max: 200,
minorTickInterval: 'auto',
minorTickWidth: 1,
minorTickLength: 10,
minorTickPosition: 'inside',
minorTickColor: '#666',
tickPixelInterval: 30,
tickWidth: 2,
tickPosition: 'inside',
tickLength: 10,
tickColor: '#666',
labels: {
step: 2,
rotation: 'auto'
},
title: {
text: 'km/h'
},
plotBands: [{
from: 0,
to: 120,
color: '#55BF3B' // green
}, {
from: 120,
to: 160,
color: '#DDDF0D' // yellow
}, {
from: 160,
to: 200,
color: '#DF5353' // red
}]
},
series: [{
name: 'Speed',
data: [80],
tooltip: {
valueSuffix: ' km/h'
}
}]
},
// Add some life
function (chart) {
setInterval(function () {
$.post('/echo/json/',{
json: JSON.stringify({
//This is just a sample data, see comments after code to real world usage
inc: Math.round((Math.random() - 0.5) * 20)
})},
function(data) {
var point = chart.series[0].points[0],
newVal,
inc = data.inc;
newVal = point.y + inc;
if (newVal < 0 || newVal > 200) {
newVal = point.y - inc;
}
point.update(newVal);
},"json");
}, 3000);
});
});​
In real world you use something like
$.post('new_data.php',{last_time: last_time},function(data) {
//set point here
},"json")
in new_data.php you do something like
$data=get_data($last_time);
echo json_encode($data);
exit;

Resources