Data aggregation in c3js

2019-09-12 18:16发布

问题:

Is there an option to aggregate the data in C3 charts? When the JSON contains multiple data elements with the same category, data is plotted as multiple points in the charts, where as it should be aggregated and shown as a single point in the chart. Attached are the C3 charts and expected chart format. In the example: "name 1" show a single point at 300 as upload, where as ion C3 it show one point at 200 and the other at 100 for the same.

Code Used:

var chart = c3.generate({
            bindto:'#png-container',
            data: {
              json: [
                {name: 'name1', upload: 200, download: 200, total: 400},
                {name: 'name1', upload: 100, download: 300, total: 400},
                {name: 'name2', upload: 300, download: 200, total: 500},
                {name: 'name3', upload: 400, download: 100, total: 500},
              ],
              keys: {
                x: 'name', // it's possible to specify 'x' when category axis
                value: ['upload', 'download'],
              },
              groups: [
                ['name']
              ]
            },
            axis: {
              x: {
                type: 'category'
              }
            }
        });

Output of the above code:

Expected Output:

回答1:

Not built into c3 as far as i'm aware. You can use d3's nest operator to aggregate the json data before passing it to c3 though.

var json = [
            {name: 'name1', upload: 200, download: 200, total: 400},
            {name: 'name1', upload: 100, download: 300, total: 400},
            {name: 'name2', upload: 300, download: 200, total: 500},
            {name: 'name3', upload: 400, download: 100, total: 500},
          ];

    var agg = function (json, nestField) {
        var nested_data = d3.nest()
            .key(function(d) { return d[nestField]; })
            .rollup(function(leaves) { 
                // Work out the fields we're not nesting by
                var keys = d3.merge (leaves.map (function(leaf) { return d3.keys(leaf); }));
                var keySet = d3.set(keys);
                keySet.remove (nestField);
                var dataFields = keySet.values();

                // total these fields up
                // console.log(leaves, dataFields); // just for testing
                var obj = {};
                dataFields.forEach (function (dfield) {
                    obj[dfield] = d3.sum(leaves, function(d) {return d[dfield];});
                });
                return obj; 
            })
            .entries(json);

        // return to original json format
        var final_data = nested_data.map (function(nestd) {
            nestd.values[nestField] = nestd.key;
            return nestd.values;
        });

        return final_data;
    };

    var chart = c3.generate({
        bindto:'#png-container',
        data: {
          json: agg(json, "name"),
          keys: {
            x: 'name', // it's possible to specify 'x' when category axis
            value: ['upload', 'download'],
          },
          groups: [
            ['name']
          ]
        },
        axis: {
          x: {
            type: 'category'
          }
        }
    });

https://jsfiddle.net/8uofn7pL/2/

whoops, linked to the wrong fiddle there



标签: json c3.js