我已经查看了与此问题相关的其他SO问题,实施了解决方案,并且尚未取得成功。
我有一个由外部JSON文件驱动的d3强制定向图,该文件有五个属性:source,target,source_title,target_title和value。
JSON示例:
[{"source":"Michael Scott", "source_title":"boss", "target":"Jim Halpert", "target_title":"salesman", "value":"1"},
{"source":"Pam Beasley", "source_title":"receptionist", "target":"Jim Halpert", "target_title":"salesman", "value":"1"},
{"source":"Pam Beasley", "source_title":"receptionist", "target":"Angela", "target_title":"accountant", "value":"1"}]
当前脚本:
<script>
d3.json("IA_Data.json", function(error, data){
data.forEach(function(d) {
d.source_title = d.source_title;
});
var links = data;
var nodes = {};
// Compute the distinct nodes from the links.
links.forEach(function(link) {
link.source = nodes[link.source] || (nodes[link.source] = {name: link.source});
link.target = nodes[link.target] || (nodes[link.target] = {name: link.target});
});
var width = 2000,
height = 1000;
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(5)
.charge(-400)
.gravity(.2)
.on("tick", tick)
.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var path = svg.append("g").selectAll("path")
.data(force.links())
.enter().append("path")
.attr("class", function(d) { return "link " + d.type; })
.attr("marker-end", function(d) { return "url(#" + d.type + ")"; });
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {return d.source_title;});
svg.call(tip);
var circle = svg.append("g").selectAll("circle")
.data(force.nodes())
.enter().append("circle")
.attr("r", 6)
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
// Use elliptical arc path segments to doubly-encode directionality.
function tick() {
path.attr("d", linkArc);
circle.attr("transform", transform);
}
function linkArc(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}
function transform(d) {
return "translate(" + d.x + "," + d.y + ")";
}
});
</script>
如您所见,我正在尝试在d3.tip的.html行中返回value
。我最初尝试初始化value
的尝试在本节中:
data.forEach(function(d) {
d.source_title = +d.source_title;
});
生成的工具提示显示&#34; undefined&#34;,暗示source_title
未正确定义。如果我在d3.tip中将source_title
换成name
,则source
/ target
文字会显示在工具提示中。我该如何定义&#39; source_title&#39;属性正常吗?
非常感谢任何见解 - 谢谢!
答案 0 :(得分:2)
节点数组中没有source_title
。
解决方案很简单:在填充节点数组时创建该键/值对:
links.forEach(function(link) {
link.source = nodes[link.source] || (nodes[link.source] = {
name: link.source,
source_title: link.source_title//creating 'source_title' here
});
});
以下是您的代码演示(注意:这里只有两个圆圈有标题):
var data = [{
"source": "Michael Scott",
"source_title": "boss",
"target": "Jim Halpert",
"target_title": "salesman",
"value": "1"
}, {
"source": "Pam Beasley",
"source_title": "receptionist",
"target": "Jim Halpert",
"target_title": "salesman",
"value": "1"
}, {
"source": "Pam Beasley",
"source_title": "receptionist",
"target": "Angela",
"target_title": "accountant",
"value": "1"
}];
data.forEach(function(d) {
d.source_title = d.source_title;
});
var links = data;
var nodes = {};
// Compute the distinct nodes from the links.
links.forEach(function(link) {
link.source = nodes[link.source] || (nodes[link.source] = {
name: link.source,
source_title: link.source_title
});
link.target = nodes[link.target] || (nodes[link.target] = {
name: link.target,
target_title: link.target_title
});
});
var width = 300,
height = 150;
var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkDistance(5)
.charge(-400)
.gravity(.2)
.on("tick", tick)
.start();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var path = svg.append("g").selectAll("ceciliaPayne")
.data(force.links())
.enter().append("path")
.attr("class", function(d) {
return "link " + d.type;
})
.attr("marker-end", function(d) {
return "url(#" + d.type + ")";
});
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return d.source_title;
});
svg.call(tip);
var circle = svg.append("g").selectAll("circle")
.data(force.nodes())
.enter().append("circle")
.attr("r", 6)
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
// Use elliptical arc path segments to doubly-encode directionality.
function tick() {
path.attr("d", linkArc);
circle.attr("transform", transform);
}
function linkArc(d) {
var dx = d.target.x - d.source.x,
dy = d.target.y - d.source.y,
dr = Math.sqrt(dx * dx + dy * dy);
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
}
function transform(d) {
return "translate(" + d.x + "," + d.y + ")";
}
path {
fill: none;
stroke: black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.7.1/d3-tip.min.js"></script>