Bikemat Bikemat - 1 month ago 18
JSON Question

C3 - Timeseries chart with JSON and categories

I am using C3 library for the first time and I think it's a good alternative to D3 for designing simple and reusable charts with no pain.

However, I have some issues in designing a timeseries chart.
Here is an example of the JSON file I will use to generate my chart:

data: {
json: [
{
"city": "Paris",
"date": "2016-09-01",
"event": 234
},
{
"city": "Paris",
"date": "2016-09-02",
"event": 891
},
{
"city": "Paris",
"date": "2016-09-03",
"event": 877
},
{
"city": "Berlin",
"date": "2016-09-01",
"event": 190
},
{
"city": "Berlin",
"date": "2016-09-02",
"event": 234
},
{
"city": "Berlin",
"date": "2016-09-03",
"event": 231
},
{
"city": "London",
"date": "2016-09-01",
"event": 23
},
{
"city": "London",
"date": "2016-09-02",
"event": 12
},
{
"city": "London",
"date": "2016-09-03",
"event": 89
},
],


The problem is that I can not set both my axis x: as a timeseries type and the key "city" as a category type.

For now I have:

keys: {
x: 'period',
value: ['event'],
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%Y-%m-%d'
}
}
},
type: 'spline'


And the corresponding Plunker: http://plnkr.co/edit/T1aLWQpaFwdu2zsWCa3d

I would like to have 3 splines, corresponding to the 3 cities that are retrieved from the JSON file.

Can you help me achieve this ?

Thank you very much :)

Answer

You need to wrangle your data into a format that c3 finds acceptable, which is akin to the example here -->https://jsfiddle.net/maxklenk/k9Dbf/

For yours we'd need an array of entries like

[{
    date = val
    London = val
    Paris = val
    Berlin = val
},
...
]

To do that we need to manipulate the original json:

     var json = <defined here>

      // group json by date
      var nestedData = d3.nest().key(function(d) { return d.date; }).entries(json);
      var cities = d3.set();   // this keeps a record of the cities mentioned so we don't need to hard-code them later on
      // run through the dates and make new objects of city=entry pairs (and the date=whatever)
      // all stored in a new array (formattedData) which we can feed to the chart json argument
      var formattedData = nestedData.map (function (entry) {
        var values = entry.values;
        var obj = {};
        values.forEach (function (value) {
          obj[value.city] = value.event;
          cities.add(value.city);
        })
        obj.date = entry.key;
        return obj;
      });


      var chart = c3.generate({
        data: {json: formattedData,
            keys: {
                x: 'date', // it's possible to specify 'x' when category axis
                value: cities.values(),
            }
        },
...

See the edited plunkr at http://plnkr.co/edit/5xa4z27HbHQbjcfpRLpQ?p=preview