我只想对符合条件的数据进行更改。数据存储在一个看起来像这样的数组中。
我用此代码创建了每个圈子。
const circle = svg.append("g")
.selectAll("circle")
.data(nodes)
.join("circle")
.attr("cx", d => Math.floor((Math.random() * 650) + 1))
.attr("cy", d => Math.floor((Math.random() * 150) + 1))
.attr("fill", d => d.color)
.attr("r", d => d.r);
我正在尝试仅将更改应用于圈子的一部分
circle
.selectAll()
.transition()
.delay(5000)
.duration(5000)
.attr("cx", d => d.change == 1 ? randomIntFromInterval(1,650) : continue)
.attr("cy", d => d.change == 1 ? randomIntFromInterval(350,450) : continue)
但这给了我这个错误:SyntaxError: expected expression, got keyword 'continue'
是否有一种方法可以告诉D3对d.change == 1
处的值不执行任何操作?
我只想对数据的一个子集应用过渡。我有一个计时器函数,它以d3.timeout
递增。我想将change
更改为一个的节点移动到屏幕上的新位置,并将其余的节点留在原处。
nodes.forEach(function(o, i) {
o.timeleft -= 1;
// reset change
o.change = 0
if (o.timeleft == 0 && o.istage < o.stages.length - 1) {
groups[o.group].cnt -= 1;
o.istage += 1;
o.group = o.stages[o.istage].stage;
o.timeleft = o.stages[o.istage].quarters;
groups[o.group].cnt += 1;
o.change = 1
}
});
做到了。 (编辑:请参阅Gerardo Furtado的答案。这实际上是行不通的)
circle
.data(nodes.filter(d => d.change == 1))
.transition()
.delay(500)
.duration(500)
.attr("cx", d => randomIntFromInterval(1, 650))
.attr("cy", d => randomIntFromInterval(500, 600))
答案 0 :(得分:2)
首先,D3 是 JavaScript。您的标题毫无意义,因为您遇到的错误是JavaScript语法错误,与D3无关。
回到问题所在:在我的comment中,我谈论的是transition.filter
,而不是selection.filter
,甚至更少的是Array.prototype.filter
,这是您根据您已编辑的问题。
transition.filter
将...
对于每个选定的元素,仅选择与指定过滤器匹配的元素,并在结果选择上返回一个过渡。
因此,我们可以像这样使用它(只有前5个圆圈具有change: 1
):
const svg = d3.select("svg");
const data = d3.range(10).map(d=>({change:+(d<5)}));
const circles = svg.selectAll(null)
.data(data)
.enter()
.append("circle")
.attr("cx", 10)
.attr("r", 5)
.attr("cy", (_,i)=>10 + i*12)
.style("fill", "teal");
circles.transition()
.filter(d=>d.change === 1)
.duration(1000)
.attr("cx", 290);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>
三元运算符的另一种(相当丑陋的)替代方法是使用吸气剂:
.attr("cx", (d, i, n) => d.change === 1 ? 290 : d3.select(n[i]).attr("cx"));
这是演示:
const svg = d3.select("svg");
const data = d3.range(10).map(d => ({
change: +(d < 5)
}));
const circles = svg.selectAll(null)
.data(data)
.enter()
.append("circle")
.attr("cx", 10)
.attr("r", 5)
.attr("cy", (_, i) => 10 + i * 12)
.style("fill", "teal");
circles.transition()
.duration(1000)
.attr("cx", (d, i, n) => d.change === 1 ? 290 : d3.select(n[i]).attr("cx"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>