Highcharts Gauge styling and adding CSS elements - javascript

I'm working on a gauge module which is intended to look as follows:
Hydration Guage
Currently, I have the following model working:
(Please refer to the fiddle for the most updated code)
GaugeFiddle
$(function() {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'gauge'
},
title: {
text: 'Hydration Index'
},
pane: {
startAngle: -140,
endAngle: 140,
size: 200,
background: {
backgroundColor: {
linearGradient: [0, 300, 300, 300],
stops: [
[0, 'rgb(152, 230, 230)'],
[1, 'rgb(0, 0, 10)']
]
},
innerRadius: '70%',
outerRadius: '100%',
shape: 'arc',
}
},
yAxis: {
reversed: true,
min: 0,
max: 100,
plotBands: [{ // mark the weekend
}],
tickInterval: 600
},
plotOptions: {
gauge: {
dataLabels: {
enabled: false
},
dial: {
radius: '100%',
backgroundColor: 'black',
borderColor: 'white',
borderWidth: 0.5,
rearLength: 0,
baseWidth: 10,
topWidth: 1,
baseLength: '0%'
},
pivot: {
radius: 0
}
},
},
series: [{
name: 'Hydration percent',
data: [20],
}],
credits: {
enabled: false
},
});
});
1) How would I add those curved edges on only one side of the gauge?
2) Can I reverse the direction of the needle from clockwise to counterclockwise? Currently, I have the yaxis reversed so the graph works how it is supposed to, but it counter-intuitively starts at high and proceeds from there onward (So if my chart goes from 0-100 and my data value is 10, it would start at 100 and go to 10 by default).
3) Finally, is there any way for me to add the dynamic text that changes based on the result?

It's possible but a bit tricky - you can modify SVG's path before it's renderer by modyfying Axis.getPlotBandPath method. See a demo below.
You can simply disable initial animation and set value = 0. Then, in callback, update the point to the correct value:
series: [{
name: 'Hydration percent',
animation: false,
data: [
0
]
}],
And callback:
function(chart) { // on complete
chart.series[0].points[0].update(80);
...
}
It's not a problem using Renderer.text. For example:
chart.myLabel = chart.renderer.text('Test', 10, 10).add(); // store in some variable
Then update text:
chart.myLabel.attr({
text: 'Nice!'
});
Here is a working demo: http://jsfiddle.net/8p8ab8bg/

Related

How to change labels axis position of dynamic data values that are showing around the chart. I'm using Highcharts here

I want to change the axis position of data label 6.02%. How do I change it because this data is dynamic. Here's my code :
Highcharts.chart('container' + this.random, {
credits: {
enabled: false
},
title: {
text: this.graphtitle,
align: 'left',
style: {
fontSize: '12px',
},
},
chart: {
height: this.graphheight,
width: 500,
animation: false,
backgroundColor: 'transparent',
},
plotOptions: {
pie: {
dataLabels: {
enabled: true,
color: '#000',
align: 'left',
format: '{point.y} %', // added percentage sign here
overflow: 'justify', // prevent labels from being cut off
distance: 10, // increase distance between labels
x: -40,
y: -20,
//css
style: {
fontSize: '10px',
textOutline: 0,
},
connectorWidth: 0,
},
animation: true,
showInLegend: true,
},
},
yAxis: {
labels: {
staggerLines: 2,
enabled: true,
align: 'left',
padding: 0,
reserveSpace: true
},
},
legend: {
layout: 'vertical',
verticalAlign: 'bottom',
align: 'right',
symbolHeight: 10,
symbolRadius: 0,
symbolPadding: 1,
itemMarginTop: 10,
itemMarginBottom: 5,
textOutline: 0,
itemStyle: {
fontSize: '10px',
textOutline: 0,
}
},
series: [{
enableMouseTracking: false,
type: 'pie',
innerSize: '65%',
colors: this.graphcolors,
data: this.graphdata,
},],
});
},
below is the visual of pie chart:
I was trying this method but it's not working with my code any other method anyone would like to suggest ?
chart.series[0].data[1].update({
dataLabels: {
align: 'center',
verticalAlign: 'middle',
inside: true
}
});
I suppose graphdata here is dynamic data passed as a props. I came across a similar kind of bottleneck recently.
What I did to resolve this error is following:
You can sort your data ascending or descending using life cycle hooks e.g. getting the highest value element at 0 index or getting the lowest value element at 0 index.
data property of series in high charts expects a object with name and other custom properties to app where graph data has values like
['value 1', 1],
['value 2', 2]
{
                  name: this.graphdata[0][0],
                  y: this.graphdata[0][1],
                  sliced: false,
                  selected: true,
                  dataLabels: {
                    x: -25,
                    y: -15
                  }
                },
               {
               name: this.graphdata[1][0],
               y: this.graphdata[1][1],
               sliced: false,
               selected: true,
               dataLabels: {
                 x: -60,
                y: -25
               }
},
  this.graphdata[2],
   ],`enter code here`
