我正在使用 d3.js 在 map SVG 上绘制高速公路网络。我希望能够改变线条的笔划粗细,以说明基于值的需求。
高速公路链接被定义为单向,因此例如一条双向道路将有两个重叠的线元素(具有单独的 id)。我可以使用 stroke-weight 来根据变量编辑线条的粗细(如下所示),但在双向道路上,两个笔划粗细中较大的总是会覆盖较小的,使其不可见。
有没有一种简单的方法可以将线条的描边粗细的一半偏移到线条绘制方向的左侧? (方向由x1,y1 x2,y2表示)
d3.csv("links.csv", function (error, data) {
d3.select("#lines").selectAll("line")
.data(data)
.enter()
.append("line")
.each(function (d) {
d.p1 = projection([d.lng1, d.lat1]);
d.p2 = projection([d.lng2, d.lat2]);
})
.attr("x1", function (d) { return d.p1[0]; })
.attr("y1", function (d) { return d.p1[1]; })
.attr("x2", function (d) { return d.p2[0]; })
.attr("y2", function (d) { return d.p2[1]; })
.on('mouseover', tip_link.show)
.on('mouseout', tip_link.hide)
.style("stroke", "black")
.style("stroke-width", lineweight)
});
最佳答案
一种选择是在绘制线条时创建新的起点/终点并使用它们:
var offset = function(start,destination,distance) {
// find angle of line
var dx = destination[0] - start[0];
var dy = destination[1] - start[1];
var angle = Math.atan2(dy,dx);
// offset them:
var newStart = [
start[0] + Math.sin(angle-Math.PI)*distance,
start[1] + Math.cos(angle)*distance
];
var newDestination = [
destination[0] + Math.sin(angle-Math.PI)*distance,
destination[1] + Math.cos(angle)*distance
];
// return the new start/end points
return [newStart,newDestination]
}
此函数取两个点,并根据两点之间的 Angular 将它们偏移一个特定的量。负值向另一边移动,交换起点和终点将向另一边移动。
实际上,这看起来像,原始行是黑色的:
var offset = function(start,destination,distance) {
// find angle of line
var dx = destination[0] - start[0];
var dy = destination[1] - start[1];
var angle = Math.atan2(dy,dx);
// offset them:
var newStart = [
start[0] + Math.sin(angle-Math.PI)*distance,
start[1] + Math.cos(angle)*distance
];
var newDestination = [
destination[0] + Math.sin(angle-Math.PI)*distance,
destination[1] + Math.cos(angle)*distance
];
// return the new start/end points
return [newStart,newDestination]
}
var line = [
[10,10],
[200,100]
];
var svg = d3.select("svg");
// To avoid repetition:
function draw(selection) {
selection.attr("x1",function(d) { return d[0][0]; })
.attr("x2",function(d) { return d[1][0]; })
.attr("y1",function(d) { return d[0][1]; })
.attr("y2",function(d) { return d[1][1]; })
}
svg.append("line")
.datum(line)
.call(draw)
.attr("stroke","black")
.attr("stroke-width",1)
svg.append("line")
.datum(offset(...line,6))
.call(draw)
.attr("stroke","orange")
.attr("stroke-width",10)
svg.append("line")
.datum(offset(...line,-4))
.call(draw)
.attr("stroke","steelblue")
.attr("stroke-width",5)
<svg width="500" height="300"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
您需要根据您的数据结构调整它,并且它需要的行数是以前的两倍,因为您没有使用笔画宽度,而是使用了行数。如果您想使用 Canvas ,这是有利的。
关于javascript - 偏移线描边重量 d3.js,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54890472/