我想知道是否有办法改变Scatter图的刷新速度? 正如你在这个link中看到的那样,散点图得到了更新,但是外观和消失之间的时间间隔是不合理的,看起来它们是闪烁的点......我试着移动circle.remove()函数吧在circle.transition之上,但没有区别。
以下是刷新功能的相关代码。谢谢!
function updateData() {
// Get the data again
data = d3.json("2301data.php", function(error, data) {
data.forEach(function(d) {
d.dtg = parseDate(d.dtg);
d.temperature = +d.temperature;
// d.hum = +d.hum; // Addon 9 part 3
});
// Scale the range of the data again
x.domain(d3.extent(data, function(d) { return d.dtg; }));
y.domain([0, 60]);
var svg = d3.select("#chart1").select("svg").select("g");
svg.select(".x.axis") // change the x axis
.transition()
.duration(750)
.call(xAxis);
svg.select(".y.axis") // change the y axis
.transition()
.duration(750)
.call(yAxis);
svg.select(".line") // change the line
.transition()
.duration(750)
.attr("d", valueline(data));
var circle = svg.selectAll("circle").data(data);
circle.remove() //remove old dots
// enter new circles
circle.enter()
.append("circle")
.filter(function(d) { return d.temperature > 35 })
.style("fill", "red")
.attr("r", 3.5)
.attr("cx", function(d) { return x(d.dtg); })
.attr("cy", function(d) { return y(d.temperature); })
// Tooltip stuff after this
.on("mouseover", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
div.transition()
.duration(200)
.style("opacity", .9);
div .html(
d.temperature + "C" + "<br>" +
formatTime(d.dtg))
.style("left", (d3.event.pageX + 8) + "px")
.style("top", (d3.event.pageY - 18) + "px");})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
circle.transition().attr("cx", function(d) { return x(d.dtg); });
// exit
circle.exit();
});
}
答案 0 :(得分:1)
在运行时查看示例,您似乎在dom中加载的圈数多于可见的圈数。这是因为您为所有数据添加了圈子,但只为那些符合您设置的过滤条件的人提供了位置。
前几天有关于数据过滤与d3过滤的相关问题 - Filtering data to conditionally render elements。如果你不想添加完整的东西,请使用数据过滤,如果你想隔离一些元素进行特殊处理(过渡,不同的样式等),请使用d3.filter。
此时,您在添加所有圈子后对d3选择进行过滤,但在您的情况下,我建议在数据到达该阶段之前对其进行过滤是最好的(并且正如其他人所建议的那样)那个问题)。这可能会让它运行得更快(但你的例子看起来也是由db更新的摆布?)
data = data.filter (function(d) { return d.temperature > 35; }); // do filtering here
var circle = svg.selectAll("circle").data(data);
circle.exit().remove() //remove old dots
// enter new circles
circle.enter()
.append("circle")
.style("fill", "red")
.attr("r", 3.5)
.attr("cx", function(d) { return x(d.dtg); })
.attr("cy", function(d) { return y(d.temperature); })
...
PS。您尝试使用circle.remove()和circle.exit()时会有点混乱。 circle.remove()将删除所有现有的圆圈(即使是存在的圆圈并拥有新数据),最后的circle.exit()将无效。我只是使用circle.exit()。remove()来替换你所做的两个调用。
此外,如果没有关键功能 - https://bost.ocks.org/mike/constancy/ - 在你的.data()调用中,你可能会发现点移动了一下。如果您的数据点有ID,请使用它们。
var circle = svg.selectAll("circle").data(data, function(d) { return d.id; /* or d.dtg+" "+d.temperature; if no id property */});