In your code, you put negative values for plotOptions.pie.dataLabels.x and plotOptions.pie.dataLabels.y. This is probably not the best strategy if you push data dynamically...
When you use setData() to update your series, Highcharts optimizes labels position automatically.
Here is a simple example:
let chart = Highcharts.chart('container', {
chart: {
type: 'pie'
},
plotOptions: {
pie: {
innerSize: '65%',
dataLabels: {
format: '{point.y}',
distance: 10
}
}
},
series: [{
colors: ['red', 'green', 'blue'],
data: [10, 20, 15]
}]
});
function getInt() {
return chance.integer({ min: 1, max: 100 });
}
document.querySelector('button').addEventListener('click', () => {
chart.series[0].setData([getInt(), getInt(), getInt()]);
});
#container {
width: 350px;
height: 350px;
}
<script src="https://code.highcharts.com/10.3.3/highcharts.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chance#1.1.9/chance.min.js"></script>
<div id="container"></div>
<button type="button">Update</button>

Highcharts gauge chart size

I've been trying to make the gauge thinner. I succeeded a little by making the innerRadius 90%, but I'm unable to change the size of the green section. It's always bigger. I tried playing around with 'outerRadius' too but lo luck so far.
var gaugeOptions = {
chart: {
type: 'solidgauge'
},
title: null,
pane: {
center: ['30%', '85%'],
size: '150%',
startAngle: -90,
endAngle: 90,
background: {
backgroundColor: Highcharts.defaultOptions.legend.backgroundColor || '#EEE',
innerRadius: '110%',
outerRadius: '85%',
shape: 'arc'
}
},
tooltip: {
enabled: false
},
// the value axis
yAxis: {
stops: [
[0.1, '#55BF3B'], // green
[0.5, '#DDDF0D'], // yellow
[0.9, '#DF5353'] // red
],
lineWidth: 0,
minorTickInterval: null,
tickAmount: 2,
title: {
y: -70
},
labels: {
y: 16
}
},
plotOptions: {
solidgauge: {
dataLabels: {
y: 5,
borderWidth: 0,
useHTML: true
}
}
}
};
// The speed gauge
var chartSpeed = Highcharts.chart('container-speed', Highcharts.merge(gaugeOptions, {
yAxis: {
min: 0,
max: 100,
title: {
text: ''
}
},
credits: {
enabled: false
},
series: [{
name: 'Speed',
data: [20],
dataLabels: {
format: '<div style="text-align:center">' +
'<span style="font-size:25px">{y}</span><br/>' +
'<span style="font-size:12px;opacity:0.4">km/h</span>' +
'</div>'
}
}]
}));
Here's a fiddle. I'm basically trying to make the green match the grey.
The size of the green section can be set by add properties radius and innerRadius in series.data.
In your case, it should be:
series: [{
name: 'Speed',
data: [{
y: 20,
radius: 90,
innerRadius: 105
}],
dataLabels: {...}
}]
more info here
You can also set radius and innerRadius properties on a series level:
series: [{
radius: 90,
innerRadius: 105,
...
}]
Live demo: https://jsfiddle.net/BlackLabel/fwumc7db/
API Reference:
https://api.highcharts.com/highcharts/series.solidgauge.innerRadius
https://api.highcharts.com/highcharts/series.solidgauge.radius

