Browse Source

Implemented access to nested JSON objects as values for charts

Code to access objects by path was taken from the solution of
http://stackoverflow.com/questions/6491463

When JSON objects are used to load chart data, nested / inner objects and
arrays can now be loaded, too.
See additional tests in spec/data-spec.js for examples, how to access nested
JSON object values
pull/1675/head
Jakob Kneissl 9 years ago committed by Ændrew Rininsland
parent
commit
cc21d9c286
  1. 106
      spec/data-spec.js
  2. 19
      src/data.convert.js

106
spec/data-spec.js

@ -23,11 +23,11 @@ describe('c3 chart data', function () {
it('should draw correctly', function () {
var expectedCx = [6, 299, 593],
expectedCy = [370, 390, 331];
expectedCy = [371, 391, 332];
d3.selectAll('.c3-circles-data1 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], -2);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[i], -2);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[i], 0);
});
});
@ -62,16 +62,104 @@ describe('c3 chart data', function () {
it('should draw correctly', function () {
var expectedCx = {443: [98, 294, 490], 995: [98, 294, 490]},
expectedCy = {443: [193, 351, 36], 995: [390, 429, 351]};
expectedCy = {443: [194, 351, 36], 995: [391, 430, 351]};
d3.selectAll('.c3-circles-443 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[443][i], -2);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[443][i], -2);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[443][i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[443][i], 0);
});
d3.selectAll('.c3-circles-995 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[995][i], -2);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[995][i], -2);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[995][i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[995][i], 0);
});
});
it('should update nested JSON args', function () {
args = {
data: {
json: [{
"date": "2014-06-03",
"443": "3000",
"995": {"996": "500"},
"112": ["600"],
"223": [{"224": "100"}],
"334": [[],[{"335": "300"}]],
"556": {"557" : {"558" : ["1000"]}}
}, {
"date": "2014-06-04",
"443": "1000",
"112": ["700"],
"223": [{"224": "200"}],
"556": {"557" : {"558" : ["2000"]}}
}, {
"date": "2014-06-05",
"995": {"996": "1000"},
"112": ["800"],
"223": [{"224": "300"}],
"443": "5000",
"334": [[],[{"335": "500"}]],
"556": {"557" : {"558" : ["3000"]}}
}],
keys: {
x: 'date',
value: [ "443","995.996","112[0]","223[0].224","334[1][0].335","556.557.558[0]"]
}
},
axis: {
x: {
type: "category"
}
}
};
expect(true).toBeTruthy();
});
it('should draw nested JSON correctly', function () {
var expectedCx = [98, 294, 490],
expectedCy = {
443: [181, 326, 36],
995: [362, 398, 326],
112: [354, 347, 340],
223: [391, 383, 376],
334: [376, 398, 362],
556: [326, 253, 181]
};
d3.selectAll('.c3-circles-443 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[443][i], 0);
});
d3.selectAll('.c3-circles-995-996 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[995][i], 0);
});
d3.selectAll('.c3-circles-112-0- .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[112][i], 0);
});
d3.selectAll('.c3-circles-223-0--224 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[223][i], 0);
});
d3.selectAll('.c3-circles-334-1--0--335 .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[334][i], 0);
});
d3.selectAll('.c3-circles-556-557-558-0- .c3-circle').each(function (d, i) {
var circle = d3.select(this);
expect(+circle.attr('cx')).toBeCloseTo(expectedCx[i], 0);
expect(+circle.attr('cy')).toBeCloseTo(expectedCy[556][i], 0);
});
});
@ -115,7 +203,7 @@ describe('c3 chart data', function () {
});
describe('normal x', function () {
it('should have correct number of xs for each', function () {
expect(Object.keys(chart.internal.data.xs).length).toBe(3);
expect(chart.internal.data.xs.data1.length).toBe(6);

19
src/data.convert.js

@ -54,7 +54,10 @@ c3_chart_internal_fn.convertJsonToData = function (json, keys) {
var new_row = [];
targetKeys.forEach(function (key) {
// convert undefined to null because undefined data will be removed in convertDataToTargets()
var v = isUndefined(o[key]) ? null : o[key];
var v = $$.findValueInJson(o, key);
if (isUndefined(v)) {
v = null;
}
new_row.push(v);
});
new_rows.push(new_row);
@ -68,6 +71,20 @@ c3_chart_internal_fn.convertJsonToData = function (json, keys) {
}
return data;
};
c3_chart_internal_fn.findValueInJson = function (object, path) {
path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .)
path = path.replace(/^\./, ''); // strip a leading dot
var pathArray = path.split('.');
for (var i = 0; i < pathArray.length; ++i) {
var k = pathArray[i];
if (k in object) {
object = object[k];
} else {
return;
}
}
return object;
};
c3_chart_internal_fn.convertRowsToData = function (rows) {
var keys = rows[0], new_row = {}, new_rows = [], i, j;
for (i = 1; i < rows.length; i++) {

Loading…
Cancel
Save