We start thinking about the bar chart we made that showed various product categories and a trend line for a chosen category. We send off another e-mail to IT to see whether they can compile the data into a JSON feed. A few minutes later, we get a reply stating that Roshan has asked for the same thing. They are still trying to get everything working, but in the interim, they created a mock JSON feed. They also sent along the URL.
We load the JSON feed in our browser. They moved all the category data into an object called categories
. They also created an object called labels
to hold the ticks for our chart:
{ "categories": { "TVs": [378583.39, 346552.99, 368164.98, 371856.60, 366457.82, 327396.58], "Computers": [563621.35, 540214.96, 589978.66, 637114.31, 621279.49, 599837.31], "DVDs/Blu-ray": [546643.33, 517902.14, 482774.32, 455892.62, 438679.00, 406907.18], "Music CDs": [398583.39, 386552.99, 372738.46, 359209.91, 336457.82, 327396.58] }, "labels": ["Q2 - 2011", "Q3 - 2011", "Q4 - 2011", "Q1 - 2012", "Q2 - 2012", "Q3 - 2012"] }
With the data sorted, we move on to updating the chart. To do this, we perform the following steps:
categoryAxisRenderer
plugin file along with the barRenderer
, trendline
, and canvas
plugin files, as follows:<script src="../js/jqplot.categoryAxisRenderer.min.js"></script> <script src="../js/jqplot.barRenderer.min.js"></script> <script src="../js/jqplot.canvasTextRenderer.min.js"></script> <script src="../js/jqplot.canvasAxisTickRenderer.min.js"></script> <script src="../js/jqplot.trendline.min.js"></script> <script src="../js/functions.js"></script>
series
objects we will create. We also create an array to hold our ticks. To build our series
objects and the tick
objects, we need to create a few helper functions. We start by creating a function called createSeries
. We pass in the name of the category and the index of the category in our drop-down menu to select trend lines, as follows:<script> $(document).ready(function(){ var dataSeriesObj = new Array; var ticks = new Array; function createSeries(name, index) {
label
and trendline
options. To generate the trendline
option, we will call createTrendObj
, where we pass in the name
and index
parameters. Once this object is created, we return the entire series
object, as shown in the following code snippet:var series = { label: name, trendline: createTrendObj(name, index) }; return series; }
createTrendObj
. We create a variable to hold the trendline
options. We set the show
option to false
by default. Then, we set the label
option to include the category name, which is passed into the function as follows:function createTrendObj(name, index) { var trendLineObj = { show: false, label: 'Trend: ' + name };
index
matches the value of our drop-down menu. We also add a condition check that will show the trend line for the first category when the page is first loaded. Once the object is created, we return the object as follows:if (index == $("#trendline").val() || $("#trendline").val() == null) { trendLineObj.show = true; } return trendLineObj ; }
dataPull
function. It will make use of the two functions we just created. We create a local variable to hold each data series. Next, we set remoteData.categories
in a new variable called categories
, so it will be easier to work with the objects inside our loop. As we did with other JSON objects, we loop through each object. We set the next element in data
to the data array for the given object, as follows:function dataPull(remoteData,options) { var data = new Array(); var i = 0; var categories = remoteData.categories; for (var name in categories) { if (categories.hasOwnProperty(name)) { data[i] = categories[name];
createSeries
and store the resulting object in the next element of dataSeriesObj
. The last thing in our loop through the categories is to create an option
tag for our drop-down menu, as follows:dataSeriesObj[i] = createSeries(name,i); $("#trendline").append($("<option></option>").attr("value",i).text(name)); i++; } }
remoteData.labels
. With all of this data generated, we return the data points to jqPlot, as follows:ticks = remoteData.labels; return data; }
dataPull
function will pull all data and create dataSeriesObj
and ticks
. We set these options in our replot
method, and the chart will reload as follows:function refreshChart() { rev_category.replot( { series: dataSeriesObj, axes: { xaxis: { ticks: ticks } } }); }
dataRenderer
and dataRendererOptions
, as follows:var rev_category = $.jqplot ('rev_category', './data/quarterly_revenue.json', { title:'Quarterly Revenue by Product Category', dataRenderer: remoteDataCallback, dataRendererOptions: { dataCallback: dataPull }, axesDefaults: { tickRenderer: $.jqplot.CanvasAxisTickRenderer, tickOptions: { angle: -30 } },
seriesDefaults
and legend
options as they were before:seriesDefaults:{ renderer:$.jqplot.BarRenderer, rendererOptions: { barMargin: 2, barPadding: 2, shadowAlpha: 0.0 }, trendline: { color: '#111111', lineWidth: 4 } }, legend: { show: true, placement: 'outside', location: 'ne' },
ticks
option. If we load our chart as is, the ticks
option will not appear. That is because jqPlot builds the chart before passing in the remote data:series: dataSeriesObj, axes:{ xaxis:{ label: 'Quarters', renderer: $.jqplot.CategoryAxisRenderer, ticks: ticks }, yaxis: { label: 'Total in Dollars', padMax: 1, tickOptions: { formatString: "$%'d" } } } });
refreshChart
method which will run the replot
method and update the chart ticks with the newly created array of ticks:refreshChart();
dataSeriesObj
. We call the createTrendObj
function and reset the options for each trendline
object. When we are done looping through the data series, we call refreshChart
to reload the chart. This can be implemented as follows:$("#trendline").change(function() { for(var x=0;x < dataSeriesObj.length; x++){ dataSeriesObj[x].trendline = createTrendObj(dataSeriesObj[x].label, x); } refreshChart(); }); }); </script>
option
tags from the drop-down menu because they will be generated dynamically:<select id="trendline" name="trendline"></select> <div id="rev_category" style="width:500px;"></div>
Finally, we load the chart in our browser; the result is shown in the following screenshot:
The advantage of our new chart is that in the next quarter, the new data will be loaded without us having to change the chart. Also, if in 2 months they decide to add new product categories to the JSON feed, they will appear without any changes on our part. If they add too many, however, the chart may become unusable, and we will have to evaluate different options to display the new data.
We select DVDs/Blu-ray, and the chart reloads without refreshing the page. The trend line for TVs is turned off, and it is enabled for DVDs/Blu-ray, as shown in the following screenshot:
It's getting close to 4 o'clock. We begin to wrap up our charts and take care of e-mails and phone calls. About 15 minutes later, Roshan and Calvin stop by. Roshan tells us that Jeff mentioned the chart we created for him. We show it to him and Calvin. Roshan comments on the chart. "This is really nice. We'll have to think through how to best use this to increase sales in-store. This is beside the point, but this is a good first step. I also heard you two were thinking in the same vein as I was to get live data for several of these charts."
We show him the updated product category chart and the updated stock chart. "These are really nice. These are actually two of the charts we discussed in our meeting earlier. The team is going to want some of these on the dashboard when we go live. It's late in the day, but I wanted to stop by and schedule a meeting for Monday. We have the charts and the data. Now, we need to make it all beautiful and fit together in a cohesive way."
Calvin speaks up, "We'll see you two on Monday. Have a good weekend." Calvin and Roshan turn and leave. We finish the few last e-mails, and then head out ourselves.
3.15.144.56