High charts gauge-solid and different data sets

I'm using High charts gauge-solid. So I need to create below like chart.
Can you tell me how to give different data sets for this chart (each and every color has its own data)?
What I need is this:
This is what I have tried: jsfiddle
$(function () {
$('#gauge').highcharts({
chart: {
type: 'solidgauge',
backgroundColor: 'transparent'
},
title: null,
pane: {
center: ['50%', '70%'],
size: '130%',
startAngle: -120,
endAngle: 120,
background: {
backgroundColor: '#fff',
innerRadius: '75%',
outerRadius: '100%',
shape: 'arc',
borderColor: 'transparent'
}
},
tooltip: {
enabled: false
},
// the value axis
yAxis: {
min: 0,
max: 100,
stops: [
[0.1, '#e74c3c'], // red
[0.5, '#f1c40f'], // yellow
[0.9, '#2ecc71'] // green
],
minorTickInterval: null,
tickPixelInterval: 400,
tickWidth: 0,
gridLineWidth: 0,
gridLineColor: 'transparent',
labels: {
enabled: false
},
title: {
enabled: false
}
},
credits: {
enabled: false
},
plotOptions: {
solidgauge: {
innerRadius: '75%',
dataLabels: {
y: -45,
borderWidth: 0,
useHTML: true
}
}
},
series: [{
data: [83],
dataLabels: {
format: '<p style="text-align:center;">{y}%</p>'
}
}]
});
});
data array can contain more than one value for a series:
series: [{
data: [80, 150, 200]
}]
Live demo: http://jsfiddle.net/kkulig/tou6wwxj/
If you want every dial to move only within its own range then you can simply make sure that a proper value is assigned to a point while initializing or updating it.

HighCharts Solid Gauge Chart not displaying ticks

