javascript - 偏移线描边重量 d3.js

标签 javascript d3.js

我正在使用 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/

相关文章:

javascript - 如何隐藏搜索栏上的结果表?

JavaScript:var 名称不是未定义的?

javascript - Nodejs主进程是否使用了所有CPU内存?

javascript - 如何在循环内设置超时

javascript - 是否有类似强制布局但支持点击事件的 D3 布局引擎

Javascript 对象 push() 函数

javascript - d3 缩放到边界框 II 缩放时滚动会引发错误

javascript - 适用于大型数据集的最佳力导向网络图引擎是什么?

javascript - 将信息显示到工具提示中

d3.js - C3.js将折线图Y轴的标签位置更改为Y轴居中