使用JavaScript将CSV格式化为JSON

使用JavaScript将CSV格式化为JSON,javascript,d3.js,underscore.js,sankey-diagram,Javascript,D3.js,Underscore.js,Sankey Diagram,我的任务:给定一组CSV格式的数据,使用D3显示sankey图表 给定数据格式:(我无法更改此格式) D3 Sankey插件所需的格式: { "nodes": [ {"name": "Use1"}, {"name": "Use2"}, {"name": "Type1"}, ... ], "links": [ {"source":"Use1", "target":"Type1", "value":1}, ... } 我的问题是:将CSV数据转换为Sankey图表所需的JS

我的任务:给定一组CSV格式的数据,使用D3显示sankey图表

给定数据格式:(我无法更改此格式)

D3 Sankey插件所需的格式:

{ "nodes": [
  {"name": "Use1"},
  {"name": "Use2"},
  {"name": "Type1"},
  ...
], "links": [
  {"source":"Use1", "target":"Type1", "value":1},
  ...
}
我的问题是:将CSV数据转换为Sankey图表所需的JSON。我无法更改提供给我的初始数据,因此我必须动态构建JSON

我的研究引导了我,但唯一一个篡改CSV数据的例子(还没有包括值,只有源和目标)是通过MySQL。由于我无法访问项目中的数据库,因此我求助于使用下划线.js来帮助我进行转换(在Backbone.js应用程序中)

这是我到目前为止所做的,它按预期工作

// buildJSON is a method of a Backbone View that oversees the creation of the diagram
buildJSON: function( csv ) {
    var json = {
        nodes: [], // unique nodes found in data
        links: []  // links between nodes
    };

    // get unique nodes!
    var uniqueNodes = _.chain(csv).map(_.values).flatten().unique().value().sort();
    uniqueNodes.forEach(function( node ) {
        json.nodes.push({ name: node });
    });

    // map colors to nodes
    this.color.domain(uniqueNodes);

    // map links
    var links = [];
    var rMap = {};
    var keys = _.keys(csv[0]);
    for ( var i = 0; i < csv.length; i++ ) {
        for ( var j = 0; j < keys.length - 1; j++ ) {
            var relationship = csv[i][keys[j]] + '-' + csv[i][keys[j + 1]];
            rMap[relationship] = ++rMap[relationship] || 1;
        }
    }

    // create links from the linkmap
    for ( var r in rMap ) {
        if ( rMap.hasOwnProperty(r) ) {
            var rel = r.split('-');
            links.push({
                source: rel[0],
                target: rel[1],
                value: rMap[r]
            });
        }
    }

    var nodeMap = {};
    json.nodes.forEach(function( node ) { nodeMap[node.name] = node; });
    json.links = links.map(function( link ) {
        return {
            source: nodeMap[link.source],
            target: nodeMap[link.target],
            value: link.value
        };
    });

    return json;
}
//buildJSON是一种主干视图方法,用于监督图表的创建
buildJSON:函数(csv){
var json={
节点:[],//在数据中找到唯一的节点
链接:[//节点之间的链接
};
//获取唯一节点!
var uniqueNodes=..chain(csv).map(..values).flatte().unique().value().sort();
uniqueNodes.forEach(函数(节点){
push({name:node});
});
//将颜色映射到节点
此.color.domain(uniqueNodes);
//地图链接
var-links=[];
var rMap={};
var-keys=u.keys(csv[0]);
对于(变量i=0;i
对于一个小的数据集来说,这并不是一个问题,但是数据可能包含数千行,可能多达10列

长话短说,我的问题分为两部分:

  • 是否有任何明显的性能提升,以及

  • 对于D3中的Sankey图表,是否有更好(更有效)的数据处理方法


  • 我意识到这是一个特别狭隘的问题,所以我感谢所有人的帮助

    顺便说一句,这里有一个好的JSCSV解析器@KonstantinV.Salikhov刚刚试用了他们的演示-棒极了!我将对此进行更深入的探讨。您的限制是否意味着您的Web应用程序正在被提供CSV数据,或者只是您必须处理它?很明显,您不可能提前在服务器端完成此操作(假设数据不是动态的),但只要有一点点机会,这就是解决方法。@mgold此时它不是一个真正的Web应用程序,只是一个本地运行的页面,将处理文件系统上的文件。数据不是动态的,而是一堆excel电子表格的集合。这看起来更像是在通过应用程序运行之前将文件处理成JSON,这可能是我唯一的选择choice@chazsolo在这种情况下,您甚至可以在node.js中运行一次现有代码,将json输出保存到一个文件中,并提供服务。或者用您选择的语言重写转换。
    // buildJSON is a method of a Backbone View that oversees the creation of the diagram
    buildJSON: function( csv ) {
        var json = {
            nodes: [], // unique nodes found in data
            links: []  // links between nodes
        };
    
        // get unique nodes!
        var uniqueNodes = _.chain(csv).map(_.values).flatten().unique().value().sort();
        uniqueNodes.forEach(function( node ) {
            json.nodes.push({ name: node });
        });
    
        // map colors to nodes
        this.color.domain(uniqueNodes);
    
        // map links
        var links = [];
        var rMap = {};
        var keys = _.keys(csv[0]);
        for ( var i = 0; i < csv.length; i++ ) {
            for ( var j = 0; j < keys.length - 1; j++ ) {
                var relationship = csv[i][keys[j]] + '-' + csv[i][keys[j + 1]];
                rMap[relationship] = ++rMap[relationship] || 1;
            }
        }
    
        // create links from the linkmap
        for ( var r in rMap ) {
            if ( rMap.hasOwnProperty(r) ) {
                var rel = r.split('-');
                links.push({
                    source: rel[0],
                    target: rel[1],
                    value: rMap[r]
                });
            }
        }
    
        var nodeMap = {};
        json.nodes.forEach(function( node ) { nodeMap[node.name] = node; });
        json.links = links.map(function( link ) {
            return {
                source: nodeMap[link.source],
                target: nodeMap[link.target],
                value: link.value
            };
        });
    
        return json;
    }