d3力中的阵列和节点映射
arrays and nodes mapping in d3 force
假设在d3中,我有两个数据数组,如下所示:
节点:
var nodes = [
{"name": "abc", "type": "Db"},
{"name": "def", "type": "Db"},
{"name": "ghi", "type": "Db"},
{"name": "jkl", "type": "Db"}
]
链接:
var links = [
{source: nodes[0], target: nodes[1]},
{source: nodes[0], target: nodes[2]},
{source: nodes[1], target: nodes[3]}
]
有没有办法用名字代替数字?像这样:
var links = [
{source: nodes["abc"], target: nodes["def"]},
{source: nodes["abc"], target: nodes["ghi"]},
{source: nodes["def"], target: nodes["jkl"]}
]
但是得到这个错误:
未捕获的类型错误:无法读取未定义的属性"x"
此处:
link.attr("x1", function(d) { return d.source.x; })
这是完整的代码:
<!doctype html>
<html>
<head>
<title>D3 tutorial</title>
<script src="https://d3js.org/d3.v3.min.js"></script>
</head>
<body>
<script>
var w = 4000,
h = 4000;
var circleWidth = 5;
var fontFamily = 'Bree Serif',
fontSizeHighlight = '1.5em',
fontSizeNormal = '1em';
var palette = {
"lightgray": "#819090",
"gray": "#708284",
"mediumgray": "#536870",
"darkgray": "#475B62",
"darkblue": "#0A2933",
"darkerblue": "#042029",
"paleryellow": "#FCF4DC",
"paleyellow": "#EAE3CB",
"yellow": "#A57706",
"orange": "#BD3613",
"red": "#D11C24",
"pink": "#C61C6F",
"purple": "#595AB7",
"blue": "#2176C7",
"green": "#259286",
"yellowgreen": "#738A05"
}
var nodes = [
{"name": "abc", "type": "Db"},
{"name": "def", "type": "Db"},
{"name": "ghi", "type": "Db"},
{"name": "jkl", "type": "Db"}
]
var links = [
{source: nodes["abc"], target: nodes["def"]},
{source: nodes["abc"], target: nodes["ghi"]},
{source: nodes["def"], target: nodes["jkl"]}
]
var vis = d3.select("body")
.append("svg:svg")
.attr("class", "stage")
.attr("width", w)
.attr("height", h);
var force = d3.layout.force()
.nodes(nodes)
.links([])
.gravity(0.1)
.charge(-1000)
.size([w, h]);
var link = vis.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.attr("stroke", "#CCC")
.attr("fill", "none");
var node = vis.selectAll("circle.node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
//MOUSEOVER
.on("mouseover", function(d,i) {
if (i>0) {
//CIRCLE
d3.select(this).selectAll("circle")
.transition()
.duration(250)
.style("cursor", "none")
.attr("r", circleWidth+3)
.attr("fill",palette.black);
//TEXT
d3.select(this).select("text")
.transition()
.style("cursor", "none")
.duration(250)
.style("cursor", "none")
.attr("font-size","1.5em")
.attr("x", 15 )
.attr("y", 5 )
.text(function(d) { return d.name + "_" + d.type; })
} else {
//CIRCLE
d3.select(this).selectAll("circle")
.style("cursor", "none")
//TEXT
d3.select(this).select("text")
.style("cursor", "none")
}
})
//MOUSEOUT
.on("mouseout", function(d,i) {
if (i>0) {
//CIRCLE
d3.select(this).selectAll("circle")
.transition()
.duration(250)
.attr("r", circleWidth)
.attr("fill",palette.pink);
//TEXT
d3.select(this).select("text")
.transition()
.duration(250)
.attr("font-size","1em")
.attr("x", 8 )
.attr("y", 4 )
.text(function(d) { return d.name; })
}
})
.call(force.drag);
//CIRCLE
node.append("svg:circle")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", circleWidth)
.attr("fill", function(d, i) { if (i>0) { return palette.pink; } else { return palette.black } } )
//TEXT
node.append("text")
.text(function(d, i) { return d.name; })
.attr("x", function(d, i) { if (i>0) { return circleWidth + 5; } else { return -10 } })
.attr("y", function(d, i) { if (i>0) { return circleWidth + 0 } else { return 8 } })
.attr("font-family", "Bree Serif")
.attr("fill", function(d, i) { if (i>0) { return palette.black; } else { return palette.black } })
.attr("font-size", function(d, i) { if (i>0) { return "1em"; } else { return "1.8em" } })
.attr("text-anchor", function(d, i) { if (i>0) { return "beginning"; } else { return "end" } })
force.on("tick", function(e) {
node.attr("transform", function(d, i) {
return "translate(" + d.x + "," + d.y + ")";
});
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; })
});
force.start();
</script>
</body>
</html>
使节点成为一个对象,每个名称都作为一个属性/键:
var nodes = {
abc: {"name": "abc", "type": "Db"},
def: {"name": "def", "type": "Db"},
ghi: {"name": "ghi", "type": "Db"},
jkl: {"name": "jkl", "type": "Db"}
}
数组只能由索引(即array[3])访问,对象可以由属性访问(即object["propertyName"]
或object.propertyName
)。
它返回undefined
,因为方括号内的数字是数组内对象(在这种特殊情况下)的索引。使用nodes[0]
时,引用的是数组nodes
中的第一个对象(索引为零,即0是第一个对象,1是第二个对象,依此类推)。
如果您想引用关键字name
的值为"abc"的对象,您必须首先找到它。请看这个答案:
如何在javascript 中通过对象的属性获取对象的索引
相关文章:
- 如何在映射数组中添加换行符
- 节点导出返回一个空对象
- 可以前端maven插件使用节点,npm已经安装
- ng映射方向备选方案
- 在jstree中,如何将指定的节点集中到大型树上
- d3力中的阵列和节点映射
- 创建键/值映射开发/生产节点.js的最佳实践
- D3.js节点映射中的缩放功能
- 反应谷歌地图节点模块映射样式加载空对象,而不是JSON
- 使用d3树映射可以在点击父节点到子节点时转到子节点
- 树映射高亮显示子节点D3
- Knockout,映射插件,将子节点附加到父元素
- DOM节点引用的IE8兼容漏洞映射
- 在ES6中过滤或映射节点器
- 如何在d3教程中映射节点对象到节点id
- 可以在节点运行时执行期间输出coffeescript源映射(未预编译)
- 将节点映射到数据
- jQuery .remove() vs Node.removeChild() 和外部映射到 DOM 节点
- 将XML节点映射到HTML表单元素
- 使用映射或模板在节点流中转换JSON