4
votes

I have an empty timeseries chart with c3js and would like to "load" dynamically columns from a unknown map.

Initialization

var chart = c3.generate({
    data: {
        x: 'ts',
        xFormat: null, // For millis
        columns: []
    },
    axis: {
        x: {
            type: 'timeseries',
            tick: {
                format: '%Y-%m-%d'
            }
        }
    },
    line: { // For enable null values in series (gaps in charts))
        connectNull: false 
    }
});

I add the x axis values and dynamically generated map with all data:

var tsData = ['ts'].concat(VALUES_FROM_ANOTHER_FUNCTION);
periodPowerChart.load({
    columns: [
        tsData
    ]
});
// opMode looks like [{"1": [null, null, 0, 3, 5]}, {"2": [2, 4, null, null, null]}]
for (key in opMode) {
    chart.load({
        columns: [
            [key].concat(opMode[key])
        ]
    })
}

So the idea is loading data from opMode. In the first iteration in the for i got:

Error: x is not defined for id = "1"

The 3 arrays (ts, "1" and "2" have same number of elements). Any ideas?

2

2 Answers

2
votes

You are inserting a invalid data format to the columns parameter. You should provide something like below to the columns.

var columnsData = [[
  "ts",
  "2013-01-01",
  "2013-01-02",
  "2013-01-03",
  "2013-01-04",
  "2013-01-05"
],
[
  "data1",
  null,
  null,
  0,
  3,
  5
],
[
  "data2",
  2,
  4,
  null,
  null,
  null
]];

I updated your dynamic column inserting logic to make data look like above. Here's the code.

//opMode should look like below with time data.
var opMode = [{
  "ts": ['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05']
}, {
  "data1": [null, null, 0, 3, 5]
}, {
  "data2": [2, 4, null, null, null]
}];

opMode.forEach(function(obj, index) {
  var key = Object.keys(obj)[0];
  var data = [key];

  data = data.concat(obj[key]);

  chart.load({
    columns: [
      data
    ]
  });

});

You can refer this example and play with it to get a good idea.
http://c3js.org/samples/timeseries.html

0
votes

Just to help someone else in another approach.

In my case the problem was related to loading multiple times data. Just joining all the column data in a single array solves the issue:

var columnsData = [];
var tsData = ['ts'].concat(VALUES_FROM_ANOTHER_FUNCTION);
columnsData.push(tsData);
for (key in opMode) {
    columnsData.push([key].concat(opMode[key]));
}
chart.load({
    columns: columnsData
});