【发布时间】:2021-04-10 09:00:40
【问题描述】:
我是 D3 的新手,刚刚编写了一个小代码来在地图上显示点转换:
Static Image
我从一个大约 100 点的小样本开始,效果很好。
但最终,我想在此动画中显示大约 1000 个点:https://www.zeit.de/feature/pendeln-stau-arbeit-verkehr-wohnort-arbeitsweg-ballungsraeume
但对于 D3 和浏览器来说,即使是 500 点似乎也难以处理 - 动画不再重复。
我读到我应该使用画布来获得更好的性能,但是在阅读了一些教程之后,我仍然无法将我的 SVG 代码正确地重写为画布代码。任何有关如何在此处正确使用画布的帮助表示赞赏。
使用 SVG 的代码:
Promise.all([
d3.json('http://opendata.ffe.de:3000/rpc/map_region_type?idregiontype=2&generalized=1'),
d3.csv('../Daten/d3_input_sample_klein.csv')
]).then(([bl, centroids]) => {
var aProjection = d3.geoMercator()
.fitSize([800, 600], bl);
var geoPath = d3.geoPath()
.projection(aProjection);
var svg = d3.select('body')
.append('svg')
.attr('width', 1000)
.attr('height', 1000);
// draw basemap
svg.selectAll('path')
.data(bl.features)
.enter()
.append('path')
.attr('d', geoPath)
.attr('class', 'bl');
// get max value for scaleLinear
var max = d3.max(centroids, function (d) {
return parseInt(d.value);
});
var radiusScale = d3.scaleLinear()
.domain([0,max])
.range([1, 10]);
// create circles with radius based on "value"
function circleTransition() {
var circles = svg.selectAll('circle')
.data(centroids)
.enter()
.append('circle')
.style('fill', 'white')
.attr('r', function (d) {
return radiusScale(d.value);
});
repeat();
// transition circles from "start" to "target" and repeat
function repeat() {
circles
.attr('cx', (d) => aProjection([d.x_start, d.y_start])[0])
.attr('cy', (d) => aProjection([d.x_start, d.y_start])[1])
.transition()
.duration(4000)
.attr('cx', (d) => aProjection([d.x_target, d.y_target])[0])
.attr('cy', (d) => aProjection([d.x_target, d.y_target])[1])
.on('end', repeat);
};
};
circleTransition();
加载的 CSV 文件包含这样的纬度/经度坐标:
| x_start | y_start | x_target | y_target | value |
|---|---|---|---|---|
| 9.11712 | 54.28097 | 8.77778 | 54.71323 | 122 |
| 9.79227 | 53.64759 | 9.60330 | 53.86844 | 87617 |
| 9.70219 | 53.58864 | 8.80382 | 54.80330 | 2740 |
有没有一种简单的方法可以将此代码转换为使用画布或以其他方式提高性能?
谢谢! 迈克尔
【问题讨论】: