如何在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对象。很抱歉,如果我错过了显而易见的事情。
答案 0 :(得分:2)
如果您要创建强制定向图表,则可以使用forceX
和forceY
来排列屏幕中的节点。根据{{3}}:
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>