我在d3中有一个力导向图,并希望能够点击圆形节点并将它们变成矩形。然后,如果我点击一个矩形,我希望它恢复为圆形。
我已经查看了this以及有关SO的相关问题,但我认为它们适用于早期版本的D3,并且不适用于我。
我可以这样做,所以我的圆圈的大小和颜色会随着点击而改变,并且使用以下代码我可以将圆形节点替换为黑色矩形,但是它没有附加到图形而只是黑色在svg上的广场。
node.on("click", function(d,i) {
var size = 20;
d3.select(this).remove();
svg.append("rect")
.attr("x", d.x)
.attr("y", d.y)
.attr("height", size)
.attr("width", size)
.style("fill", function(d) {
return color( d.group);
});
})
谁能告诉我我缺少的东西?我怀疑rect
没有附加到图表数据上,但我不熟悉d3以了解我应该改变什么。谢谢。
答案 0 :(得分:3)
当你说:
时没用我已经在SO上查看了这个问题和相关问题,但我认为它们适用于早期版本的D3,并且对我不起作用。
在我看来that answer中没有任何内容表明它在D3 v4.x中不起作用。值得一提的是,在您链接的答案(和问题)中,node
是一个组元素,因此this
指的是组,而不是圆/矩形。< / p>
继续,一个可能的解决方案(不涉及删除和附加元素)是模拟一个带有矩形的圆圈:
node.append("rect")
.attr("width", 16)
.attr("height", 16)
.attr("rx", 8)
.attr("ry", 8)
并且,在点击功能中,更改rx
和ry
:
function click() {
if(d3.select(this).attr("rx") == 8){
d3.select(this).attr("rx", 0).attr("ry", 0);
} else {
d3.select(this).attr("rx", 8).attr("ry", 8);};
};
这是一个演示:
var nodes = [
{"id": 1},
{"id": 2},
{"id": 3},
{"id": 4},
{"id": 5},
{"id": 6},
{"id": 7},
{"id": 8},
{"id": 9},
{"id": 10},
{"id": 11},
{"id": 12}
];
var links = [
{source: 1, target: 8},
{source: 1, target: 3},
{source: 1, target: 4},
{source: 1, target: 9},
{source: 1, target: 10},
{source: 1, target: 11},
{source: 2, target: 5},
{source: 2, target: 6},
{source: 2, target: 7},
{source: 2, target: 12},
{source: 2, target: 4},
{source: 2, target: 8},
{source: 6, target: 7},
{source: 6, target: 8},
{source: 6, target: 9},
{source: 6, target: 5},
{source: 6, target: 3},
{source: 6, target: 9},
]
var index = 10;
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
node,
link;
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) { return d.id; }))
.force("charge", d3.forceManyBody())
.force("collide", d3.forceCollide(30))
.force("center", d3.forceCenter(width / 2, height / 2));
update();
function update() {
link = svg.selectAll(".link")
.data(links, function(d) { return d.target.id; })
link = link.enter()
.append("line")
.attr("class", "link");
node = svg.selectAll(".node")
.data(nodes, function(d) { return d.id; })
node = node.enter()
.append("g")
.attr("class", "node");
node.append("rect")
.attr("width", 16)
.attr("height", 16)
.attr("rx", 8)
.attr("ry", 8)
.attr("fill", "teal")
.on("click", click);
simulation
.nodes(nodes)
.on("tick", ticked);
simulation.force("link")
.links(links);
}
function click() {
if(d3.select(this).attr("rx") == 8){d3.select(this).attr("rx", 0).attr("ry", 0);}
else{d3.select(this).attr("rx", 8).attr("ry", 8);};
}
function ticked() {
link
.attr("x1", function(d) { return d.source.x + 8; })
.attr("y1", function(d) { return d.source.y + 8; })
.attr("x2", function(d) { return d.target.x+ 8; })
.attr("y2", function(d) { return d.target.y+ 8; });
node
.attr("transform", function(d) { return "translate(" + d.x + ", " + d.y + ")"; });
}
&#13;
.link {
stroke: #aaa;
}
.node {
stroke: none;
stroke-width: 40px;
}
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="400" height="300"></svg>
&#13;