Learning jqPlot
上QQ阅读APP看书,第一时间看更新

Working with remote data sources

We return from lunch and decide to start on our line chart showing social media conversions. With this chart, we want to pull the data in from other sources. You start to look for some internal data sources, coming across one that returns the data as an object. We can see an excerpt of data returned by the data source. We will need to parse the object and create data arrays for jqPlot:

{ "twitter":[ ["2012-11-01",289],...["2012-11-30",225] ],
  "facebook":[ ["2012-11-01",27],...["2012-11-30",48] ] }
  1. We solve this issue using a data renderer to pull our data and then format it properly for jqPlot. We can pass a function as a variable to jqPlot and when it is time to render the data, it will call this new function. We start by creating the function to receive our data and then format it. We name it remoteDataSource. jqPlot will pass the following three parameters to our function:
    • url: This is the URL of our data source.
    • plot: The jqPlot object we create is passed by reference, which means we could modify the object from within remoteDataSource. However, it is best to treat it as a read-only object.
    • options: We can pass any type of option in the dataRendererOptions option when we create our jqPlot object. For now, we will not be passing in any options:
      <script src="../js/jqplot.dateAxisRenderer.min.js"></script>  
      <script>
      $(document).ready(function(){
        var remoteDataSource = function(url, plot, options)   {
  2. Next we create a new array to hold our formatted data. Then, we use the $.ajax method in jQuery to pull in our data. We set the async option to false. If we don't, the function will continue to run before getting the data and we'll have an empty chart:
        var data = new Array;
        $.ajax({
          async: false,
  3. We set the url option to the url variable that jqPlot passed in. We also set the data type to json:
          url: url,
          dataType:"json",
          success: function(remoteData) {
  4. Then we will take the twitter object in our JSON and make that the first element of our data array and make facebook the second element. We then return the whole array back to jqPlot to finish rendering our chart:
            data.push(remoteData.twitter);
            data.push(remoteData.facebook);
          }
        });
        return data;
      };
  5. With our previous charts, after the id attribute, we would have passed in a data array. This time, instead of passing in a data array, we pass in a URL. Then, within the options, we declare the dataRenderer option and set remoteDataSource as the value. Now when our chart is created, it will call our renderer and pass in all the three parameters we discussed earlier:
      var socialPlot = $.jqplot ('socialMedia', "./data/social_shares.json",
      {
        title:'Social Media Shares',
        dataRenderer: remoteDataSource,
  6. We create labels for both our data series and enable the legend:
        series:[
          { label: 'Twitter' },
          { label: 'Facebook' }
        ],
        legend: {
          show: true,
          placement: 'outsideGrid'
        },
  7. We enable DateAxisRenderer for the x axis and set min to 0 on the y axis, so jqPlot will not extend the axis below zero:
        axes:{
          xaxis:{
            renderer:$.jqplot.DateAxisRenderer,
            label: 'Days in November'
          },
          yaxis: {
            min:0,
            label: 'Number of Shares'
          }
        }
      });
    });
    </script>
    <div id="socialMedia" style="width:600px;"></div>

Tip

If you are running the code samples from your filesystem in Chrome, you will get an error message similar to this:

No 'Access-Control-Allow-Origin' header is present on the requested resource.

The security settings do not allow AJAX requests to be run against files on the filesystem. It is better to use a local web server such as MAMP, WAMP, or XAMPP. This way, we avoid the access control issues. Further information about cross-site HTTP requests can be found at the Mozilla Developer Network at https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS.

We load this new chart in our browser and can see the result in the following screenshot:

Tip

We are likely to run into cross-domain issues when trying to access remote sources that do not allow cross-domain requests. The common practice to overcome this hurdle would be to use the JSONP data type in our AJAX call. jQuery will only run JSONP calls asynchronously. This keeps your web page from hanging if a remote source stops responding. However, because jqPlot requires all the data from the remote source before continuing, we can't use cross-domain sources with our data renderers.

We start to think of ways we can use external APIs to pull in data from all kinds of sources. We make a note to contact the server guys to write some scripts to pull from the external APIs we want and pass along the data to our charts. By doing it in this way, we won't have to implement OAuth (OAuth is a standard framework used for authentication), web app or worry about which sources allow cross-domain access.

Adding to the project's scope

As we continue thinking up new ways to work with this data, Calvin stops by. "Hey guys, I've shown your work to a few of the regional vice-presidents and they love it." Your reply is that all of this is simply an experiment and was not designed for public consumption.

Calvin holds up his hands as if to hold our concerns at bay. "Don't worry, they know it's all in beta. They did have a couple of ideas. Can you insert in the expenses with the revenue and profit reports? They also want to see those same charts but formatted differently."

He continues, "One VP mentioned that maybe we could have one of those charts where everything under the line is filled in. Oh, and they would like to see these by Wednesday ahead of the meeting." With that, Calvin turns around and makes his customary abrupt exit.