Dynamically building our chart when the page loads

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:

  1. We start by including the 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>
  2. We declare an array to hold all the 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) {
  3. Next, we create a variable to hold an object with the 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;
      }
  4. Our next function is 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 };
  5. Next, we check whether 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 ;
      }
  6. With the functions complete, we revisit our 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];
  7. Then, we call 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++;
          }
        }
  8. Once we are done with the loop, we set our previously declared variable ticks to remoteData.labels. With all of this data generated, we return the data points to jqPlot, as follows:
        ticks = remoteData.labels;
        return data;
      }
  9. With our remote data function complete, we create a function to be called each time we change the drop-down menu. Our 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 } }
        });
      }
  10. Now we begin building our chart. We pass in the JSON URL to jqPlot. We pass in our functions for 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 }
        },
  11. We leave the 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' },
  12. We need to pass in an array of objects to series. We also need to pass an array to the 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" }
          }
        }
      });
  13. With our chart complete, we call the refreshChart method which will run the replot method and update the chart ticks with the newly created array of ticks:
      refreshChart();
  14. We change the entire event handler for the drop-down menu. We start by looping through 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>
  15. We remove all the 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:

Dynamically building our chart when the page loads

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:

Dynamically building our chart when the page loads

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.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.144.56