Automatic conversion from simple, accessible data tables to YUI Charts

By YUI TeamJanuary 17th, 2008

About the Author: Christian Heilmann is the author of Beginning JavaScript with DOM Scripting and Ajax. He has worked in web development for almost 9 years for several agencies and .coms and is currently a lead developer at Yahoo! in England. Christian is a frequent speaker on the conference circuit in the UK and Europe; you can find some of his writing here on YUIBlog as well as on his personal blog at http://wait-till-i.com.

Charts are a great idea to make rows and rows of boring numbers easier to understand and to take in — for people that can see them. However, not all of your site’s visitors can see and you’ll also want to keep information you offer available for search engines. There are a lot of libraries on the web that allow you to create charts, but not many take this use case into consideration.

In praise of data tables

This is where data tables come into play. (Note: For the purposes of this article, I’m referring to pure HTML tables — not to rich UI controls like Jenny Han Donnelly’s YUI DataTable Control.) They are the perfect data construct in HTML as they are available both for people that can see and those who can’t. Assistive technologies like screen readers offer a way to navigate tables and to read their information row-by-row and cell-by-cell. All you need to do to please everyone is to use the correct markup (including a few attributes you might not have used yet):

<table summary="Results of a survey of which animals people would like to see more on YDN">
  <caption>What animals would you like to see more?</caption>
  <thead>
    <tr>
      <th scope="col">Animal</th>
      <th scope="col">Requests</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kittens</td>
      <td>45331</td>
    </tr>
    <tr>
      <td>Puppies</td>
      <td>32323</td>
    </tr>
    <tr>
      <td>Elephants</td>
      <td>12345</td>
    </tr>
    <tr>
      <td>Badgers</td>
      <td>6546</td>
    </tr>
    <tr>
      <td>Sharks (without lasers)</td>
      <td>223</td>
    </tr>
    <tr>
      <td>Sharks (with lasers)</td>
      <td>2323</td>
    </tr>
  </tbody>
</table>

The summary attribute tells assistive technology what this table is about and the caption shows up for all users. The th elements define what cells are headers and the scope attribute applies them to all the data cells they are connected to. In this case it means that “animal” gets read out before each animal and “requests” before each number. This means that even a visitor who cannot see will still know in row five what the information is about. All in all the table renders as:

What animals would you like to see more?
Animal Requests
Kittens 45331
Puppies 32323
Elephants 12345
Badgers 6546
Sharks (without lasers) 223
Sharks (with lasers) 2323

Easy to understand, but not too pretty. And it can get boring. How about we use this information and create a tasty pie chart like the following (click on the image below to see the working example in action)?

The accessible table enhanced with a pie chart (image; click through to see working example)

Using table data to automatically generate charts

In order to have the table be preceeded by a pie chart like this all you need is to add two scripts at the end of the document body and a class called yui-table to the table itself. For example:

<table class="yui-table" summary="Results of a survey of what browser people love">
  <caption>What browser do you love?</caption>
  <thead>
    <tr>
      <th scope="col">Browser</th>
      <th scope="col">Lovers</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>MSIE</td>
      <td>221</td>
    </tr>
    <tr>
      <td>Firefox</td>
      <td>516</td>
    </tr>
    <tr>
      <td>Opera</td>
      <td>312</td>
    </tr>
    <tr>
      <td>Safari</td>
      <td>100</td>
    </tr>
    <tr>
      <td>Omniweb</td>
      <td>30</td>
    </tr>
    <tr>
      <td>Lynx</td>
      <td>4</td>
    </tr>
  </tbody>
</table>
<script src="http://yui.yahooapis.com/2.4.1/build/yuiloader/yuiloader-beta-min.js"></script>
<script src="tablestoyuicharts.js"></script>

This will show in a browser with the latest Flash plugin like this:

The accessible table enhanced with a pie chart (image; click through to see working example)

You can define the size of the chart in CSS by defining a width and height for each div element with a class of yuichartfromtable:

div.yuichartfromtable{
  width:300px;
  height:300px;
  margin:0 auto;
}

As for the scripts: the first script is the YUI Loader Utility which allows you to pull in YUI components on-demand. This is great, as you don’t need to add lots and lots of script elements but let the YUI Loader figure out what it needs. You can download the second script here; if you care to know what is going on with it, check the following section. If you just want to use the script, then you’re done :-).

How does this work?

The script to turn all tables with the class yui-table into charts is quite short, as it uses the newer YUI components that take a lot of the heavy lifting off you, especially the table-to-dataset conversion which is done by the YUI DataSource Utility. The full script is this:


