gpt4 book ai didi

javascript - 如何使用画笔选择D3.js中多个组元素中包含的圆圈?

转载 作者:行者123 更新时间:2023-12-03 08:45:24 28 4
gpt4 key购买 nike

我正在绘制散点图。图中的圆圈包含在多个组元素内。

我正在尝试使用brush选择属于我画笔范围的圆圈。但 Brushend 函数中的参数给出的是单个组的数据。

如何更改代码,以便 Brushend 函数知道哪些组被刷过,而无需迭代图中的所有圆圈?

<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>

#plot {
border-style: solid;
border-width: 4px;
border-color: lightgrey;
display: inline-block;
line-height: 0;
}

.extent {
fill: grey;
fill-opacity: 0.5;
stroke: black;
stroke-width: 1px;
}

</style>
<script type="text/javascript" src="d3.js"></script>
</head>

<body>
<div id=plot>
<script>

(function() {
var data = [];

for (i = 0; i < 100; i++) {
var x = Math.floor(Math.random() * 100) + 1;
var y = Math.floor(Math.random() * 100) + 1;
var c = Math.random();

if (c < 0.33) c = "red";
else if (c < 0.66) c = "green";
else c = "blue";

data.push({x: x, y: y, c: c});
}

data = d3.nest()
.key(function(d) { return d.c })
.entries(data);

var svg = d3.select("#plot").append("svg")
.attr("width", 400)
.attr("height", 400)
.selectAll("scatter")
.data(data)
.enter().append("g")
.each(scatter);

var xScale = d3.scale.linear()
.domain([0, 100])
.range([0, 400]);

var yScale = d3.scale.linear()
.domain([0, 100])
.range([400, 0]);

var brush = d3.svg.brush()
.x(xScale)
.y(yScale)
.on("brushend", brushend);

svg.call(brush);

function brushend(d) {
}

})();

function scatter(d) {
var g = d3.select(this);

var xScale = d3.scale.linear()
.domain([0, 100])
.range([0, 400]);

var yScale = d3.scale.linear()
.domain([0, 100])
.range([400, 0]);

g.selectAll("circle")
.data(d.values)
.enter().append("circle")
.attr("r", 4)
.attr("cx", function(d) { return xScale(d.x) })
.attr("cy", function(d) { return yScale(d.y) })
.attr("fill", function(d) { return d.c });
}

</script>
</div>
</body>
</html>

编辑:我意识到画笔不能跨组元素工作,因此我接受了一个不使用传递给 Brushend 函数的参数的答案。

最佳答案

您可以通过稍微更改 brushend 函数来实现此目的。 brush.extent() 函数返回画笔选择的障碍,您需要做的是选择所有位于这些障碍之间的障碍。

  function brushend(d) {
var e = brush.extent();
svg.selectAll("circle")
.classed("hidden", function(d) {
if(e[0][0] < d.x && d.x < e[1][0]
&& e[0][1] < d.y && d.y < e[1][1]) {
console.log(d);
}
return e[0][0] < d.x && d.x < e[1][0]
&& e[0][1] < d.y && d.y < e[1][1]; });
}
})();

我知道这不是处理这个问题的最优雅的方法,但我会寻找一种更好的方法来选择具有该功能的圆圈,然后编辑我的答案。我现在希望此更改将允许您将所选内容中的所有圆圈记录到控制台。

编辑我找到了一个不需要将类应用于所有内容的解决方案,并且我非常确定它可以正常工作。然而,它并不漂亮,因为 brush.extent() 和圈子的 cxcy 属性的工作方式不同。从外面看,它应该看起来不错。

  function brushend(d) {
var e = brush.extent();
var circles = svg.selectAll("circle");
var ae00 = e[0][0]*4; //The cx and cy values are 4 times as big
var ae10 = e[1][0]*4;
var ae01 = 400 - e[0][1]*4; //revert the y values, so 0 is at the top
var ae11 = 400 - e[1][1]*4;
for(var j = 0; j < 3; j ++) {
for (var i = 0; i < circles[j].length; i++) {
if(ae00 < circles[j][i].cx.animVal.value && circles[j][i].cx.animVal.value < ae10
&& ae01 > circles[j][i].cy.animVal.value && circles[j][i].cy.animVal.value > ae11) {
console.log(circles[j][i]);
}
}
}
}

关于javascript - 如何使用画笔选择D3.js中多个组元素中包含的圆圈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32911299/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com