I built this for one small project then found myself using it all over the place. It's basically a generic JavaScript 'class'* that allows you to easily build YUI charts with very little JavaScript code.
If you use YUI charts as suggested in many examples you'll need configuration code for each individual chart which, if you have more than 2 or 3 charts on a page, can make your code appear cluttered. With the ChartsAjax class, all the chart options can be set with JSON data built dynamically on the server and retrieved from one AJAX call. This includes not only data for the datastore but also styling and column definitions.
Below is a breakdown with code examples. Feel free to offer suggestions on how to make it better!
- The very first thing you need to do is go to the YUI developer page and select the components you want to use then include the CSS/JavaScript per their instructions.
- Include the ChartsAjax and AjaxObject code in your page.
function ChartsAjax(){ var statType=''; var chartType=''; this.buildChart = buildChart; this.useData = useData; this.handleFailure = handleFailure; function buildChart(type, chart){ statType = type; chartType = chart; var sourceUrl = '/stats/get_chart/'+statType+'/'; var callback = {success:this.useData,failure:this.handleFailure}; AjaxObject.makeRequest(sourceUrl, callback); }; function useData(o){ try {var json = YAHOO.lang.JSON.parse(o.responseText);} catch (e) {return false;} YAHOO.widget.Chart.SWFURL = "http://yui.yahooapis.com/2.7.0/build/charts/assets/charts.swf"; var msDs = new YAHOO.util.DataSource( json.Response.Results ); msDs.responseType = YAHOO.util.DataSource.TYPE_JSARRAY; msDs.responseSchema = { fields:json.Response.Fields }; var targetDiv = statType; var chartDefinition = { series: json.Response.Series, xField: json.Response.XField, yField: json.Response.YField, style: json.Response.Style } switch(chartType){ case "line": var chart = new YAHOO.widget.LineChart(targetDiv, msDs, chartDefinition); break; case "column": var chart = new YAHOO.widget.ColumnChart(targetDiv, msDs, chartDefinition); break; } }; function handleFailure(o){ //do something with o.responseText } }; var AjaxObject = { makeRequest:function(url, callback){var request = YAHOO.util.Connect.asyncRequest('GET', url, callback);} }; - Create an empty container div. Remember that the chart takes on the dimensions of it's parent container so you could either apply a class to this div or a style attribute (ex: style="width:500px;height:200px").
<div id="products_sold" >Loading...</div>
- On page load, create a ChartsAjax instantiation. Notice the second argument in the buildChart method. You can choose to display the chart as 'line' or 'column'. You can also add options to the ChartsAjax class as you wish. ex:
function load_charts(){ var products_sold = new ChartsAjax(); products_sold.buildChart('products_sold', 'line'); } YAHOO.util.Event.onDOMReady(load_charts); - Return data from server. The class will use the sourceUrl variable to request data from your server. You can configure the url to fit your needs. The JSON can be built using any server side language. My favorite is python because the list and dictionary data structures are virtually identical to the resulting JSON. Example json:
{"Response": { "YField": "", "Style": { "legend": { "display": "bottom"}, "xAxis": {"labelRotation": "-90"}, "yAxis": {"titleRotation": "-90"}}, "Fields": ["date", "total"], "Results": [ {"date": "05-27", "total": 147}, {"date": "05-28", "total": 105}, {"date": "05-29", "total": 160}, {"date": "05-30", "total": 40}, {"date": "05-31", "total": 66}, {"date": "06-01", "total": 136}, {"date": "06-02", "total": 243}], "Series": [{ "yField": "total", "displayName": "Total Products Sold"}], "XField": "date"}} - Presto!