D3js:如何加载CSV数据并将其转换为nvd3.js对象?

时间:2014-03-11 18:32:47

标签: jquery csv d3.js key-value nvd3.js

我有一个逗号分隔的文件:

 dV,  dA, Model, Cell
-1.5, -3.2,  B, xA
-1.1, -2.3,  B, xB
 1.2, -0.8,  B, xC
 6.5,  2.7,  C, xA
 7.4,  4.5,  C, xB
 6.1,  3.3,  C, xC
 24.6, 12.3, D, xA
 25.2, 11.8, D, xB
 29.9, 18.3, D, xC
...

并希望将if转换为nvd3.js对象,其中数据按“Cell”列值分组:

{
 key: value from "Cell" column,
 values: {x: .., y: ..., shape: value from "Model" column},
 ...
}

为此,我使用以下代码:

function loadData(filename) {

var data = [],
    shapes = {xA: 'circle', xB: 'square;' xC: 'cross']

d3.csv(filename, function(d) {
    if ((data['key' === undefined) || (data.key[d.Cell] === undefined)) {
        data.push{
            key: d.Cell,
            values: []
        }
    }
    data.key[d.Cell].values.push({
        x: +d.dV,
        y: +d.dA,
        size: 3,
        shape: function(d) { return shapes[d.Model] || 'circle'; }
    })
);

return data;

}

代码不起作用。以下代码有什么问题,以及如何将CSV数据转换为nvd3.js对象?

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题:

  • Javascript语法

发布的示例包含Javascript语法错误(shapes定义中的拼写错误,检查data.key的值,data.push) - 您是否在发布之前尝试调试javascript ?

  • CSV文件包含空格

D3.js,CSV解析器不会剥离空格,这与使用d.Cell提取Cell属性的方式尤其相关。 D3.js将其解析为'细胞'而不是' Cell'。

  • CSV回调函数返回已解析行的数组,而不是单行

您需要将行处理代码包装在d.forEach(function(rowData) { /* your row processing here */ })

  • data的返回并不反映CSV的回调性质

您的return data;不在CSV回调函数中。因此,在CSV功能完成其工作之前,所有人都可能会被调用。

您需要将loadData函数更改为异步模式。即:让调用者提供一个回调函数,该函数在CSV函数中使用已处理的data输出调用。

  • 数据库未正确设置

我相信您正在寻找以下列形式返回的数据:

[ { key: 'xA', values: .... }, { key: 'xB', values: .... } .... ]

即:一组对象,每个对象具有与key属性相对应的不同Cell

但是,您的data.key[...]检查正在尝试检查key阵列本身的data属性!它不会评估data中的对象是否具有key属性。

不一定是个问题,具体取决于您的NVD3.js设置:

  • shapes密钥是否正确?

您的shapes查询的关键字为xAxBxC。根据您提供的数据,这些数据与Cell中的值相对应,但是您要检查d.Model

  • shapes属性是否需要是一个函数?

鉴于所有其他属性都是CSV解析数据的直接副本,形状的function(d)方法可能会造成不必要的复杂化。

直接设置它? shape: shapes[d.Model] || 'circle'

将上述所有内容放在一起,我将代码示例放在下面,说明:

        loadData('data.csv', function(data) { console.log(data); });

        function getOrCreateEntry(data, key) {
            data.forEach(function(d) {
                if (d.key === key)
                    return d;
            });

            var newEntry = { key: key, values: [] };

            data.push(newEntry);

            return newEntry;
        }

        function loadData(filename, cb) {

            var data = [],
                shapes = {A: 'circle', B: 'square', C: 'cross'}

            d3.csv(filename,function(csvData) {
                csvData.forEach(function(d) {

                    cellEntry = getOrCreateEntry(data, d.Cell);

                    cellEntry.values.push({
                        x: +d.dV,
                        y: +d.dA,
                        size: 3,
                        shape: shapes[d.Model] || 'circle'
                    })
                });

                cb(data);
            });
        }