如何在 D3.js 中绘制一个只有 2 个坐标的矩形

moe*_*moe 1 svg d3.js

我正在学习 D3.js 并将使用它来绘制简单的线条和矩形。我的问题是,我使用的是用于 RPG 的数据。因此,对于矩形 RPG 只需要 2 个点,它将使用该对角线来完成矩形。我没有高度或宽度只有 2 个坐标。有没有办法只使用 2 个点在 D3 中绘制一个矩形?

Ger*_*ado 6

由于您有两个点(坐标),因此任务很简单:

对于xy位置,使用第一个点。对于矩形的widthheight,只需分别计算x2 - x1y2 - y1

这是一个包含三个矩形的演示。在数据数组中,每个对象有4个属性,分别对应两个点(这只是一个例子,你可以根据你的数据结构更改代码):

var svg = d3.select("body")
	.append("svg")
	.attr("width", 400)
	.attr("height", 200);
	
var data = [{x1: 20, x2: 60, y1: 30, y2: 50},
{x1: 50, x2: 80, y1: 100, y2: 150},
{x1: 200, x2: 400, y1: 10, y2: 100}];

var rects = svg.selectAll("foo")
	.data(data)
	.enter()
	.append("rect")
	.attr("x", d=> d.x1)
	.attr("y", d=> d.y1)
	.attr("width", d=> d.x2 - d.x1)
	.attr("height", d=> d.y2 - d.y1)
	.attr("fill", "teal");
Run Code Online (Sandbox Code Playgroud)
<script src="https://d3js.org/d3.v4.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

这是相同的原理,但数据包含两个数组,第一个数组是第一个点,第二个数组是第二个点:

var svg = d3.select("body")
	.append("svg")
	.attr("width", 400)
	.attr("height", 200);
	
var data = [[[20,30],[40,50]], [[50,100],[80,150]], [[200,30],[400,100]]];

var rects = svg.selectAll("foo")
	.data(data)
	.enter()
	.append("rect")
	.attr("x", d=> d[0][0])
	.attr("y", d=> d[0][1])
	.attr("width", d=> d[1][0] - d[0][0])
	.attr("height", d=> d[1][1] - d[0][1])
	.attr("fill", "teal");
Run Code Online (Sandbox Code Playgroud)
<script src="https://d3js.org/d3.v4.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

要使上述两个代码段都起作用,数据必须具有以下顺序的坐标:首先是左上角的点,然后是右下角的点。当然,您可以编写一个函数来检查这一点,如果顺序不正确,则交换点数。

要绘制对角线,只需选择您想要的点。例如,从左上角到右下角:

var svg = d3.select("body")
	.append("svg")
	.attr("width", 400)
	.attr("height", 200);
	
var data = [{x1: 20, x2: 60, y1: 30, y2: 50},
{x1: 50, x2: 80, y1: 100, y2: 150},
{x1: 200, x2: 400, y1: 10, y2: 100}];

var rects = svg.selectAll("foo")
	.data(data)
	.enter()
	.append("rect")
	.attr("x", d=> d.x1)
	.attr("y", d=> d.y1)
	.attr("width", d=> d.x2 - d.x1)
	.attr("height", d=> d.y2 - d.y1)
	.attr("fill", "teal")
	.attr("opacity", 0.3);
  
var lines = svg.selectAll("foo")
	.data(data)
	.enter()
	.append("line")
	.attr("x1", d=> d.x1)
	.attr("y1", d=> d.y1)
	.attr("x2", d=> d.x2)
	.attr("y2", d=> d.y2)
	.attr("stroke", "firebrick")
	.attr("stroke-width", 2);
Run Code Online (Sandbox Code Playgroud)
<script src="https://d3js.org/d3.v4.min.js"></script>
Run Code Online (Sandbox Code Playgroud)