在 D3 中的位置内定位节点

  • 本文关键字:定位 节点 位置 D3 d3.js
  • 更新时间 :
  • 英文 :


如何在包含节点的 SVG 元素中定义位置?我正在尝试创建一个抽象地图,其中节点包含在使用 D3 的位置中。然后,节点将链接到其他节点(有时同一位置+/或其他位置的许多节点)。

因此,示例数据可能如下所示:

{"nodes":[
    {"id": "a", "location": "1"},
    {"id": "b", "location": "1"},
    {"id": "c", "location": "2"},
    {"id": "d", "location": "2"},
    {"id": "e", "location": "3"},
    {"id": "f", "location": "3"},
    {"id": "g", "location": "4"},
    {"id": "h", "location": "4"}]
}

我想创建 4 个矩形/气泡,每个矩形/气泡有 2 个节点(圆形)。我是 D3 的新手,猜我正在努力从简单的数据集到 JSON 对象。很抱歉,如果我错过了显而易见的内容。

如果要创建力导向图,则可以使用forceXforceY来排列屏幕中的节点。根据 API:

x 和 y 定位力以可配置的强度将节点沿给定尺寸推向所需位置。力的强度与节点位置与目标位置之间的一维距离成正比。

在此演示中,我将根据 location 获取您的数据数组并在 x 坐标中定位。首先,我设置一个比例:

var xScale = d3.scalePoint()
    .domain([1, 2, 3, 4])
    .range([100, width - 100]);

并在forceX中使用此比例:

var force = d3.forceSimulation(data)
    .force('x', d3.forceX((d) => xScale(d.location)).strength(2))

这是一个演示:

var data = [{
    "id": "a",
    "location": "1"
}, {
    "id": "b",
    "location": "1"
}, {
    "id": "c",
    "location": "2"
}, {
    "id": "d",
    "location": "2"
}, {
    "id": "e",
    "location": "3"
}, {
    "id": "f",
    "location": "3"
}, {
    "id": "g",
    "location": "4"
}, {
    "id": "h",
    "location": "4"
}];
var width = 500,
    height = 200;
var color = d3.scaleOrdinal(d3.schemeCategory10);
var svg = d3.select("body")
    .append("svg")
    .attr("width", width)
    .attr("height", height);
var xScale = d3.scalePoint()
    .domain([1, 2, 3, 4])
    .range([100, width - 100]);
var circles = svg.selectAll(".bigCircles")
	.data(xScale.domain())
	.enter()
	.append("circle")
	.attr("cx", d=>xScale(d))
	.attr("cy", height/2)
	.attr("fill", d=>color(d))
	.attr("r", 40)
	.attr("opacity", 0.2);
var node = svg.selectAll(".circles")
    .data(data)
    .enter().append("circle")
    .attr("r", 10)
    .attr("fill", (d) => color(d.location));
var force = d3.forceSimulation(data)
    .force('x', d3.forceX((d) => xScale(d.location)).strength(2))
    .force('center', d3.forceCenter(width / 2, height / 2))
    .force("collide", d3.forceCollide(12));
force.nodes(data)
    .on('tick', function() {
        node
            .attr('transform', (d) => {
                return 'translate(' + (d.x) + ',' + (d.y) + ')';
            });
    });
<script src="https://d3js.org/d3.v4.min.js"></script>

最新更新