我有2个CSV文件,一个描述树的链接(graph.csv - 2列:源和目标),另一个是节点名称的字典(nodes.csv - 2列:node_id,node_name )。包含源/目标的CSV引用第二个CSV中的node_id列。
现在我想使用第二个CSV将节点名称(以及最终的其他属性)附加到树中的节点。我已经想出了如何将文本附加到节点,但我无法弄清楚如何“交叉”第二个CSV中的数据,以将每个节点的名称作为文本附加到相应的节点。 / p>
我得到的代码就像我想要的那样工作,但现在它只根据Mike Bostock的answer here in SO从第一个CSV中提取节点。现在我无法确定哪个节点是哪个节点,我想使用第二个CSV来识别节点。
据我所知,这段代码显然标识了graph.csv中的唯一节点,确定了根,然后构建了树。如果有办法从第一个CSV和复制读取它,用第二个CSV中的节点名称更改节点的ID,我认为这将是第一步,但我无法执行它正确。
CSV示例:
graph.csv:
source,target 1,2 1,3 1,4 2,5 2,6 11,22 14,21 3,7 3,8 4,9 4,10 5,11 5,12 5,13 6,14 6,15 7,16 8,17 9,18 10,19 10,20
nodes.csv:
node_id,node_name 1,Node1 2,Node2 3,Node3 4,Node4 5,Node5 6,Node6 7,Node7 8,Node8 9,Node9 10,Node10 11,Node11 12,Node12 13,Node13 14,Node14 15,Node15 16,Node16 17,Node17 18,Node18 19,Node19 20,Node20 21,Node21 22,Node22
目前的代码是:
var margin = {top: 40, right: 40, bottom: 40, left: 40}, width = 1024 - margin.left - margin.right, height = 768 - margin.top - margin.bottom; var tree = d3.layout.tree() .size([height, width]); var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); d3.csv("graph.csv", function(links) { var nodesByName = {}; links.forEach(function(link) { var parent = link.source = nodeByName(link.source), child = link.target = nodeByName(link.target); if (parent.children) parent.children.push(child); else parent.children = [child]; }); var nodes = tree.nodes(links[0].source); svg.selectAll(".link") .data(links) .enter().append("line") .attr("class", "link") .attr("x1", function(d) { return d.source.y; }) .attr("y1", function(d) { return d.source.x; }) .attr("x2", function(d) { return d.target.y; }) .attr("y2", function(d) { return d.target.x; }); svg.selectAll(".node") .data(nodes) .enter().append("circle") .attr("class", "node") .attr("r", 10) .attr("cx", function(d) { return d.y; }) .attr("cy", function(d) { return d.x; }); svg.selectAll("text") .data(nodes) .enter().append("text") .attr("class", "label") .attr("x",function(d) { return (d.y - 25); }) .attr("y",function(d) { return (d.x + 20); }) .text("Text"); function nodeByName(name) { return nodesByName[name] || (nodesByName[name] = {name: name}); } });
有没有人知道如何“关联”两个CSV并在文本追加中输出相应的名称?
编辑:我一直在寻找替换数组内容的技术,基于来自其他数组的内容我在PHP中发现了这个功能正是我所需要的:{{ 3}}。现在我需要在Javascript / D3.js中使用它,但我似乎可以找到完全相同的解决方案或类似的解决方案。有什么想法吗?
答案 0 :(得分:4)
我认为最简单的方法是将id直接映射到您使用它的名称,如下所示:
svg.selectAll("text")
[...]
.text( function(d) { return namesMap[d.name]; });
假设namesMap
将node_id
转换为node_name
。
现在您只需要创建上述namesMap
,例如像这样:
d3.csv("nodes.csv", function(names) {
var namesMap = {};
names.forEach(function(d) {
namesMap[d.node_id] = d.node_name;
});
// code using namesMap goes here
});
this fiddle中提供了一个经过严格修改的代码(来自HTML中<pre>
个节点的csv数据加载)。