Preparing delicious donut charts in C3.js

An introduction to build simple charts based on JSON data

Posted on May 01, 2015

Visualizing data quickly is vital for business, experiments, monitoring, ... for life! There are many javascript frameworks for drawing charts. In particular, I always admired D3.js.

There are many examples and tutorials to build surreal charts with D3.js. They are really good but may be highly time-consuming. For cases, when you just want to draw simple charts, or you are only prototyping, we can find some frameworks that let life easier to use D3.js.

C3.js - D3-based reusable chart library

C3.js abstracts D3js by providing an API that represents chart types and elements, time series, data sources, etc. Here, I will focus on how to draw Donut (yummy!!) charts getting data from a JSON source:

This beautiful donut chart collects country searches of users, aggregates the data, and then, plots the % of search of each country. C3.js calculates the % automatically, we just have to provide the aggregation =]

C3.js examples are very clear about how to build a Donut chart and get data from JSON source. However, it don't explain how to combine both tasks which can be a very tricky combination.

Preparing JSON data ( our main ingredient )

For this specific chart type, we have to structure our JSON data into something like this:

[
  {"brazil": 60},
  {"france": 10},
  {"united_states": 5},
  {"canada": 5},
  {"italy": 20},
  {"south_africa": 10},
  {"thailand": 2}
]

Besides, we have to explicit define the chart subtitles that can be provided through an array or csv string, like the following example:

brazil,france,united_states,canada,italy,south_africa,thailand

In our application, JSON data can also contain the subtitles, or it can be set by some helper method, in case of a Rails app.

Baking the donut charts

To render our donut chart we can develop a simple coffeescript function that receives:

  • target where to render the chart
  • chartTitle chart title
  • jsonData our json data, as presented above
  • categories chart subtitles

@renderDonutChart = (target, chartTitle, jsonData, categories) ->
  c3.generate({
    bindto: target,
    data: {
      json: jsonData,
      keys : { value: categories.split(",") },
      type: "donut"},
    },
    donut: { title: chartTitle }
  })

As my motivation in this post is to build a beautiful chart as quickly as possible, we don't get Json data from an AJAX call. Just to exemplify, I'm calling the above function statically in my view. In a Rails app with Haml, to develop the views, we can render our chart by calling:

:coffeescript
  data = #{@country_data.to_json}
  subtitles = @country_labels

  renderDonutChart("#country_chart", "% of searches", data, subtitles)

In this example, both json data and subtitles comes from my controller. Only I have to do is to interpolate the data and pass it to to my coffeescript function.

That's it, I would like to thank my friend @diegoy_kuri for showing me C3.js. He also started this coffeescript function and I've adapted it for donut charts.

Thank you for reading