Loading
Creating Real-time Angluar Gauge
The angular gauge is a real-time chart, which can continuously request new data from the server and display the same, without involving any page refreshes. The chart initializes itself, loads new data periodically and auto-updates to reflect the current state of data. There are two different ways to update the angular gauge; one method directly polls data from the server while the other retrieves data using JavaScript API methods.
In this section, you will learn how to:
-
Understand and use the various methods available for data streaming
-
Build an example of a real-time gauge that can stream data from an URL
Understanding Data Streaming and the Various Methods for Data Streaming
When you use the real-time data format you need to create a data provider (primarily a server side script) at your server. Next, need to specify the URL of this data provider and the time interval (in seconds) after which the gauge will look for new data. The data provider must then output the new data in the real-time data format.
Real-time Data Format
The real-time data format for the angular gauge depends on:
-
Whether you’ve multiple dials on the chart or a single dial?
-
If you’ve multiple pointers, whether you want to provide data by pointer numerical index or by their defined IDs?
-
Commands for the chart - like stop update
Simple Example
Updating a Single Pointer
In the simplest form, if you’re looking to update the value of a gauge, you need to output the data in following format:
Here, the output is a single value, 34. So, when the gauge will read this value, it will update itself by setting its value to 34 (if a data range is provided by the gauge, the value will first be checked to verify if it falls within the defined range).
Updating Multiple Pointers
If you have multiple dials defined, you can update them all in a single update as shown in the following output from the real-time data provider page:
Here, we’re specifying three values in the real-time update. So, assuming that we’ve 3 dials or pointers defined in the chart, each one of them will take the values in sequence and update itself. Therefore, the first dial will now show 34, second one will show 25, and the third one will show 54. The sequence of dials is determined by the order in which they are defined in the JSON/XML data.
Updating using Named ID of the Dial/Pointer
Another way to update dials is by defining a unique ID for each dial and then passing the updated value to the ID.
To define an ID for each dial, you can use the code snippet shown below:
You can now update each of these named dials as shown in the following output in your real-time data stream:
This will change the value of dial 1 (with id as CPU1Temp
) to 23 and dial 2 to 34.
Stopping Real-time Updates from the Server
If you wish to stop the gauge from polling the server for any more real-time updates, you can send the following command from server to do so:
After stopping the update, it can be restarted again by using client-side JavaScript.
Building an Example of a Real-time Gauge that streams data from an URL
A real-time angular gauge configured to stream data from an URL looks like this:
{
"chart": {
"caption": "Server CPU Utilization",
"subcaption": "food.hsm.com & cloth.hsm.com",
"lowerLimit": "0",
"upperLimit": "100",
"numberSuffix": "%",
"dataStreamUrl": "http://static.fusioncharts.com/sampledata/php/serverLoad.php",
"refreshInterval": "10",
"theme": "fint"
},
"colorRange": {
"color": [
{
"minValue": "0",
"maxValue": "35",
"label": "Low",
"code": "#1aaf5d"
},
{
"minValue": "35",
"maxValue": "70",
"label": "Moderate",
"code": "#f2c500"
},
{
"minValue": "70",
"maxValue": "100",
"label": "High",
"code": "#c02d00"
}
]
},
"dials": {
"dial": [
{
"id": "fd_dial",
"value": "72.5",
"tooltext": "food.hsm.com : $value"
},
{
"id": "clth_dial",
"value": "64.8",
"alpha": "40",
"tooltext": "cloth.hsm.com : $value"
}
]
}
}
<html>
<head>
<title>My first chart using FusionCharts Suite XT</title>
<script type="text/javascript" src="http://static.fusioncharts.com/code/latest/fusioncharts.js"></script>
<script type="text/javascript" src="http://static.fusioncharts.com/code/latest/themes/fusioncharts.theme.fint.js?cacheBust=56"></script>
<script type="text/javascript">
FusionCharts.ready(function(){
var fusioncharts = new FusionCharts({
type: 'angulargauge',
renderAt: 'chart-container',
id: 'cs-angular-gauge',
width: '400',
height: '300',
dataFormat: 'json',
dataSource: {
"chart": {
"caption": "Server CPU Utilization",
"subcaption": "food.hsm.com & cloth.hsm.com",
"lowerLimit": "0",
"upperLimit": "100",
"numberSuffix": "%",
"dataStreamUrl": "http://static.fusioncharts.com/sampledata/php/serverLoad.php",
"refreshInterval": "10",
"theme": "fint"
},
"colorRange": {
"color": [{
"minValue": "0",
"maxValue": "35",
"label": "Low",
"code": "#1aaf5d"
}, {
"minValue": "35",
"maxValue": "70",
"label": "Moderate",
"code": "#f2c500"
}, {
"minValue": "70",
"maxValue": "100",
"label": "High",
"code": "#c02d00"
}]
},
"dials": {
"dial": [{
"id": "fd_dial",
"value": "72.5",
"tooltext": "food.hsm.com : $value"
}, {
"id": "clth_dial",
"value": "64.8",
"alpha": "40",
"tooltext": "cloth.hsm.com : $value"
}]
}
}
}
);
fusioncharts.render();
});
</script>
</head>
<body>
<div id="chart-container">FusionCharts XT will load here!</div>
</body>
</html>
In the above gauge, observe that both the dials update themselves every 10 seconds.
Given below is a brief description of the attributes used to configure real-time updates from an URL:
Attribute Name | Description | ||
---|---|---|---|
|
This parameter sets the path of the page which is supposed to relay real-time data to the chart. If you have special characters as a part of your data stream URL, like ? or &, you will have to URL Encode the entire |
||
|
For this parameter, we can specify the number of seconds after which the chart will look for new data. This process will happen continuously - i.e., if we specify 5 seconds here, the chart will look for new data every 5 seconds. |
||
|
|
In the above data, note that we have set the dataStreamURL
attribute to http://static.fusioncharts.com/sampledata/php/serverLoad.php and the refreshInterval
attribute to 10
. Which means that after every 10 seconds the chart will fetch data from the URL and update the two dials.
For example, the serverLoad.php
data provider will return two random values within 100% in the format shown below:
Because we have defined unique IDs for both dials, It can also return data in the format shown below:
The data provider page needs to be on the same sub-domain on which the chart is hosted and invoked from. Otherwise, the cross-domain security might restrict data access and hence the real-time feature won’t work.
Using the JavaScript API to Update the Gauge
The FusionCharts JavaScript Class provides a rich and powerful API collection that eases the implementation and management of charts using its powerful functions, properties, and events, because of the highly enhanced JavaScript architecture that it uses.
A real-time angular gauge configured to use JavaScript API for real-time updates looks like this:
{
"chart": {
"caption": "Speedometer",
"captionFont": "Arial",
"captionFontColor": "#333333",
"manageresize": "1",
"origw": "320",
"origh": "320",
"tickvaluedistance": "-10",
"bgcolor": "#FFFFFF",
"upperlimit": "240",
"lowerlimit": "0",
"basefontcolor": "#FFFFFF",
"majortmnumber": "9",
"majortmcolor": "#FFFFFF",
"majortmheight": "8",
"majortmthickness": "5",
"minortmnumber": "5",
"minortmcolor": "#FFFFFF",
"minortmheight": "3",
"minortmthickness": "2",
"pivotradius": "10",
"pivotbgcolor": "#000000",
"pivotbordercolor": "#FFFFFF",
"pivotborderthickness": "2",
"tooltipbordercolor": "#FFFFFF",
"tooltipbgcolor": "#333333",
"gaugeouterradius": "115",
"gaugestartangle": "240",
"gaugeendangle": "-60",
"decimals": "0",
"placevaluesinside": "1",
"pivotfillmix": "",
"showpivotborder": "1",
"annrenderdelay": "0",
"gaugeoriginx": "160",
"gaugeoriginy": "160",
"showborder": "0"
},
"dials": {
"dial": [
{
"value": "65",
"bgcolor": "000000",
"bordercolor": "#FFFFFF",
"borderalpha": "100",
"basewidth": "4",
"topwidth": "4",
"borderthickness": "2",
"valuey": "260"
}
]
},
"annotations": {
"groups": [
{
"x": "160",
"y": "160",
"items": [
{
"type": "circle",
"radius": "130",
"fillasgradient": "1",
"fillcolor": "#4B4B4B,#AAAAAA",
"fillalpha": "100,100",
"fillratio": "95,5"
},
{
"type": "circle",
"x": "0",
"y": "0",
"radius": "120",
"showborder": "1",
"bordercolor": "cccccc",
"fillasgradient": "1",
"fillcolor": "#ffffff,#000000",
"fillalpha": "50,100",
"fillratio": "1,99"
}
]
},
{
"x": "160",
"y": "160",
"showbelow": "0",
"scaletext": "1",
"items": [
{
"type": "text",
"y": "100",
"label": "KPH",
"fontcolor": "#FFFFFF",
"fontsize": "14",
"bold": "1"
}
]
}
]
}
}
<html>
<head>
<title>My first chart using FusionCharts Suite XT</title>
<script type="text/javascript" src="http://static.fusioncharts.com/code/latest/fusioncharts.js"></script>
<script type="text/javascript" src="http://static.fusioncharts.com/code/latest/themes/fusioncharts.theme.fint.js?cacheBust=56"></script>
<script type="text/javascript">
FusionCharts.ready(function(){
var fusioncharts = new FusionCharts({
type: 'angulargauge',
id: "myGauge",
renderAt: 'chart-container',
width: '400',
height: '300',
dataFormat: 'json',
dataSource: {
"chart": {
"caption": "Speedometer",
"captionFont": "Arial",
"captionFontColor": "#333333",
"manageresize": "1",
"origw": "320",
"origh": "320",
"tickvaluedistance": "-10",
"bgcolor": "#FFFFFF",
"upperlimit": "240",
"lowerlimit": "0",
"basefontcolor": "#FFFFFF",
"majortmnumber": "9",
"majortmcolor": "#FFFFFF",
"majortmheight": "8",
"majortmthickness": "5",
"minortmnumber": "5",
"minortmcolor": "#FFFFFF",
"minortmheight": "3",
"minortmthickness": "2",
"pivotradius": "10",
"pivotbgcolor": "#000000",
"pivotbordercolor": "#FFFFFF",
"pivotborderthickness": "2",
"tooltipbordercolor": "#FFFFFF",
"tooltipbgcolor": "#333333",
"gaugeouterradius": "115",
"gaugestartangle": "240",
"gaugeendangle": "-60",
"decimals": "0",
"placevaluesinside": "1",
"pivotfillmix": "",
"showpivotborder": "1",
"annrenderdelay": "0",
"gaugeoriginx": "160",
"gaugeoriginy": "160",
"showborder": "0"
},
"dials": {
"dial": [{
"value": "65",
"bgcolor": "000000",
"bordercolor": "#FFFFFF",
"borderalpha": "100",
"basewidth": "4",
"topwidth": "4",
"borderthickness": "2",
"valuey": "260"
}]
},
"annotations": {
"groups": [{
"x": "160",
"y": "160",
"items": [{
"type": "circle",
"radius": "130",
"fillasgradient": "1",
"fillcolor": "#4B4B4B,#AAAAAA",
"fillalpha": "100,100",
"fillratio": "95,5"
}, {
"type": "circle",
"x": "0",
"y": "0",
"radius": "120",
"showborder": "1",
"bordercolor": "cccccc",
"fillasgradient": "1",
"fillcolor": "#ffffff,#000000",
"fillalpha": "50,100",
"fillratio": "1,99"
}]
}, {
"x": "160",
"y": "160",
"showbelow": "0",
"scaletext": "1",
"items": [{
"type": "text",
"y": "100",
"label": "KPH",
"fontcolor": "#FFFFFF",
"fontsize": "14",
"bold": "1"
}]
}]
}
},
"events": {
"initialized": function(evtObj, argObj) {
var scoreArray = [],
score,
speedScore,
flag,
diff;
evtObj.sender.resetInterval = setInterval(function() {
var i,
percent,
num = 30;
score = 40 +
parseInt(Math.floor(Math.random() * 170));
if (!speedScore) {
speedScore = score;
}
diff = (score - speedScore);
for (i = 0; i < 5; i++) {
percent = num - (i * 5);
scoreArray[i] = diff * (percent / 100);
}
flag = 0;
}, 1000);
evtObj.sender.changeInterval = setInterval(function() {
if (speedScore && diff) {
speedScore += scoreArray[flag];
flag += 1;
FusionCharts.items["myGauge"].feedData("value=" + speedScore);
}
}, 2000);
},
"disposed": function(evtObj, argObj) {
clearInterval(evtObj.sender.resetInterval);
clearInterval(evtObj.sender.changeInterval);
}
}
}
);
fusioncharts.render();
});
</script>
</head>
<body>
<div id="chart-container">FusionCharts XT will load here!</div>
</body>
</html>
Given below is a brief description of the JavaScript API methods used to configure the real-time angular gauge to receive real-time updates:
Attribute Name | Description |
---|---|
|
It is used to feed real-time data to the gauge using JavaScript. The data has to be in the same format as that provided by the real-time data provider page. |
|
It is used to get the data for a given dial index on the gauge. The first dial is represented by index 1, the second by 2, and so on. |
|
It is used to get the data for a given dial using its defined ID. |
|
It is used to set data for a given dial index on the chart. The first dial is represented by index 1, the second by 2, and so on. |
|
It is used to set data for a given dial using its defined ID. |
|
It is used to stop the gauge from self-updating. |
|
It is used to resume self-update of the gauge, if you have stopped it. |
Configuring Events associated with Real-time Updates
FusionCharts Suite XT introduces two events, realTimeUpdateComplete
and realTimeUpdateError
, to track real-time updates on gauges.
A real-time angular gauge configured to listen to the realTimeUpdateComplete
event looks like this:
{
"chart": {
"caption": "Server CPU Utilization",
"subcaption": "forum.hsm.com",
"lowerLimit": "0",
"upperLimit": "100",
"editMode": "1",
"showValue": "1",
"valueBelowPivot": "1",
"tickValueDistance": "25",
"gaugeFillMix": "{dark-30},{light-60},{dark-10}",
"gaugeFillRatio": "15",
"theme": "fint",
"valueFontSize": "14"
},
"colorRange": {
"color": [
{
"minValue": "0",
"maxValue": "50",
"code": "#6baa01"
},
{
"minValue": "50",
"maxValue": "75",
"code": "#f8bd19"
},
{
"minValue": "75",
"maxValue": "100",
"code": "#e44a00"
}
]
},
"dials": {
"dial": [
{
"id": "crntYr",
"value": "78",
"showValue": "1",
"tooltext": "Current year's average : $value",
"rearExtension": "5"
}
]
}
}
<html>
<head>
<title>My first chart using FusionCharts Suite XT</title>
<script type="text/javascript" src="http://static.fusioncharts.com/code/latest/fusioncharts.js"></script>
<script type="text/javascript" src="http://static.fusioncharts.com/code/latest/themes/fusioncharts.theme.fint.js?cacheBust=56"></script>
<script type="text/javascript">
FusionCharts.ready(function(){
var fusioncharts = new FusionCharts({
type: 'angulargauge',
renderAt: 'chart-container',
width: '400',
height: '300',
dataFormat: 'json',
dataSource: {
"chart": {
"caption": "Server CPU Utilization",
"subcaption": "forum.hsm.com",
"lowerLimit": "0",
"upperLimit": "100",
"editMode": "1",
"showValue": "1",
"valueBelowPivot": "1",
"tickValueDistance": "25",
"gaugeFillMix": "{dark-30},{light-60},{dark-10}",
"gaugeFillRatio": "15",
"theme": "fint",
"valueFontSize": "14"
},
"colorRange": {
"color": [{
"minValue": "0",
"maxValue": "50",
"code": "#6baa01"
}, {
"minValue": "50",
"maxValue": "75",
"code": "#f8bd19"
}, {
"minValue": "75",
"maxValue": "100",
"code": "#e44a00"
}]
},
"dials": {
"dial": [{
"id": "crntYr",
"value": "78",
"showValue": "1",
"tooltext": "Current year's average : $value",
"rearExtension": "5"
}]
}
},
events: {
'beforeRender': function(evt, args) {
var score = document.createElement('div');
score.setAttribute('id', 'score-detail');
score.innerHTML = 'Current server CPU Utilization is: <b>78</b>';
score.style.cssText = "font-family:'Helvetica Neue', Arial; font-size: 14px; padding:10px 0 10px 20px;";
args.container.parentNode.insertBefore(score, args.container.nextSibling);
},
"rendered": function(evtObj, argObj) {
evtObj.sender.intervalVar = setInterval(function() {
var chartIns = evtObj.sender,
prcnt = 65 + parseInt(Math.floor(Math.random() * 10), 10);
chartIns.feedData("value=" + prcnt);
}, 5000);
},
"realtimeUpdateComplete": function(evtObj, argObj) {
var updtObj = argObj && argObj.updateObject,
values = updtObj && updtObj.values,
updtValStr = values && values[0],
updtVal = updtValStr &&
parseFloat(updtValStr).toFixed(0),
divToUpdate = document.getElementById("score-detail");
divToUpdate.innerHTML = "Current server CPU Utilization is : <b>" + updtVal + "</b>";
},
"disposed": function(evtObj, argObj) {
clearInterval(evtObj.sender.intervalVar);
}
}
}
);
fusioncharts.render();
});
</script>
</head>
<body>
<div id="chart-container">FusionCharts XT will load here!</div>
</body>
</html>
Given below is a brief description of the realTimeUpdateComplete
and the realTimeUpdateError
events:
Event Name | Description |
---|---|
|
This event is raised every time the real-time gauge updates itself with new data. This event is raised in any of the following cases: |
|
This event is raised when an error occurs while performing real-time update using |
Troubleshooting
If the chart renders initially, but does not update in real-time, do the following:
-
Check if you have specified a correct and valid path for the
dataStreamURL
attribute in the JSON/ XML data.. -
Check if you have specified a valid value for the
refreshInterval
attribute in the data. -
Check if the
dataStreamURL
attribute is returning the correct data. To test this, just open your browser and run this page. It should return the data in text format. -
Make sure the output data does not contain any carriage returns (new-line characters) or HTML elements. In many scripting languages, these are automatically added. If they are, you will need to remove them.
-
You also need to make sure that the page which provides the incremental data update to the charts must be hosted on the same sub-domain in which the charts are hosted - otherwise, owing to security restrictions, the charts won’t be able to receive the updates. Due to security restrictions, charts are allowed to retrieve data only from the same sub-domain in which the charts are residing. Data can only be loaded from a domain that is an exact match to the location of the charts, including sub-domains. For this reason, a chart residing at
server1.mydomain.com
will not be able to access data frommydomain.com
.
If you wish to load data from a different domain, you can set up a proxy page at the same sub-domain that will actually request data from the distant domain and then relay it to the charts. You must be able to upload and run a server-side script on a server in the same domain as the charts. In this method, a chart accesses the script, which loads the information, retrieves it and returns the information back to the chart. This method is best feasible if the server hosting the data is not under your control (for example, a public source or a web service).
While accessing any of the JavaScript API methods listed above, if you get an error like "... is not a function of ..."
,
-
Make sure you are not calling the JavaScript API method before the chart has loaded and rendered. You need to use an event listener for the
rendered
event of the gauge to track the loading of the gauge. -
Make sure that you have provided all the required
.js
files of the FusionCharts library and no other JavaScript error is encountered.