Watch the CPU and memory gauges for a second. They move dynamically.
The example code shown below does not move the gauges like that (or at least when I tried it in my own project.)
How do I to get it moving dynamically like that?
(Also, will these gauges slow down my site connecting to Google? On the other hand, will it bring up my rankings?)
The example code and the actual demo are different. Try this instead:
<html>
<head>
<script type='text/javascript' src='http://www.google.com/jsapi'></script>
<script type='text/javascript'>
google.load('visualization', '1', {packages:['gauge']});
google.setOnLoadCallback(drawChart);
</script>
</head>
<body>
<div id='chart_div'></div>
<script type="text/javascript">
function Timer(){this.t={};this.tick=function(a,b){this.t[a]=[(new Date).getTime(),b]};this.tick("start")}var loadTimer=new Timer;window.jstiming={Timer:Timer,load:loadTimer};if(window.external&&window.external.pageT)window.jstiming.pt=window.external.pageT;if(window.jstiming)window.jstiming.report=function(g,d){var c="";if(window.jstiming.pt){c+="&srt="+window.jstiming.pt;delete window.jstiming.pt}if(window.external&&window.external.tran)c+="&tran="+window.external.tran;var a=g.t,h=a.start;delete a.start;var i=[],e=[];for(var b in a){if(b.indexOf("_")==0)continue;var f=a[b][1];if(f)a[f][0]&&e.push(b+"."+(a[b][0]-a[f][0]));else h&&i.push(b+"."+(a[b][0]-h[0]))}if(d)for(var j in d)c+="&"+j+"="+d[j];(new Image).src=["http://csi.gstatic.com/csi?v=3","&s=gviz&action=",g.name,e.length?"&it="+e.join(",")+c:c,"&rt=",i.join(",")].join("")};
</script>
<script type="text/javascript">
var csi_timer = new window.jstiming.Timer();
csi_timer.name = 'docs_gauge';
google.setOnLoadCallback(drawChart);
function drawChart() {
csi_timer.tick('load');
var data = new google.visualization.DataTable();
data.addColumn('string', 'Label');
data.addColumn('number', 'Value');
data.addRows(3);
data.setValue(0, 0, 'Memory');
data.setValue(0, 1, 80);
data.setValue(1, 0, 'CPU');
data.setValue(1, 1, 55);
data.setValue(2, 0, 'Network');
data.setValue(2, 1, 68);
csi_timer.tick('data');
var chart = new google.visualization.Gauge(document.getElementById('chart_div'));
csi_timer.tick('new');
var options = {width: 400, height: 120, redFrom: 90, redTo: 100,
yellowFrom:75, yellowTo: 90, minorTicks: 5};
chart.draw(data, options);
csi_timer.tick('draw');
window.jstiming.report(csi_timer);
setInterval(function() {
data.setValue(0, 1, 40 + Math.round(60 * Math.random()));
chart.draw(data, options);
}, 13000);
setInterval(function() {
data.setValue(1, 1, 40 + Math.round(60 * Math.random()));
chart.draw(data, options);
}, 5000);
setInterval(function() {
data.setValue(2, 1, 60 + Math.round(20 * Math.random()));
chart.draw(data, options);
}, 26000);
}
</script>
</body>
</html>
Their demo uses a pseudo random number generator to update the graph. It's a little misleading.
I draw the initial chart using their code and then use an ajax call to fetch the updated data as a json string - from php. Then I populate the data table and update the chart with jQuery/javascript. I haven't gotten around to making a full tutorial yet b/c it's not ready for production...
The hardest part is getting your data formatted correctly on the server-side and feeding ajax without blowing up the browser. The code appears to be really fast and when you're monitoring a webserver you kinda want the image rendering to be done somewhere else. It works but, at this point, it's still not completely browser agnostic - which is why I chose to use re-write in jQuery.
As far as I know, your page rankings are unrelated...
All of the solutions are using random generated number to animate the gauge for demo. What if you want to show a real value AND animate it at the same time?
Here is the solution:
Code it yourself on JSFiddle
function isEven(n) {
return n % 2 == 0;// true|false
}
google.charts.load('current', {'packages':['gauge']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['Memory', 80],
['CPU', 55],
['Network', 68]
]);
var options = {
width: 400, height: 120,
redFrom: 90, redTo: 100,
yellowFrom:75, yellowTo: 90,
minorTicks: 5
};
var chart = new google.visualization.Gauge(document.getElementById('chart_div'));
chart.draw(data, options);
// Animate Gauges: (ArrayNum(start:0), ColumnInThatArray(start:0), NewValue)
// OR in anoher words(rowIndex, columnIndex, NewValue)
setInterval(function() {
var chartValue = data.getValue(0, 1);
if (isEven(chartValue)){
data.setValue(0, 1, (chartValue + 5));
} else {
data.setValue(0, 1, (chartValue - 5));
}
chart.draw(data, options);
}, 450);// milisecond
setInterval(function() {
var chartValue = data.getValue(1, 1);
if (isEven(chartValue)){
data.setValue(1, 1, (chartValue + 1));
} else {
data.setValue(1, 1, (chartValue - 1));
}
chart.draw(data, options);
}, 600);// milisecond
setInterval(function() {
var chartValue = data.getValue(2, 1);
if (isEven(chartValue)){
data.setValue(2, 1, (chartValue + 3));
} else {
data.setValue(2, 1, (chartValue - 3));
}
chart.draw(data, options);
}, 1000);// milisecond
}
Related
I am trying to print the bottom label of the Google gauges outside(just below the respective gauges). Also, I want to provide two different suffixes for the two gauges. I have tried giving separate formatters(formatter1, formatter2) for both and separate data(data1 and data2), but it's not even drawing the gauges(no error). In this case, the draw_data_guage will have a fourth argument.
var e = document.getElementById('draw_chart');
e.onclick = draw_data_gauge(80, 68, '%');
function draw_data_gauge(cpu_data, memory_data, suffix) {
console.log("in guage")
google.charts.load('current', {
'packages': ['gauge']
});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data1 = google.visualization.arrayToDataTable([
['Label', 'Value'],
['CPU', cpu_data],
['Memory', memory_data],
]);
var options = {
width: 500,
height: 150,
redFrom: 90,
redTo: 100,
yellowFrom: 75,
yellowTo: 90,
minorTicks: 5,
};
var formatter1 = new google.visualization.NumberFormat({
suffix: suffix,
});
formatter1.format(data1, 1);
var chart = new google.visualization.Gauge(document.getElementById('chart_div'));
chart.draw(data1, options);
}
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<input name="Button" type="button" value="Draw" id="draw_chart" />
<div id="chart_div"></div>
I want the gauge's bottom label to be displayed outside and be able to give separate suffixes for both the gauges. Consider this jsfiddle link. I want to display the percentages(bottom label) outside the gauges just below them. My jsfiddle link is here. Thanks in advance.
Your direction to separate the graphs is right. Here is how to do this:
div {
display: inline-block;
}
<script type='text/javascript' src='https://www.google.com/jsapi'></script>
<script type="text/javascript">
google.load('visualization', '1', {
packages: ['gauge']
});
google.setOnLoadCallback(drawChart);
function drawChart() {
var options = {
width: 400,
height: 120,
redFrom: 90,
redTo: 100,
yellowFrom: 75,
yellowTo: 90,
minorTicks: 5
};
var source = [{
data: ['Memory', 80],
suffix: '%'
},
{
data: ['CPU', 55],
suffix: '?'
},
{
data: ['Network', 68],
suffix: '$'
},
];
source.map((item, index) => {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
item.data
]);
var formatter = new google.visualization.NumberFormat({
suffix: item.suffix,
fractionDigits: 0
});
formatter.format(data, 1);
document.body.innerHTML += '<div id="chart_div_' + index + '"></div>';
var chart = new google.visualization.Gauge(document.getElementById('chart_div_' + index));
chart.draw(data, options);
});
// dynamic update, randomly assign new values and redraw
//setInterval(function() {
// data.setValue(0, 1, 40 + Math.round(60 * Math.random()));
// formatter.format(data, 1);
// chart.draw(data, options);
//}, 1000);
//
//setInterval(function() {
// data.setValue(1, 1, 40 + Math.round(60 * Math.random()));
// chart.draw(data, options);
//}, 1000);
//
//setInterval(function() {
// data.setValue(2, 1, 40 + Math.round(60 * Math.random()));
// chart.draw(data, options);
//}, 1000);
}
</script>
About the text position, I think that it's impossible. You can add a div below each chart with the text.
I'm making a dashboard in Google Spreadsheet and would like to use cell data. Now you need to hard code the data and the values for redFrom, redTo etc etc but I want them to be dynamic and dependant on a certain value in a cell. Same applies to the values shown by the gauge.
The dashboard will to track monthly income and the gauge will indicate if someone if in the green for that month based on the percentage relative to their target.
This is the standard example from google:
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['gauge']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['Memory', 80],
['CPU', 55],
['Network', 68]
]);
var options = {
width: 400, height: 120,
redFrom: 90, redTo: 100,
yellowFrom:75, yellowTo: 90,
minorTicks: 5
};
var chart = new google.visualization.Gauge(document.getElementById('chart_div'));
chart.draw(data, options);
setInterval(function() {
data.setValue(0, 1, 40 + Math.round(60 * Math.random()));
chart.draw(data, options);
}, 13000);
setInterval(function() {
data.setValue(1, 1, 40 + Math.round(60 * Math.random()));
chart.draw(data, options);
}, 5000);
setInterval(function() {
data.setValue(2, 1, 60 + Math.round(20 * Math.random()));
chart.draw(data, options);
}, 26000);
}
</script>
</head>
<body>
<div id="chart_div" style="width: 400px; height: 120px;"></div>
</body>
</html>
So I want it to be something like this:
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['gauge']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['A1', A2],
['B1', B2],
['C1', C2]
]);
var options = {
width: 400, height: 120,
redFrom: D1, redTo: D2,
yellowFrom:D3, yellowTo: D4,
minorTicks: 5
};
Is this possible? Thanks!
if the charts will be running in an html page,
you can query the sheet using --> google.visualization.Query
following is an example, using a sample spreadsheet --> gauge data
columns A & B are used for the gauge chart data
columns D-I are for the from / to color values
the setQuery method is used to separate the two ranges into data tables
first, get the chart data, the options data, then draw the chart...
google.charts.load('current', {
packages: ['gauge']
}).then(function () {
// get chart data
var queryChart = new google.visualization.Query('https://docs.google.com/spreadsheets/d/16IeSOMvl4-B3qFr386kjZA-vSRIHTNvSIigqyracGj0/edit#gid=0');
queryChart.setQuery('select A,B');
queryChart.send(function (responseChart) {
var dataChart = responseChart.getDataTable();
// get options data
var queryOptions = new google.visualization.Query('https://docs.google.com/spreadsheets/d/16IeSOMvl4-B3qFr386kjZA-vSRIHTNvSIigqyracGj0/edit#gid=0');
queryOptions.setQuery('select D,E,F,G,H,I');
queryOptions.send(function (responseOptions) {
var dataOptions = responseOptions.getDataTable();
var options = {
minorTicks: 5
};
options.redFrom = dataOptions.getValue(0, 0);
options.redTo = dataOptions.getValue(0, 1);
options.yellowFrom = dataOptions.getValue(0, 2);
options.yellowTo = dataOptions.getValue(0, 3);
options.greenFrom = dataOptions.getValue(0, 4);
options.greenTo = dataOptions.getValue(0, 5);
var chart = new google.visualization.Gauge(document.getElementById('chart_div'))
chart.draw(dataChart, options);
});
});
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
I have a google gauge that retrieves data dynamically from a database with PHP, the problem is that I want the gauge to have a suffix in the bottom label for that I have used:
// This is what creates the problem
var formatter = new google.visualization.NumberFormat({
suffix: '%',
fractionDigits: 0
});
formatter.format(data, 1);
And this works fine until I have start to change the gauge values over time. Only the pointer moves, the label on the bottom witch says the 'value + %' keeps the same.
Anyone know how to fix this?!?
Code for the gauge:
function SOC() {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['SOC', 10]
]);
var options = {
width: 250, height: 250,
redFrom: 0, redTo: 10,
yellowFrom: 10, yellowTo: 25,
minorTicks: 5,
majorTicks: ['0','25','50','75','100']
};
var formatter = new google.visualization.NumberFormat({
suffix: '%',
fractionDigits: 0
});
formatter.format(data, 1);
var chart = new google.visualization.Gauge(document.getElementById('SOC'));
chart.draw(data, options);
setInterval(function() {
$.ajax({
url: "soc.php",
dataType: "JSON",
data:{},
success: function(x){
console.log(x["SOC"]);
data.setValue(0, 1, x["SOC"] );
chart.draw(data, options);
}
});
}, 2000);
}
Try to call formatter.format(data, 1) after updating your data:
setInterval(function() {
data.setValue(0, 1, 40 + Math.round(60 * Math.random()));
formatter.format(data, 1);
chart.draw(data, options);
}, 1000);
Check out this fiddle
I am not a javascript developer not even expert in ajax, just a no vice desktop developer , I would really appreciate if you can show me how can I connect MCU returning json data to a web page that uses google gauge running on client on local network at home.
So I have implemented a simple Arduino based web sever that returns data in below format:
{“arduino”:
[
{“location”:”outdoor”,”temperature”:”15.55″},
{“location”:”outdoor”,”humidity”:”15″}
]
}
I want to be able to show live temperature without having to refresh the whole page: I came across with google gauge example.
I have modified the example in the link below to display temperature and humidity separate gauge:
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['gauge']});
google.charts.setOnLoadCallback(drawGauge);
var gaugeOptions = {min: 0, max: 280, yellowFrom: 200, yellowTo: 250,
redFrom: 250, redTo: 280, minorTicks: 5};
var gauge;
function drawGauge() {
gaugeData = new google.visualization.DataTable();
gaugeData.addColumn('number', 'Temperature');
gaugeData.addColumn('number', 'Humidity');
gaugeData.addRows(2);
gaugeData.setCell(0, 0, 120);
gaugeData.setCell(0, 1, 80);
gauge = new google.visualization.Gauge(document.getElementById('gauge_div'));
gauge.draw(gaugeData, gaugeOptions);
}
function changeTemp(dir) {
gaugeData.setValue(0, 0, gaugeData.getValue(0, 0) + dir * 25);
gauge.draw(gaugeData, gaugeOptions);
}
function changeHumid(dir) {
gaugeData.setValue(0, 1, gaugeData.getValue(0, 1) + dir * 20);
gauge.draw(gaugeData, gaugeOptions);
}
</script>
</head>
<body>
<div id="gauge_div" style="width:280px; height: 140px;"></div>
<small>Change</small>
<input type="button" value="Temperature" onclick="changeTemp(1)" />
<input type="button" value="Humidity" onclick="changeHumid(1)" />
</body>
</html>
Now I want the change temperate and change Humidity functions should execute after 5 sec displaying latest data from the json returned by executing the MCU bee server URL ? How can I implement that ?
Well, I figured it out, after lots of digging, I finally have something working before I finish my vacation.
below code works and displays the latest value in my google gauge and it refreshes after every 15 seconds, same principle I can apply on json data I have put as sample in the Opening post.
<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'></script>
<script type='text/javascript' src='https://www.google.com/jsapi'></script>
<script type='text/javascript'>
// set your channel id here
var channel_id = 166617;
// set your channel's read api key here if necessary
var api_key = 'ZCUB611J8M8ELM9M';
// maximum value for the gauge
var max_gauge_value = 70;
// name of the gauge
var gauge_name = 'Temperature';
// global variables
var chart, charts, data;
var public_key = 'dZ4EVmE8yGCRGx5XRX1W';
// load the google gauge visualization
google.load('visualization', '1', {packages:['gauge']});
google.setOnLoadCallback(initChart);
// display the data
function displayData(point) {
data.setValue(0, 0, gauge_name);
data.setValue(0, 1, point);
chart.draw(data, options);
}
// load the data
function loadData() {
// variable for the data point
var p;
// JSONP request
var jsonData = $.ajax({
url: 'https://data.sparkfun.com/output/' + public_key + '.json',
data: {page: 1},
dataType: 'jsonp',
}).done(function (results){
// get the data last value
p = results[results.length - 1].tempf;
// if there is a data point display it
if (p) {
displayData(p);
}
});
}
// initialize the chart
function initChart() {
data = new google.visualization.DataTable();
data.addColumn('string', 'Label');
data.addColumn('number', 'Value');
data.addRows(1);
chart = new google.visualization.Gauge(document.getElementById('gauge_div'));
options = {width: 120, height: 120, greenFrom: 10, greenTo: 29, redFrom: 41, redTo: 70, yellowFrom:30, yellowTo: 40, minorTicks: 5};
loadData();
// load new data every 15 seconds
setInterval('loadData()', 15000);
}
</script>
In order to retreive temperature and humidity, you can do (using jquery):
function repeat() {
$.get( "YOUR_WEB_SERVER_JSON_URL", function( data ) {
gaugeData.setValue(0, 0, data.arduino[0].temperature);
gaugeData.setValue(0, 1, data.arduino[1].humidity);
gauge.draw(gaugeData, gaugeOptions);
setTimeout(repeat, 5000);
});
I've set up a simple example for you, check it out here.
I created a sample fiddle for you:
google.charts.load('current', {
'packages': ['gauge']
});
google.charts.setOnLoadCallback(drawGauge);
var gaugeOptions = {
min: 0,
max: 280,
yellowFrom: 200,
yellowTo: 250,
redFrom: 250,
redTo: 280,
minorTicks: 5
};
var gauge;
var gaugeData;
function drawGauge() {
gaugeData = new google.visualization.DataTable();
gaugeData.addColumn('number', 'Temperature');
gaugeData.addColumn('number', 'Humidity');
gaugeData.addRows(2);
gaugeData.setCell(0, 0, 120);
gaugeData.setCell(0, 1, 80);
gauge = new google.visualization.Gauge(document.getElementById('gauge_div'));
gauge.draw(gaugeData, gaugeOptions);
repeat();
}
function repeat() {
var dir = Math.floor((Math.random() * 10) + 1);
gaugeData.setValue(0, 0, dir * 25);
gaugeData.setValue(0, 1, dir * 20);
gauge.draw(gaugeData, gaugeOptions);
setTimeout(repeat, 5000);
}
Repeat function is going to be executed every 5 seconds. In a sample fiddle it gets some random number from 1 to 10 and updates charts with this value multiplied by 25 and 20. In your scenario, you should make a call to your web server, parse the response, get values for temperature and humidity and update the charts. Please let me know if you need help on this too.
Is there any plugin who give's the chart type = ODOMETER ?
incrideble how is so hard to find this, even highchart's that i'm using ( very good chart library ) dont have a odometer, dont know why.
i found some "speedometer", Demo but wont help-me.
anyone know any plugin or something like who work with odometer's ?
Thanks.
Google Charts
Super easy to use and well documented.
google.charts.load('current', {'packages':['gauge']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Label', 'Value'],
['Memory', 80],
['CPU', 55],
['Network', 68]
]);
var options = {
width: 400, height: 120,
redFrom: 90, redTo: 100,
yellowFrom:75, yellowTo: 90,
minorTicks: 5
};
var chart = new google.visualization.Gauge(document.getElementById('chart_div'));
chart.draw(data, options);
setInterval(function() {
data.setValue(0, 1, 40 + Math.round(60 * Math.random()));
chart.draw(data, options);
}, 13000);
setInterval(function() {
data.setValue(1, 1, 40 + Math.round(60 * Math.random()));
chart.draw(data, options);
}, 5000);
setInterval(function() {
data.setValue(2, 1, 60 + Math.round(20 * Math.random()));
chart.draw(data, options);
}, 26000);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div" style="width: 400px; height: 120px;"></div>
Let this question up-to-date. New features from highcharts, i was looking for this, and now they have available:
Highcharts gauge-speedometer
Javascript speedometer plugin is available.
https://github.com/rmanivannan/speedometer-jquery-plugin
may be this could help