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!
Not sure if you've checked it out:
http://omnipotent.net/jquery.sparkline/ nice lib if you are on the jquery side of the fence.
Posted by: Hardy | 06/12/2009 at 07:05 AM
looks like a good lib. I definitely prefer the cleanliness of jQuery and most of it's plugins, especially compared to YUI's verbose syntax. However, I do like having EVERYTHING hosted and ALL the documentation centralized. I only use it for admin consoles though, since it's so freakin bloated. Even though it's frowned upon, I love mixing the two together, especially since they're both available through the google API (http://code.google.com/apis/ajaxlibs/)
Posted by: Aaron | 06/12/2009 at 07:24 AM
Beautiful! For a while now I've been puzzling over how to make the complete charts component much more dynamic rather than having to write a function for each chart I need.
Using the response from the ajax to get all of the fields and chart settings is simply genius!
Thanks a lot!
Posted by: Alex Hall | 12/10/2009 at 03:39 AM