【发布时间】:2017-03-01 23:38:28
【问题描述】:
我有一个功能齐全的强制有向图。我正在尝试使用方向箭头。
每个节点的大小与其入度和出度成正比,链接的粗细根据以下链接属性而变化:
.attr("stroke-width",function(d) {return d.total_amt/60;})
我试图让箭头与笔划宽度和节点大小成比例。
不能选择使用多个标记,因为不知道笔画宽度的变化,因为它取决于链接属性之一的 d.total_amount。
所以我试图用数学方法计算线的 x2 和 y2 值:
var nodeRadius = 20;
var lineX2 = function (d) {
var length = Math.sqrt(Math.pow(d.target.y - d.source.y, 2) + Math.pow(d.target.x - d.source.x, 2));
var scale = (length - nodeRadius) / length;
var offset = (d.target.x - d.source.x) - (d.target.x - d.source.x) * scale;
return d.target.x - offset;
};
var lineY2 = function (d) {
var length = Math.sqrt(Math.pow(d.target.y - d.source.y, 2) + Math.pow(d.target.x - d.source.x, 2));
var scale = (length - nodeRadius) / length;
var offset = (d.target.y - d.source.y) - (d.target.y - d.source.y) * scale;
return d.target.y - offset;
};
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(d3GraphData.links)
.enter().append("line")
.attr("stroke-width",function(d) {return d.total_amt/60;})
.attr("class", "link")
.attr("x1", function (d) {
return d.source.x;
})
.attr("y1", function (d) {
return d.source.y;
})
.attr("x2", lineX2)
.attr("y2", lineY2)
.attr("marker-end", "url(#end)")
下面是使用 lineX2 和 lineY2
的节点的刻度函数 function ticked() {
link
.attr("x1", function(d) {
return d.source.x;
})
.attr("y1", function(d) {
return d.source.y;
})
.attr("x2", lineX2)
.attr("y2", lineY2)
node
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
}
下面是标记定义:
svg.append("svg:defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("svg:marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 0 10 10")
.attr("refX", "4")
.attr("refY", "3")
.attr("markerUnits", "strokeWidth")
.attr("markerWidth", "7")
.attr("markerHeight", "2")
.attr("orient", "auto")
.append("svg:path")
.attr("d", "M 0 0 L 10 5 L 0 10 z")
现在这似乎在箭头似乎与边缘厚度成比例的情况下部分起作用。
但是当节点大小较小时,箭头似乎不会接触节点的外边缘并且会更早终止。
我确实尝试在 lineX2 和 lineY2 的计算中使用 d3.scaleLinear() 而不是 nodeRadius但这使得整个图表非常奇怪。
var minRadius = 5
var maxRadius = 20
var scale = (length - d3.scaleLinear().range([minRadius,maxRadius])) / length
此外,即使箭头似乎与边缘厚度成正比,控制台仍然会抛出以下错误:
Error: <line> attribute x2: Expected length, "NaN".
(anonymous) @ d3.v4.min.js:2
797d3.v4.min.js:2 Error: <line> attribute y2: Expected length, "NaN".
下面是演示问题的fiddle
【问题讨论】:
-
不是完全重复,但类似于问题I answered here
-
我明天去看看。但是一看,我发现您使用的 .Weight 属性在 d3 v4 中无效。
标签: javascript d3.js