我正在尝试在力有向图上实现标记边缘。
我使用的例子可以在这里找到。
示例中的相关代码位在此处给出。
我的代码如下:
<style>
.node {
stroke: #fff;
stroke-width: 0.5px;
}
.node text {
pointer-events: none;
font: 15px helvetica;
}
.link {
fill: none;
stroke: #bbb;
stroke-width: 3.0px;
opacity: 0.5;
}
.highlight {
stroke: #259359;
}
</style>
<body>
<script src= "//d3js.org/d3.v3.min.js" > </script>
<script>
var width = 700,
height = 550;
var color = d3.scale.category20();
var force = d3.layout.force()
.linkStrength(1)
.distance(0.01)
.gravity(0.2)
.charge(-500)
.size([width, height]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 16)
.attr("refY", 0)
.attr("markerWidth", 3)
.attr("markerHeight", 3)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5")
.style("stroke", "#bbb");
d3.json("fg.json", function(error, graph) {
if (error) throw error;
var nodes = graph.nodes.slice(),
links = [],
bilinks = [];
graph.links.forEach(function(link) {
var s = nodes[link.source],
t = nodes[link.target],
i = {}; // intermediate node
nodes.push(i);
links.push({
source: s,
target: i
}, {
source: i,
target: t
});
bilinks.push([s, i, t]);
});
force
.nodes(nodes)
.links(links)
.size([width, height])
.start();
var link = svg.selectAll(".link")
.data(bilinks)
.enter().append("path")
.attr("class", "link")
.style("marker-end", "url(#end)")
.on("mouseover", function() {
d3.select(d3.event.target).classed("highlight", true);
})
.on("mouseout", function() {
d3.select(d3.event.target).classed("highlight", false);
});
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.call(force.drag)
node.append("circle")
.attr("r", 8)
.style("fill", function(d) {
return color(d.group);
})
node.append("text")
.attr("dx", 15)
.attr("dy", ".40em")
.text(function(d) {
return d.name
})
.style("stroke", "gray");
//
var padding = 30, // separation between circles
radius = 1;
function collide(alpha) {
var quadtree = d3.geom.quadtree(graph.nodes);
return function(d) {
var rb = 2 * radius + padding,
nx1 = d.x - rb,
nx2 = d.x + rb,
ny1 = d.y - rb,
ny2 = d.y + rb;
quadtree.visit(function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== d)) {
var x = d.x - quad.point.x,
y = d.y - quad.point.y,
l = Math.sqrt(x * x + y * y);
if (l < rb) {
l = (l - rb) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
});
};
}
var edgepaths = svg.selectAll(".edgepath")
.data(graph.links)
.enter()
.append('path')
.attr({'d': function(d) {return 'M '+d.source.x+' '+d.source.y+' L '+ d.target.x +' '+d.target.y},
'class':'edgepath',
'fill-opacity':0,
'stroke-opacity':0,
'fill':'blue',
'stroke':'red',
'id':function(d,i) {return 'edgepath'+i}})
.style("pointer-events", "none");
var edgelabels = svg.selectAll(".edgelabel")
.data(graph.links)
.enter()
.append('text')
.style("pointer-events", "none")
.attr({'class':'edgelabel',
'id':function(d,i){return 'edgelabel'+i},
'dx':80,
'dy':0,
'font-size':10,
'fill':'#aaa'});
edgelabels.append('textPath')
.attr('xlink:href',function(d,i) {return '#edgepath'+i})
.style("pointer-events", "none")
.text(function(d,i){return 'label '+i});
force.on("tick", function() {
link.attr("d", function(d) {
return "M" + d[0].x + "," + d[0].y + "S" + d[1].x + "," + d[1].y + " " + d[2].x + "," + d[2].y;
});
node.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
edgepaths.attr('d', function(d) { var path='M '+d.source.x+' '+d.source.y+' L '+ d.target.x +' '+d.target.y;
return path});
edgelabels.attr('transform',function(d,i){
if (d.target.x<d.source.x){
bbox = this.getBBox();
rx = bbox.x+bbox.width/2;
ry = bbox.y+bbox.height/2;
return 'rotate(180 '+rx+' '+ry+')';
}
else {
return 'rotate(0)';
}
});
node.each(collide(0.5));
});
});
</script>
数据如下:
{
"nodes":[
{"name":"alkene","group":1},
{"name":"alkane","group":1},
{"name":"halogenoalkane","group":2},
{"name":"dihalogenoalkane","group":2},
{"name":"amine","group":3},
{"name":"alcohol","group":4},
{"name":"ketone","group":5},
{"name":"aldehyde","group":6},
{"name":"hydroxynitrile","group":7},
{"name":"ester","group":8},
{"name":"carboxylic acid","group":9},
{"name":"acyl chloride","group":9},
{"name":"amide","group":10},
{"name":"nitrile","group":11}
],
"links":[
{"source":0,"target":2,"value":2},
{"source":0,"target":1,"value":1},
{"source":2,"target":0,"value":8},
{"source":0,"target":3,"value":10},
{"source":2,"target":4,"value":10},
{"source":5,"target":2,"value":1},
{"source":2,"target":5,"value":1},
{"source":6,"target":5,"value":1},
{"source":5,"target":6,"value":1},
{"source":7,"target":5,"value":1},
{"source":5,"target":7,"value":1},
{"source":7,"target":8,"value":2},
{"source":7,"target":10,"value":1},
{"source":10,"target":7,"value":1},
{"source":5,"target":9,"value":3},
{"source":10,"target":9,"value":3},
{"source":13,"target":10,"value":5},
{"source":10,"target":11,"value":1},
{"source":11,"target":10,"value":1},
{"source":11,"target":12,"value":1}
]
}
不幸的是,图表上的标签不可见。
最终目标是在每条边上显示相应的值“值”。
你能告诉我我做错了什么吗?
感谢您的时间。
更新
通过涂底液成功地将标签添加到边缘
"M" + d[0].x + "," + d[0].y + "S" + d[1].x + "," + d[1].y + " " + d[2].x + "," + d[2].y
为了
'M '+d.source.x+' '+d.source.y+' L '+ d.target.x +' '+d.target.y
但是,问题仍然存在:如何添加“值”数据而不是标签“标签 i”?此外,它们在鼠标悬停时的外观如何实现?
更新二
通过为边缘标签的 textPath 定义 .data(graph.links) 然后返回 d.value 来显示“值”数据。你能告诉我鼠标悬停是如何实现的吗?如果每条边的“值”数据只能在悬停时看到,那就太好了。谢谢!