Javascript 修改数据源时,D3停止打印点
我正在用D3从实时数据流中绘制英国地图上的点。当数据点超过10000时,浏览器将变得迟钝,动画不再平滑。因此,我修改了Javascript 修改数据源时,D3停止打印点,javascript,d3.js,plot,Javascript,D3.js,Plot,我正在用D3从实时数据流中绘制英国地图上的点。当数据点超过10000时,浏览器将变得迟钝,动画不再平滑。因此,我修改了dataPoints数组,只保留最后5000个点 但是,当我第一次使用splice()D3修改dataPoints时,将停止渲染任何新点。旧点逐渐消失(由于过渡),但没有新点。我不确定我在这里做错了什么 我模拟了这个问题,加载CSV数据并将其存储在内存中,并以每100ms 1点的速度绘制它们。一旦点数超过10,我将拼接以保留最后5个点。我看到了同样的行为。有人能检查一下代码,让我
dataPoints
数组,只保留最后5000个点
但是,当我第一次使用splice()
D3修改dataPoints
时,将停止渲染任何新点。旧点逐渐消失(由于过渡),但没有新点。我不确定我在这里做错了什么
我模拟了这个问题,加载CSV数据并将其存储在内存中,并以每100ms 1点的速度绘制它们。一旦点数超过10,我将拼接以保留最后5个点。我看到了同样的行为。有人能检查一下代码,让我知道我做错了什么吗
设置和打印功能:
var width = 960,
height = 1160;
var dataPoints = []
var svg = d3.select("#map").append("svg")
.attr("width", width)
.attr("height", height);
var projection = d3.geo.albers()
.center([0, 55.4])
.rotate([4.4, 0])
.parallels([40, 70])
.scale(5000)
.translate([width / 2, height / 2]);
function renderPoints() {
var points = svg.selectAll("circle")
.data(dataPoints)
points.enter()
.append("circle")
.attr("cx", function (d) {
prj = projection([d.longitude, d.latitude])
return prj[0];
})
.attr("cy", function (d) {
prj = projection([d.longitude, d.latitude])
return prj[1];
})
.attr("r", "4px")
.attr("fill", "blue")
.attr("fill-opacity", ".4")
.transition()
.delay(5000)
.attr("r", "0px")
}
/* JavaScript goes here. */
d3.json("uk.json", function(error, uk) {
if (error) return console.error(error);
console.log(uk);
var subunits = topojson.feature(uk, uk.objects.subunits);
var path = d3.geo.path()
.projection(projection);
svg.selectAll(".subunit")
.data(subunits.features)
.enter().append("path")
.attr("class", function(d) { return "subunit " + d.id })
.attr("d", path);
svg.append("path")
.datum(topojson.mesh(uk, uk.objects.subunits, function(a,b) {return a!== b && a.id !== 'IRL';}))
.attr("d", path)
.attr("class", "subunit-boundary")
svg.append("path")
.datum(topojson.mesh(uk, uk.objects.subunits, function(a,b) {return a=== b && a.id === 'IRL';}))
.attr("d", path)
.attr("class", "subunit-boundary IRL")
svg.selectAll(".place-label")
.attr("x", function(d) { return d.geometry.coordinates[0] > -1 ? 6 : -6; })
.style("text-anchor", function(d) { return d.geometry.coordinates[0] > -1 ? "start": "end"; });
svg.selectAll(".subunit-label")
.data(topojson.feature(uk, uk.objects.subunits).features)
.enter().append("text")
.attr("class", function(d) { return "subunit-label " + d.id })
.attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; })
.attr("dy", ".35em")
.text(function(d) { return d.properties.name; })
// function applyProjection(d) {
// console.log(d);
// prj = projection(d)
// console.log(prj);
// return prj;
// }
lon = -4.6
lat = 55.45
dataPoints.push([lon,lat])
renderPoints()
});
清除旧点的功能
var cleanupDataPoints = function() {
num_of_elements = dataPoints.length
console.log("Pre:" + num_of_elements)
if(num_of_elements > 10) {
dataPoints = dataPoints.splice(-5, 5)
}
console.log("Post:" + dataPoints.length)
}
从CSV加载数据并以限制速率打印
var bufferedData = null
var ptr = 0
var renderNext = function() {
d = bufferedData[ptr]
console.log(d)
dataPoints.push(d)
ptr++;
renderPoints()
cleanupDataPoints()
if(ptr < bufferedData.length)
setTimeout(renderNext, 100)
}
d3.csv('test.csv', function (error, data) {
bufferedData = data
console.log(data)
setTimeout(renderNext, 100)
})
var bufferedData=null
var ptr=0
var renderNext=函数(){
d=缓冲数据[ptr]
控制台日志(d)
数据点推送(d)
ptr++;
renderPoints()
cleanUpdatePoints()
if(ptr
在行中
points = svg.selectAll("circle")
.data(dataPoints)
points.enter() (...)
d3将数据点
(索引范围从0到5000)中的每个元素映射到圆
元素(最终应该有5000个)。因此,从它的角度来看,没有输入数据:有足够的圆来容纳所有的点
为了确保相同的数据点在更改其数组中的索引后映射到相同的html元素,您需要使用附加到每个数据点的某种类型的id
字段,并告诉d3使用此id将数据映射到元素,而不是它们的索引
points = svg.selectAll("circle")
.data(dataPoints, function(d){return d.id})
如果坐标是点的良好标识符,则可以直接使用:
points = svg.selectAll("circle")
.data(dataPoints, function(d){return d.longitude+" "+d.latitude})
有关更多详细信息,请参见第行中的
points = svg.selectAll("circle")
.data(dataPoints)
points.enter() (...)
d3将数据点
(索引范围从0到5000)中的每个元素映射到圆
元素(最终应该有5000个)。因此,从它的角度来看,没有输入数据:有足够的圆来容纳所有的点
为了确保相同的数据点在更改其数组中的索引后映射到相同的html元素,您需要使用附加到每个数据点的某种类型的id
字段,并告诉d3使用此id将数据映射到元素,而不是它们的索引
points = svg.selectAll("circle")
.data(dataPoints, function(d){return d.id})
如果坐标是点的良好标识符,则可以直接使用:
points = svg.selectAll("circle")
.data(dataPoints, function(d){return d.longitude+" "+d.latitude})
有关详细信息,请参阅。谢谢!问题是D3使用索引从数据中识别圆圈。将其改为使用按键功能修复。谢谢!问题是D3使用索引从数据中识别圆圈。将其更改为使用键功能修复了它。