我有一些代码可以在D3中缩放和翻译地图,但性能非常糟糕。在缩放和平移时,刷新需要将近3秒钟。我认为地图会看起来更好,包括所有县的线路边界,但是在6MB +我怀疑这可能是瓶颈所在的地方。还有另一种方法我应该处理变换或者可能是一种优化地图数据的方法吗? D3真的不适合这个细节吗? D3很新。
我正在使用此处的形状文件,使用QGIS从DBF转换为Geojson: https://www.census.gov/cgi-bin/geo/shapefiles2010/main
<!doctype html>
<html>
<head>
<title>d3 map</title>
<script src="http://d3js.org/d3.v3.min.js">
</script>
</head>
<body>
<script>
var width = 800;
var height = 600;
var projection = d3.geo.mercator();
var path = d3.geo.path().projection (projection);
var canvas = d3.select ("body")
.append ("svg")
.attr ("width", width)
.attr ("height", height)
var zoomVar = d3.behavior.zoom()
.translate(projection.translate())
.scale(projection.scale())
.scaleExtent([height, 60 * height])
.on("zoom", onPostZoom);
var hotbox = canvas.append("g").call(zoomVar);
hotbox.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("fill", "white")
.attr("height", height);
d3.json ("cali.geojson", function (data)
{
hotbox.append("g")
.attr("id", "geometry")
.selectAll("path")
.data(data.features)
.enter()
.append("path")
.attr("d", path)
.attr("fill", "steelblue")
.on("click", onClick);
})
function onClick (d)
{
var centroid = path.centroid(d), translate = projection.translate();
projection.translate(
[translate[0] - centroid[0] + width / 2,
translate[1] - centroid[1] + height / 2 ]);
zoomVar.translate(projection.translate());
hotbox.selectAll("path").transition()
.duration(700)
.attr("d", path);
}
function onPostZoom()
{
projection.translate(d3.event.translate).scale(d3.event.scale);
hotbox.selectAll("path").attr("d", path);
}
</script>
</body>
</html>
答案 0 :(得分:10)
正如Lars所说,你绝对应该简化你的数据到适当的分辨率。根据您要放大的距离选择最大分辨率。我建议topojson -s
进行简化,因为您还可以获得较小TopoJSON format的好处。
另一件大事是如果你只是平移和缩放,请避免重新投影。重投影是一种相对昂贵的三角运算,因此在SVG中序列化非常大的路径串。您只需在路径元素或包含G元素上设置transform attribute即可避免平移和缩放(平移和缩放)。请参阅以下示例:
您还应该考虑使用projected TopoJSON(alternate example)将投影烘焙到TopoJSON文件中。这使客户端更快:它永远不必投射!
答案 1 :(得分:4)
您遇到的问题不是因为D3,而是因为浏览器。主要瓶颈是渲染所有视觉元素,而不是计算其位置等。
避免这种情况的唯一方法是减少数据量。一种开始的方法是简化QGIS中的边界,例如,使用例如dpsimplify插件。