var tablestoYUIchartsplease = new YAHOO.util.YUILoader({
  require: ['charts'],
  onSuccess: function(){
    var tables = YAHOO.util.Dom.getElementsByClassName('yui-table','table');
    YAHOO.util.Dom.batch(tables,function(o){
      var chartcontainer = document.createElement('div');
      YAHOO.util.Dom.addClass(chartcontainer,'yuichartfromtable');
      YAHOO.util.Dom.insertBefore(chartcontainer,o);
      var data = new YAHOO.util.DataSource(o);
      data.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
      data.responseSchema = {fields:['response','count']};
      YAHOO.widget.Chart.SWFURL = 'http://developer.yahoo.com/yui/build/charts/assets/charts.swf?_yuiversion=2.4.1';
      var chart = new YAHOO.widget.PieChart(chartcontainer,data,{
        categoryField:'response',
        dataField:'count',
        expressInstall:'http://developer.yahoo.com/yui/build/charts/assets/expressinstall.swf'
      });
    });
  }
});
if(document.location.toString().indexOf('http')!==-1){
  tablestoYUIchartsplease.insert();
}

Let’s chunk it up and see what each section does:

var tablestoYUIchartsplease = new YAHOO.util.YUILoader({
  require: ['charts'],
  onSuccess: function(){

First up, we let the YUI Loader do its magic: We instantiate a new loader, tell it we need the YUI Charts Control and wait for the different script nodes to be generated and the components to be loaded before we continue. The loader tells us all is OK by firing the onSuccess event, which we use to execute an anonymous function that does all the other work.

    var tables = YAHOO.util.Dom.getElementsByClassName('yui-table','table');
    YAHOO.util.Dom.batch(tables,function(o){

We use the YUI Dom Collection to get all tables with the correct class and apply a function to each of these tables using the batch method. The method sends the current table as the parameter o to this function.

      var chartcontainer = document.createElement('div');
      YAHOO.util.Dom.addClass(chartcontainer,'yuichartfromtable');
      YAHOO.util.Dom.insertBefore(chartcontainer,o);

We create a new div element, give it a class of yuichartfromtable (to allow for styling) and insert the new element into the document before the table.

      var data = new YAHOO.util.DataSource(o);
      data.responseType = YAHOO.util.DataSource.TYPE_HTMLTABLE;
      data.responseSchema = {fields:['response','count']};

Then we allow the rather new YUI DataSource Utility to flex its binary muscles. While this is meant to wade through external data sources and JavaScript arrays for you, it also allows for a responseType of HTML table, which means it converts a table to a JavaScript object you can work with. As we’re dealing here with a really simple table, all we need to do in terms of responseSchema is to define two fields: a response (what) and a count (how many). These three lines are all you need to convert the table to a dataset that both the YUI Charts Control and the YUI DataTable Control can use.

      YAHOO.widget.Chart.SWFURL = 'http://developer.yahoo.com/yui/build/charts/assets/charts.swf?_yuiversion=2.4.1';
      var chart = new YAHOO.widget.PieChart(chartcontainer,data,{
        categoryField:'response',
        dataField:'count',
        expressInstall:'http://developer.yahoo.com/yui/build/charts/assets/expressinstall.swf'
      });

Time for pie: we define the URL of the Flash movie that draws the pie and instantiate a new pie chart. We send the div we created earlier as the container, the data we retrieved from the table as the data to display and define a configuration object. This object has the response field as the categories and the count field as the data. The expressinstall defines what Flash movie to show if the visitor doesn’t have the right Flash version.

    });
  }
});
if(document.location.toString().indexOf('http')!==-1){
  tablestoYUIchartsplease.insert();
}

Almost done. All the script now needs to do is to call the insert() method of the YUI Loader — that gets the ball rolling. I’ve enclosed the method in an if statement that checks if the HTML is called up via HTTP or not as the Charts Control needs HTTP to work.

Summary

That’s all you need to do to progressively enhance an accessible data table to turn them into a pie chart using the YUI Charts Control. We can extend this example to allow for several types of charts and to turn the tables into sortable data tables quite easily. If there is interest, drop us a comment.

