I'm using ChartsJS to create a gauge. I like their styles so I thought it wouldn't be too hard to implement compared to Highcharts or others.
I put the code (which comes in from a jQuery AJAX load - might be a factor) and it ONLY works if I right click and open Inspect Element, or if it is already open, I have to close it. Otherwise it's just empty white space ... no console errors..
Code:
var scaleSettings = {
startValue: -50,
endValue: 50,
majorTick: {
color: 'black',
tickInterval: 10
},
minorTick: {
visible: true,
color: 'black',
tickInterval: 1
}
};
$("#gaugeGraph").dxCircularGauge({
value:200,
valueIndicator: {
type: 'rangebar',
color: '#483D8B'
},
geometry: {
startAngle: 180, endAngle: 0
},
scale: {
startValue: 0, endValue: 100,
majorTick: {
tickInterval: 25,
tickInterval: 50,
tickInterval: 75,
tickInterval: 100
},
label: {
customizeText: function (arg) {
return arg.valueText + ' %';
}
}
}
});
Load Code:
$(document).ready(function() {
loadURL("dataGraph.php?id=<?php echo $id;?>", $('#section > .graph'));
loadURL("dataGauge.php?id=<?php echo $id;?>", $('#section > .gauge')); //GAUGE
$(window).trigger('resize');
loadURL("dataRecords.php?id=<?php echo $id;?>", $('#section > .dataTable'));
});
#k0pernikus helped to discover the resize issue.
I used this code to make it happen:
$( document ).ready(function() {
var scaleSettings = {
startValue: -50,
endValue: 50,
majorTick: {
color: 'black',
tickInterval: 10
},
minorTick: {
visible: true,
color: 'black',
tickInterval: 1
}
};
$(window).resize(function()
{
$("#gaugeGraph").dxCircularGauge({
value:200,
valueIndicator: {
type: 'rangebar',
color: '#483D8B'
},
geometry: {
startAngle: 180, endAngle: 0
},
scale: {
startValue: 0, endValue: 100,
majorTick: {
tickInterval: 25,
tickInterval: 50,
tickInterval: 75,
tickInterval: 100
},
label: {
customizeText: function (arg) {
return arg.valueText + ' %';
}
}
}
});
}).resize();
});
Related
html
js
var myChart = echarts.init(document.getElementById("main"));
window.onresize = myChart.resize;
var statistics = {
title: {
text: "面积",
textStyle: {
fontWeight: "normal",
color: "#fff",
fontSize: 14
},
left: "center"
},
tooltip: {
// 鼠标移动柱状图是提示文字
show: true
},
legend: {
// data: ['面积'],
textStyle: {
fontSize: 12
}
},
xAxis: {
data: ["灌木", "森林", "森林", "树木", "小树", "大树", "红树"],
axisLabel: {
show: true,
textStyle: {
color: "#fff"
}
},
axisLine: {
lineStyle: {
color: "#094060"
}
}
},
yAxis: {
axisLine: {
lineStyle: {
color: "#094060"
}
},
axisLabel: {
show: true,
textStyle: {
color: "#fff"
}
},
splitLine: {
lineStyle: {
color: ["#07405c"]
}
}
},
itemStyle: {
color: "#06ae7c",
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: "rgba(0, 0, 0, 0.5)"
}
},
series: [
{
type: "bar",
barWidth: 48,
data: [38, 23, 35, 12, 26, 8, 36]
}
]
};
myChart.setOption(statistics);
The echarts container in the tab switch width is set to 100%, but no matter how to set the width, are only 100px, the Internet that is because the tab bar tried to hide cause, many of the above methods, are not normal display, followed by window.onresize = myChart.resize in the code; only when changing the size of the browser window to display properly, but if you do not change the size of the window or after 100px, before we have encountered this kind of situation is how to solve?
put the class "echart" in each div chart, and execute that in your js.
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
$(".echart").each(function() {
var id = $(this).attr('echarts_instance');
window.echarts.getInstanceById(id).resize();
});
});
I have discovered one workaround for this issue. Try to call the resize event of window object when you switch tabs. To achieve it with jQuery is straightforward:
$(window).trigger('resize');
var myChart=$("#myChart");
myChart.style.width=window.innerWidth+'px';
chartObj=echarts.init(myChart);
chartObj.setOption(option);
i have the next problem with Highcharts. This is a new Highchart for an other site.
See here: https://imgur.com/a/VQQLU
The arrow show to -3 Megawatts but the value at the bottom shows another value. At the first pageload the values are identical, but there comes all 5 seconds new values. And they are not updated at the bottom.
Edit: The tolltip will be updated correctly.
My code:
$(function () {
$.getJSON('jsonlive.php', function(chartData) {
var ADatum; var Eheit; var AktL; var MinL; var MaxL; var chartValue; var i;
ADatum = chartData[0].AktDatum;
Eheit = chartData[0].Einheit;
AktL = chartData[0].AktuelleLeistung;
MinL = chartData[0].MinLeistung;
MaxL = chartData[0].MaxLeistung;
var tMin = (MinL*-1); var tMax = MaxL;
var ttt = new Array();
if (tMin < tMax) { chartValue = tMax; } else if (tMin > tMax) { chartValue = tMin; } // Ermitteln ob neg/pos Zahl die größere ist.
ttt[0] = (chartValue*-1); // Skala mit Zahlen beschriften
for (i = 1; i < chartValue; i++) { ttt[i] = (i*-1); }
var tz = ttt.length ;
for (i = 0; i < chartValue; i++) { ttt[(tz+i)] = i; }
ttt[ttt.length] = chartValue;
var gaugeOptions = {
chart:{ events: {
load: function () { setInterval(function () {
$.getJSON('jsonlive.php', function(chartData) {
ADatum = chartData[0].AktDatum;
AktL = chartData[0].AktuelleLeistung;
var point = $('#inhalt').highcharts().series[0].setData([AktL], true);
});}, 5000);}
}, type: 'gauge' },
title: null,
pane: {
center: ['50%', '85%'], size: '140%', startAngle: -90, endAngle: 90,
background: [{
backgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [[0, '#00fb00'],[1, '#003f00']]},
borderWidth: 2,
outerRadius: '109%',
innerRadius: '102%', shape: 'arc' }]
},
series: [{
data: [AktL],
dataLabels: { borderWidth: 0,align: 'center',x: 0,y: 110,
format: '<div style="text-align:center;font-size:24px;color:black">'+AktL+' ' +Eheit+'</span></div>'
}
}],
tooltip: {
formatter: function () { return 'Datum: <b>' + (new Date(ADatum).toLocaleString("de-DE", { timeZone: 'UTC' })) +
'</b> <br>Leistung <b>' + AktL + ' ' + Eheit + '</b>';}, enabled: true },
yAxis: {lineWidth: 10, minorTickInterval: null, tickPixelInterval: 100, tickWidth: 5, title: { y: -250 }, labels: { y: 2 }}
};
// Anzeige
$('#inhalt').highcharts(Highcharts.merge(gaugeOptions, {
yAxis: {
min: (chartValue*-1),max: chartValue,tickPositions: ttt,tickColor: '#666',minorTickColor: '#666',
plotBands: [{ // optionaler Bereich, zeigt von 0-1 grün, 1 bis hälfte maximum gelb, und hälfte max bis max rot
from: 0, to: -1, color: '#55BF3B' }, { // green
from: -1, to: ((chartValue*-1)/2), color: '#DDDF0D' }, { // yellow
from: ((chartValue*-1)/2),to: (chartValue*-1),color: '#DF5353' }, { // red
from: 0,to: 1,color: '#55BF3B' }, { // green
from: 1,to: (chartValue/2),color: '#DDDF0D' }, { // yellow
from: (chartValue/2),to: chartValue,color: '#DF5353' }],// red
title: { style: { color: 'black', fontWeight: 'bold', fontSize: '24px' }, text: 'Leistung in '+Eheit },
labels: { formatter: function () { return this.value; }}},
credits: { enabled: false } // Link auf highcharts rechts unten an/aus
}));
});
});
</script>
The problem here is that you use a hard-coded value (AktL) in your dataLabels.format. In your example format is just a string that's used all the time.
Use {point.y} to have the label updated on every setData():
series: [{
data: [val],
dataLabels: {
// format: val // WONT WORK
format: '{point.y}'
}
}],
Live demo: http://jsfiddle.net/BlackLabel/v28q5n09/
My idea is to display CPU and memory load with highcharts solid gauge which would update every few seconds, but what ever I do, it just wont run it as I wanted, so it's like this:
I have this php code which is giving me an integer for cpu and memory usage
$cpu = exec("mpstat 1 1 | grep 'all' | awk '{print 100 - $12}' | head -n 1");
$mem = exec("free -m | grep Mem | awk '{print $3 / $2 * 100}'");
This is my highcharts js script:
$(function () {
var gaugeOptions = {
chart: {
type: 'solidgauge'
},
title: null,
pane: {
center: ['50%', '85%'],
size: '105%',
startAngle: -90,
endAngle: 90,
background: {
backgroundColor: (Highcharts.theme && Highcharts.theme.background3) || '#EEE',
innerRadius: '60%',
outerRadius: '100%',
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,
tickPixelInterval: 400,
tickWidth: 0,
title: {
y: -70
},
labels: {
y: 16
}
},
plotOptions: {
solidgauge: {
dataLabels: {
// y: 5,
borderWidth: 0,
useHTML: true
}
}
}
};setTimeout(function () {
$('#container-speed').highcharts(Highcharts.merge(gaugeOptions, {
yAxis: {
min: 0,
max: 100,
title: {
text: 'CPU'
}
},
credits: {
enabled: false
},
series: [{
name: 'CPU',
data: [0],
dataLabels: {
format: '<div style="text-align:center"><span style="font-size:18px;color:' +
((Highcharts.theme && Highcharts.theme.contrastTextColor) || '#CECECE') + '">{y:.1f} %</span><br/>' +
'<span style="font-size:12px;color:silver"></span></div>'
},
}]
}));
$('#container-rpm').highcharts(Highcharts.merge(gaugeOptions, {
yAxis: {
min: 0,
max: 100,
title: {
text: 'RAM'
}
},
series: [{
name: 'RAM',
data: [0],
dataLabels: {
format: '<div style="text-align:center"><span style="font-size:20px;font-family:Arial;color:' +
((Highcharts.theme && Highcharts.theme.contrastTextColor) || '#CECECE') + '">{y:.1f}%</span><br/>' +
'<span style="font-size:12px;color:silver"></span></div>'
},
}]
}));
var chart = $('#container-speed').highcharts(),
point,
newVal,
inc;
if (chart) {
point = chart.series[0].points[0];
inc = <?php echo $cpu; ?>;
newVal = inc;
if (newVal < 0 || newVal > 200) {
newVal = point.y - inc;
}
point.update(newVal);
}
chart = $('#container-rpm').highcharts();
if (chart) {
point = chart.series[0].points[0];
inc = <?php echo $mem; ?>;
newVal = inc;
if (newVal < 0 || newVal > 5) {
newVal = point.y - inc;
}
point.update(newVal);
} }, 5000);});
...and this is my container for calling the gauge:
<div style="width: 600px; height: 400px; margin: 0 auto" >
<div id="container-speed" style="width: 300px; height: 200px; float: left"></div>
<div id="container-rpm" style="width: 300px; height: 200px; float: left"></div></div>
Now, the problem is when it refreshes, it keeps giving me the same values on every refresh.
Thanks to everyone in advance.
I the meanwhile I managed to solve my problem with the help of #Grzegorz Blachliński's comment, so here goes:
first, my php code which is nothing more than two variables checking for cpu load and memory usage.
<?php
$cpu = exec("mpstat 1 1 | grep 'all' | awk '{print 100 - $12}' | head -n 1");
$mem = exec("free -m | grep Mem | awk '{print $3 / $2 * 100}'");
echo "[$cpu,$mem]";?>
Now, for some reason json_encode($cpu,$mem); was returning values which were inside quotes and I was able to read them as integer with for example alert(mem);, but the chart didn't accept those values and didn't draw chart, so I did a workaround for it by echoing the proper format of variable values.
Here's my javascript file:
function setDivHeight() {
var div = $('#cpu-meter');
div.height(div.width() * 0.75);
div = $('#memory-meter');
div.height(div.width() * 0.75); } $(function () {
if( $(window).width() < 1000){
setDivHeight();
$(window).on('load resize', function(){
setDivHeight();
});
}
var gaugeOptions = {
chart: {
type: 'solidgauge',
events: {
load: requestData
}
},
title: null,
pane: {
center: ['50%', '85%'],
size: '140%',
startAngle: -90,
endAngle: 90,
background: {
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || '#EEE',
innerRadius: '60%',
outerRadius: '100%',
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,
tickPixelInterval: 400,
tickWidth: 0,
title: {
y: -70
},
labels: {
y: 16
}
},
plotOptions: {
solidgauge: {
dataLabels: {
y: 5,
borderWidth: 0,
useHTML: true
}
}
}
};
$('#cpu-meter').highcharts(Highcharts.merge(gaugeOptions, {
yAxis: {
min: 0,
max: 100,
title: {
text: 'CPU Usage'
}
},
credits: {
enabled: false
},
series: [{
data: [0],
dataLabels: {
format: '<div style="text-align:center"><span style="font-size:20px;font-family:Arial;color:#777;">{y:.2f} %</span><br/>'
},
}]
}));
$('#memory-meter').highcharts(Highcharts.merge(gaugeOptions, {
yAxis: {
min: 0,
max: 100,
title: {
text: 'Memory Usage'
}
},
credits: {
enabled: false
},
series: [{
data: [0],
dataLabels: {
format: '<div style="text-align:center"><span style="font-size:20px;font-family:Arial;color:#777;">{y:.2f} %</span><br/>'
},
}]
}));
function requestData() {
$.ajax({
url: 'core/cpu-data.php',
type: "GET",
dataType:"json",
success: function(load) {
var chart = $('#cpu-meter').highcharts(),
point = 0,
newVal = 0,
inc = 0;
point = chart.series[0].points[0];
inc = load[0];
diff = newVal - inc;
if (diff > 0) {
newVal = newVal + diff;
} else {
newVal = newVal - diff;
}
point.update(newVal);
chart = $('#memory-meter').highcharts(),
point = 0,
newVal = 0,
inc = 0;
point = chart.series[0].points[0];
inc = load[1];
diff = newVal - inc;
if (diff > 0) {
newVal = newVal + diff;
} else {
newVal = newVal - diff;
}
point.update(newVal);
setTimeout(requestData, 3000);
},
cache: false
});
}});
As you can see, ajax is getting data from my php file and making gauge increase and decrease it's value for setTimeout value (don't use setInterval).
Once again, thanks to all for help.
The chart may be reloading, but it looks like you never reload the $cpu and $mem variables themselves. They would also need to be refreshed, as once they're assigned, they will continue to hold their initial value until you specifically re-execute their exec(...) commands and update them.
You can change the width of the pointer by setting the cap:size value, but I need to change the length of the pointers so that they are in a tiered fashion representing 5 different points in time. How can this be done?
function createGauge() {
$("#gauge").kendoRadialGauge({
pointer: [{
value: 10,
color: "#c20000",
cap: {
size: 0.19
}
}, {
value: 70,
color: "#ff7a00",
cap: {
size: 0.15
}
}, {
value: 140,
color: "#ffc700",
cap: {
size: 0.11
}
}, {
value: 350,
color: "#ffe700",
cap: {
size: 0.07
}
}, {
value: 313,
color: "#fff700",
cap: {
size: 0.03
}
}],
scale: {
minorUnit: 5,
startAngle: 90,
endAngle: 450,
max: 360
}
});
}
$(document).ready(function() {
createGauge();
$("#example .slider").each(function() {
$(this).kendoSlider({
min: 0,
max: 360,
showButtons: true,
change: function() {
var id = this.element.attr("id");
var pointerIndex = id.substr(id.length - 1);
var gauge = $("#gauge").data("kendoRadialGauge");
gauge.pointers[pointerIndex].value(this.value());
}
});
});
$("#getValues").click(function() {
alert("All values: " + $("#gauge").data("kendoRadialGauge").allValues().join(", "));
});
$("#setValues").click(function() {
var values = $("#newValues").val().split(",");
values = $.map(values, function(val) {
return parseInt(val);
});
$("#gauge").data("kendoRadialGauge").allValues(values);
});
$(document).bind("kendo:skinChange", function(e) {
createGauge();
});
});
#gauge {
width: 33em;
height: 33em;
//margin: 0 auto 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.3.1411/js/kendo.all.min.js"></script>
<div id="gauge-container">
<div id="gauge"></div>
</div>
According to Telerik you can't. At least for the current version.
http://www.telerik.com/forums/change-length-of-radial-gauge-pointer
I used in ANGULARJS below code is used to reduce the length of the pointer.
gauge.options.scale.labels = {
border: { width:13 }
};
I used label position as 'outside'.
Yes, you can change the pointer length now. pointer.length:
The pointer length (in percent) that is based on the distance to the scale. The default length of 1 indicates that the pointer exactly reaches the scale. Accepts values between 0.1 and 1.5.
function createGauge() {
$("#gauge").kendoRadialGauge({
pointer: [{
value: 10,
color: "#c20000",
cap: {
size: 0.19
},
length: 1,
}, {
value: 70,
color: "#ff7a00",
cap: {
size: 0.15
},
length: 0.8,
}, {
value: 140,
color: "#ffc700",
cap: {
size: 0.11
},
length: 0.6,
}, {
value: 350,
color: "#ffe700",
cap: {
size: 0.07
},
length: 0.5,
}, {
value: 313,
color: "#fff700",
cap: {
size: 0.03
},
length: 0.4,
}],
scale: {
minorUnit: 5,
startAngle: 90,
endAngle: 450,
max: 360
}
});
}
$(document).ready(function() {
createGauge();
$("#example .slider").each(function() {
$(this).kendoSlider({
min: 0,
max: 360,
showButtons: true,
change: function() {
var id = this.element.attr("id");
var pointerIndex = id.substr(id.length - 1);
var gauge = $("#gauge").data("kendoRadialGauge");
gauge.pointers[pointerIndex].value(this.value());
}
});
});
$("#getValues").click(function() {
alert("All values: " + $("#gauge").data("kendoRadialGauge").allValues().join(", "));
});
$("#setValues").click(function() {
var values = $("#newValues").val().split(",");
values = $.map(values, function(val) {
return parseInt(val);
});
$("#gauge").data("kendoRadialGauge").allValues(values);
});
$(document).bind("kendo:skinChange", function(e) {
createGauge();
});
});
#gauge {
width: 33em;
height: 33em;
//margin: 0 auto 0;
}
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2021.2.511/js/kendo.all.min.js"></script>
<div id="gauge-container">
<div id="gauge"></div>
</div>
Having issues with the Knockout-Kendo radial gauge in my application.
I'm trying to initialize it via the data-bind property, but it does not appear to be resizing itself correctly.
<div id="speedGauge" data-bind="kendoRadialGauge: $parent.speedGaugeOptions"></div>
...
self.speedGaugeOptions = {
renderAs: 'svg',
value: 0,
gaugeArea: {
background: 'transparent'
},
pointer: {
color: 'lightgray',
animation: {
speed: 100
}
},
scale: {
minorUnit: 75,
majorUnit: 150,
startAngle: -40,
endAngle: 220,
max: 300,
min: -300,
labels: {
position: 'inside',
font: '10px Arial,Helvetica,sans-serif'
},
ranges: [
{
from: -300,
to: -200,
color: "darkgray"
},
{
from: 300,
to: 200,
color: "darkgray"
}
],
rangeSize: 5,
rangeDistance: -5,
rangePlaceholderColor: '#f2f2f2'
}
Here comes the fun part;
When the page has activated (using durandal), the gauges are drawn like this:
In order for the gauge to scale correctly and fit inside the gray circle, I have to redraw it like this (either from the browser console, or in the .js file):
$("#speedGauge").data("kendoRadialGauge").redraw()
When doing so, my gauge looks the way it's suppose to;
Now, I've tried creating it using the regular Kendo implementation - and that works just fine resulting in the gauge to be drawn correctly like in the image above;
<div id="speedGauge"></div>
...
self.activate = function () {
createGauge();
}
...
function createGauge() {
$("#speedGauge").kendoRadialGauge({
renderAs: 'svg',
value: 0,
gaugeArea: {
background: 'transparent'
},
pointer: {
color: 'lightgray',
animation: {
speed: 100
}
},
scale: {
minorUnit: 75,
majorUnit: 150,
startAngle: -40,
endAngle: 220,
max: 300,
min: -300,
labels: {
position: 'inside',
font: '10px Arial,Helvetica,sans-serif'
},
ranges: [
{
from: -300,
to: -200,
color: "darkgray"
},
{
from: 300,
to: 200,
color: "darkgray"
}
],
rangeSize: 5,
rangeDistance: -5,
rangePlaceholderColor: '#f2f2f2'
}
});
}
Does anyone have an idea of what might be wrong here?
A colleague suggested to do a forced redraw of the gauges on durandals attached event, which solved the problem for now. The actual resizing of the gauge is not visible with this solution.
self.attached = function(element) {
$(element).find("[data-role='radialgauge']").each(function () { $(this).data("kendoRadialGauge").redraw(); });
};
I've reported the issue here.