Using Highcharts 5.0.11 .JS version and Solid Gauge.
Page has two temperature Gauges which are going to be half crescent in shape.
The first Gauge Internal Temperature is fine, but when trying to play with settings to create an inverse Gauge the chart stops displaying ticks and labels associated to them as shown below along with link to my fiddle. The key thing I have found is that when ever the start angle is higher than the end angle this is the result and the problem occurs.
JS Fiddle Here to show Code for above
HTML
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/highcharts-more.js"></script>
<script src="http://code.highcharts.com/modules/solid-gauge.js"></script>
<!--Temperature Block-->
<div style="width: 600px; height: 200px; margin: 0 auto; background-color: black;">
<div id="containerinternalTemp" style="width: 200px; height: 200px; float: left"></div>
<div id="containerexternalTemp" style="width: 200px; height: 200px; float: left"></div>
</div>
JavaScript
$(function() {
// Temperature Guage Options
var temperatureGaugeOptions = {
chart: {
backgroundColor: null,
type: 'solidgauge'
},
title: null,
pane: {
size: '90%',
background: {
backgroundColor: 'white',
innerRadius: '93%',
outerRadius: '102%',
shape: 'arc'
}
},
tooltip: {
enabled: false
},
credits: {
enabled: false
},
// the value axis
yAxis: {
stops: [
[0, '#045ce2'],
[0.1, '#045ce2'],
[0.2, '#045ce2'],
[0.25, '#045ce2'],
[0.3, '#0489e2'],
[0.4, '#0489e2'],
[0.5, '#04cbe2'],
[0.52, '#04cbe2'],
[0.521, '#f9c527'],
[0.6, '#f9a426'],
[0.7, '#f98826'],
[0.8, '#f95e26'],
[0.9, '#f95e26']
],
lineWidth: 0,
minorTickInterval: 5,
tickPixelInterval: 50,
tickWidth: 1,
labels: {
style: {
color: 'white'
},
enabled: true,
distance: 12,
useHTML: true
}
},
plotOptions: {
solidgauge: {
innerRadius: '95%',
dataLabels: {
x: -20,
y: 35,
borderWidth: 0,
useHTML: true
}
}
}
};
// Internal Temperature
$('#containerinternalTemp').highcharts(Highcharts.merge(temperatureGaugeOptions, {
yAxis: {
min: -15,
max: 40,
},
pane: {
startAngle: -180,
endAngle: 0,
},
series: [{
name: 'inTemp',
data: [13],
dataLabels: {
style: {
color: 'orange',
},
format: '<div style="text-align:center"><span style="font-size:25px;">{y}°C</span><br/>' + '<span style="font-size:10px;color:white">Internal</span></div>'
}
}]
}));
// External Temperature
$('#containerexternalTemp').highcharts(Highcharts.merge(temperatureGaugeOptions, {
yAxis: {
min: -15,
max: 40,
},
pane: {
startAngle: 180,
endAngle: 0
},
series: [{
name: 'exTemp',
data: [5],
dataLabels: {
style: {
color: 'orange',
},
format: '<div style="text-align:center"><span style="font-size:25px;">{y}°C</span><br/>' + '<span style="font-size:10px;color:white">External</span></div>'
}
}]
}));
});
I have tried various settings and the closest results I can achieve is below using the reversed:true option and having the start angle lower than the end angle, the only problem being that the plot line is drawn from a start point of 40. I require it to start from -15 and draw up to 5.
Js Fiddle for second result
Javascript - The only change is the reversed: true added on the yAxis and the start and end angle for the pane.
// External Temperature
$('#containerexternalTemp').highcharts(Highcharts.merge(temperatureGaugeOptions, {
yAxis: {
min: -15,
max: 40,
reversed: true
},
pane: {
startAngle: 0,
endAngle: 180
},
series: [{
name: 'exTemp',
data: [5],
dataLabels: {
style: {
color: 'orange',
},
format: '<div style="text-align:center"><span style="font-size:25px;">{y}°C</span><br/>' + '<span style="font-size:10px;color:white">External</span></div>'
}
}]
}));
I have searched and found an issue from 2015 with Solid Gauge charts HERE and trying to do what I have done. This issue looks to have been fixed and I can not find anything else to show this being an outstanding problem with Highcharts platform.
Many thanks in advance from anyone who takes the time to read and review this question.
It looks like it is a problem with automating calculation of the tick positions when endAngle is greater than startAngle. You can force the tick positions by setting axis tickPositions or tickPositioner. In your case, you can grab the tick positions from the first gauge chart in the tick positioner callback.
yAxis: {
min: -15,
max: 40,
// reversed: true
tickPositioner: function() {
var tickPositions = $('#containerinternalTemp').highcharts().yAxis[0].tickPositions
return tickPositions;
}
example: http://jsfiddle.net/egr0ge11/

HighChart how set dataLabel position dynamically in formatter base on its value

I try drawing a polar chart by 'HighChart' that each series have 2 data category between 0 to 100 that have overlap on other.
My problem is when data value is greater than 90, dataLabel of 2 category have overlap.
I want set dataLabel position dynamically by formatter function.
All my try to do this was failed.
Is there solution to solve this problem?
In below is my simplified code. And in this JSFiddle.net you can see result and edit it
var chart;
var options={
chart:
{
renderTo: 'container',
type: 'column',
polar: true
},
xAxis:
{
categories: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']
},
yAxis:
{
gridLineWidth: 0,
labels:
{
enabled: false
}
},
colors: ['#F47414', '#A8CBFF'],
plotOptions:
{
column:
{
grouping: false,
shadow: false
},
series:
{
dataLabels:
{
enabled: true /// for use My solution, comment this line
/* ------------------------------------------------------------
/// My solution is using formatter to set y align based on value. But I don't know why this don't work.
enabled: true,
formatter: function ()
{
if (this.y>=90 && this.y<100)
{
console.log(this.series.options.dataLabels.y);
this.series.options.dataLabels.y =+ 20;
}
}
---------------------------------------------------------------*/
}
}
},
series:
[
{name: 'GoalPerecent', data:[100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100]},
{name: 'ActualPerecent', data:[95, 20, 23, 45, 98, 10, 35, 73, 33, 85, 64, 10]}
]
}
$(document).ready(function()
{
chart = new Highcharts.Chart(options);
});

Categories

Resources