21 Comments

  1. Hey! You ought to check out http://lovegraph.thefootnotes.net which uses a very similar method to the one described here. Plus, it’s dorky and fun all at the same time!

  2. Hi,

    Is there any way of making the flash charts printable ?

    I’d love to use something like this as part of a lightweight reporting tool, but every time I get requirements for such a tool from a client they want printable charts…

  3. That’s awesome. It brings the barriers to entry to using Flash very, very low. And the Charts control had already lowered them a lot, so kudos on that very simple yet extremely powerful idea.

    For extra awesomeness, you could sniff for Flash before running tablestoYUIchartsplease, so that browsers don’t create a big empty space if the plugin isn’t available.

    Keep up the good work ;)

  4. Great example!! thanks for sharing

  5. great stuff. Is there anyway to modify how the charts display? For instance, could I have control of the colors used to render the pie-pieces?

    Thanks for the tutorial!

  6. James, the charts are printable, at least from a quick test I just did in Firefox. It appears that they do not show up in Print Preview, but I was able to successfully print Christian’s YUI Charts from Data Tables example page.

  7. This is impressive, but designers should be very careful with how they use pie charts, which are typically the worst format for presenting comparative data. Pie charts are sort of the friendly doofuses of the graph world, they seem very approachable and clear, but don’t really offer any solid insight.

    It’s very hard to accurately compare the wedge shapes in pies, because humans aren’t that good at determining angle sizes or angular area. If you were just looking at the pie chart above, could you tell what the difference between Lynx and Opera is easily and accurately? (That’s not quite fair, since the pie chart’s not actually labelled.) Most importantly, can you easily tell that Opera represents 6x Lynx? If you can’t tell simply by looking at the graph (not the data table), it’s not a useful visualization. Wikipedia’s got a terrific example of this problem. The examples of pie charts in Google’s Chart API impart literally no information at all other than “some things make up some other thing.”

    Also, this particular dataset doesn’t need to show how much a given browser represents out of 100%. It’s probably obvious that if MSIE is about a quarter of the chart (and there’s no way to know this without manually doing the math–the chart doesn’t tell you if it’s 25%, 28%, or what) that it’s out of some total. This chart just says that it’s “out of 100%”, but not 100% of what. If you were comparing multiple datasets against each other, than the total might matter: for instance browser use by men vs. browser use by women. Even then, it’s probably unimportant.

    A good rule of thumb is that any pie chart almost certainly would be better as a plain vertical bar graph. It’s easy to visually compare the relative sizes of various rectangles, plus a bar chart would give you a place to put labels or ticks which would clarify this data a lot. Finally: if you only have one column of numbers to compare, the original plain data table is the most effective presentation of them! Let the numbers speak for themselves.

    I’d love to see this rewritten to show how to generate bar charts, perhaps with some datasets that really merited visualizations.

  8. [...] Automatic conversion from simple, accessible data tables to YUI Charts » Yahoo! User Interface Blog [...]

  9. Josh – Thanks, I’d only quickly looked at print preview in FF…

  10. Hey, this is cool!
    But, how i make to do the chart with dimension 200×200?

    Thx!

  11. @Fred — The chart will be the size of the containing element, so just instantiate the chart in a 200×200 div. -Eric

  12. [...] I played with Google charts and porting the idea of generating charts from accessible table data over to YUI charts Stoyan Stevanof had to use the same idea to generate his own, home-made Canvas-driven [...]

  13. [...] I played with Google charts and porting the idea of generating charts from accessible table data over to YUI charts Stoyan Stevanof had to use the same idea to generate his own, home-made Canvas-driven [...]

  14. [...] Automatic conversion from simple, accessible data tables to YUI Charts – для разработчиков, использующих AJAX и нуждающихся в отображении различных табличных данных, описывается простой способ, как при помощи библиотеки Yahoo User Interface (YUI) создать приложение, строящее графики по исходным табличным данным. Кстати, многие популярные фреймворки уже имеют в своём арсенале компоненты для рисования графиков, некоторые даже замахиваются на трёхмерные диаграммы (Dojo Toolkit), а Google недавно предоставил свой сервис построения графиков, так что, видимо, рынок вполне готов принять новый подход, когда данные это не только и не столько сухие данные в таблицах, но и красочные диаграммы. [...]

  15. Hello, i have a question, is there a way to display labels on the pie chart or legend so a user can view data without having to hover over the pie chart.

    I know you can place a legend but you cant place any meaningful data on the legend.

    Basically display the datatip data without having to hover over its a fairly common for pie charts to display such data.

  16. The example on this page seems to be broken. clicking on the charts takes you to page where the tables are displayed and a space for the charts, but no actual chart.

    I there an updated version of this page as i’m really keen to be able to create charts from html tables but my javascript is not so good.

  17. I have a question about charts.I dont know it belongs here.If not plz leave it .

    My Question is “i have a chart drawn using yui charts its sie is more that 4000px(for displaying it properly).So it cant be displayed as its edges get cropped or clipped.I tried to specify a start and end indexes for data source so that data b/w the indexes will be used for drawing chart.YUI Data Source doesn’t provide a facility like this(as far as i know).Is there any solution for handling large charts ?”

    Thanks in advance

  18. Kenneth –

    Thanks for the question. The blog isn’t the best place for support on YUI component usage — I’d recommend the YUILibrary forums: http://yuilibrary.com/forum. That’s where all the YUI experts hang out and answer questions.

    -Eric

  19. can we use 3d charts in YUI? if we create our own SWF then hw we should put datasourse?