In this recipe, we will be creating a really fun gauge meter and injecting some random animation into it to make it look like a real source of live data is connected to it, such as the speed of a car:
To get started you will need to use jQuery and jqPlot. This time around we will start from scratch.
To get the latest scripts, visit the creator site at http://blog.everythingfla.com/?p=339.
Download both jQuery and jqPlot, or download our source files to start with.
Let's list the steps required to complete the task:
<!DOCTYPE html> <html> <head> <title>JQPlot Meter</title> <meta charset="utf-8" /> <link rel="stylesheet" href="./external/jqplot/jquery.jqplot.min.css"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script src="./external/jqplot/jquery.jqplot.js"></script> <script src="./external/jqplot/plugins/jqplot.meterGaugeRenderer.min.js"></script> <script src="./07.01.jqplot-meter.js"></script> </head> <body style="background:#fafafa"> <div id="meter" style="height:400px;width:400px; "></div> </body> </html>
07.01.jqplot-meter.js
file.var meter; var meterValue=0; var startingSpeed = parseInt(Math.random()*60) + 30; var isStarting = true; var renderOptions= { label: 'Miles Per Hour', labelPosition: 'bottom', labelHeightAdjust: -10, intervalOuterRadius: 45, ticks: [0, 40, 80, 120], intervals:[25, 90, 120], intervalColors:[ '#E7E658','#66cc66', '#cc6666'] };
$(document).ready(function(){ meter = $.jqplot('meter',[[meterValue]],{ seriesDefaults: { renderer: $.jqplot.MeterGaugeRenderer, rendererOptions:renderOptions } }); });
ready
listener interval (it will run from now on until the end of the recipe):$(document).ready(function(){ meter = $.jqplot('meter',[[meterValue]],{ seriesDefaults: { renderer: $.jqplot.MeterGaugeRenderer, rendererOptions:renderOptions } }); setInterval(updateMeter,30); });
updateMeter
function:function updateMeter(){ meter.destroy(); if(isStarting && meterValue<startingSpeed){ ++meterValue }else{ meterValue += 1- Math.random()*2; meterValue = Math.max(0,Math.min(meterValue,120)); //keep our value in range no mater what } meter = $.jqplot('meter',[[meterValue]],{ seriesDefaults: { renderer: $.jqplot.MeterGaugeRenderer, rendererOptions:renderOptions } }); }
Well done. Refresh your browser and you will find an animated speedometer that looks like that of a car driving around (if you only imagine it).
This task was really easy as we didn't need to start everything from scratch. For the meter to run, we need to import the library meterGaugeRenderer
. We do that by adding that into our JavaScript files that we are loading. But let's focus on our code. The first step in our JavaScript is to prepare a few global variables; we are using global variables as we want to re-use these variables in two different functions (when we are ready to reset our data).
var meter; var meterValue=0; var startingSpeed = parseInt(Math.random()*60) + 30; var isStarting = true;
The meter
variable will hold the meter that we will generate from our open source library. The meterValue
will be our initial value when the application loads. Our startingSpeed
variable is going to be a random value between 30
and 90
. The goal is to start from a different place each time to make it more interesting. As soon as our application starts, we will want our meter to quickly animate to its new base speed (the startingSpeed
variable). Lastly, this connects to the isStarting
variable as we will want to have one animation that will get us to our base speed. When we get there, we want to switch to a random driving speed that would cause the animation to change. Now that we have all the helper variables set, we are ready to create the renderOptions
object:
var renderOptions= { label: 'Miles Per Hour', labelPosition: 'bottom', labelHeightAdjust: -10, intervalOuterRadius: 45, ticks: [0, 40, 80, 120], intervals:[25, 90, 120], intervalColors:[ '#E7E658','#66cc66', '#cc6666'] };
This object is really the heart of the visuals for our application. (There are other options that you are welcome to explore in the jqPlot project home page documentation.) Now let's review a few of the key parameters.
intervalOuterRadius
has a bit of a tricky name, but it's actually the internal radius. The actual size of our meter is controlled by the size of div
that we set our application to be in. intervalOuterRadius
controls the size of our internal shape in the speedometer's core.
var renderOptions= { label: 'Miles Per Hour', labelPosition: 'bottom', labelHeightAdjust: -10, intervalOuterRadius: 45, //ticks: [0, 40, 80, 120], intervals:[10,25, 90, 120], intervalColors:['#999999', '#E7E658','#66cc66', '#cc6666'] };
The ticks
function controls where the copy outlines would be. The default would take our top range and divide it by 4 (that is 30, 60, 90, and 120). The intervals
and intervalColors
functions let the meter know the ranges and the inner, internal, pie colors (separated from the ticks).
$(document).ready(function(){ meter = $.jqplot('meter',[[meterValue]],{ seriesDefaults: { renderer: $.jqplot.MeterGaugeRenderer, rendererOptions:renderOptions } }); setInterval(updateMeter,30); });
To create a new chart using the jqPlot library, we always call the $.jqplot
function. The first parameter of the function is the div
layer, which is where our work will live. The second parameter is a two-dimensional array containing the data of the chart (kind of looks odd for this example as it expects a 2D array and as our sample only includes one data entry at a time, we need to wrap it in two arrays). The third parameter defines the used renderer and rendererOptions
(that we created earlier).
Let's explore a few more functions.
The updateMeter
function gets called every 30 milliseconds. What we need to do is start by clearing our art every time that it is called:
meter.destroy();
This will clear everything related to our meter so we can recreate it.
If we are still in the intro part of our application where we want our speed to go up to the goal speed, we need to update our meterValue
by 1
.
if(isStarting && meterValue<startingSpeed){ ++meterValue; }
If we are already passed this state and want our meter to go up and down randomly, making it look like variations in driving speed, we'll use the following code snippet:
}else{ meterValue += 1- Math.random()*2; meterValue = Math.max(0,Math.min(meterValue,120)); //keep our value in range no mater what }
We are randomly adding a value between -1
and 1
to our meter value. A correction to our result can be achieved by keeping our value not lower than 0
and not higher than 120
, followed by redrawing our meter with our new meterValue
value.
18.221.208.183