javascript - d3js v5 + Topojson v3 关于加入 csv & json 的优化

标签 javascript d3.js topojson

为了制作 map ,我需要将一些值从 csv 导入到 json 直接在代码中。 为了加载 json 和 csv 文件,我对 Promise 对象使用异步操作,并使用两个循环和一个公共(public)键在 json 文件上添加新属性。

for (var i=0; i< fr[1].length;i++){
        var csvId = fr[1][i].codgeo;
        var csvValue1 = parseFloat(fr[1][i].value1);
        var csvValue0 = parseFloat(fr[1][i].value0);
        for (var j=0; j<topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features.length;j++){
          var jsonId = topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.codgeo;
          if (csvId === jsonId) {
            topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.value1 = csvValue1;
            topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.value0 = csvValue0;
            break;

一切正常,但在网络上显示 map 需要时间。 有没有办法优化 map 的加载时间?

这是我的代码示例:https://plnkr.co/edit/ccwIQzlefAbd53qnjCX9?p=preview

最佳答案

我使用了你的 plunkr 并向它添加了一些时间点,运行了很多次并获得了一些关于你的脚本花费时间的数据:

enter image description here

这是一个 block与日志记录。

我很确定我居住的地方的带宽低于平均水平并且有很大的可变性;文件加载时间对我来说变化很大,低至 500 毫秒,高至 1800 毫秒,其他一切都是一致的

让我们仔细看看您在问题中包含的数据操作阶段:

for (var i=0; i< fr[1].length;i++){
        var csvId = fr[1][i].codgeo;
        var csvValue1 = parseFloat(fr[1][i].value1);
        var csvValue0 = parseFloat(fr[1][i].value0);
        for (var j=0; j<topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features.length;j++){
          var jsonId = topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.codgeo;
          if (csvId === jsonId) {
            topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.value1 = csvValue1;
            topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8).features[j].properties.value0 = csvValue0;
            break;

根据我的统计,嵌套的 for 语句运行了大约 5,151 次。 for 语句的父级运行 101。这些不应更改,因为您的数据是固定的。为什么这些周期需要这么长时间?因为你每次迭代都调用 topojson.feature() :

如果我隔离这一行:

topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8)

我们可以看到,这实际上只需要几毫秒。

Topojson.feature

Returns the GeoJSON Feature or FeatureCollection for the specified object in the given topology. If the specified object is a GeometryCollection, a FeatureCollection is returned, and each geometry in the collection is mapped to a Feature. Otherwise, a Feature is returned. The returned feature is a shallow copy of the source object: they may share identifiers, bounding boxes, properties and coordinates. (from the docs).

因此,每次我们使用 topojson.feature 时,我们实际上都是将 topojson 转换为 geojson。我们不需要在 for 循环中这样做。让我们这样做一次:

  var featureCollection = topojson.feature(fr[0],fr[0].objects.dep_GEN_WGS84_UTF8);

  //Merge csv & json
  //Add properties from csv to json)
 for (var i=0; i< fr[1].length;i++){
    var csvId = fr[1][i].codgeo;
    var csvValue1 = parseFloat(fr[1][i].value1);
    var csvValue0 = parseFloat(fr[1][i].value0);
    for (var j=0; j<featureCollection.features.length;j++){
      var jsonId = featureCollection.features[j].properties.codgeo;
      if (csvId === jsonId) {
        featureCollection.features[j].properties.value1 = csvValue1;
        featureCollection.features[j].properties.value0 = csvValue0;
        break;
      }
    }
  }

当然,我们也必须更新渲染的代码部分以使用 featureCollection 变量,而不是 topojson

现在让我们看一下时间: enter image description here

这是更新的 bl.ock基于上面的,也有时间点。

不,我没有忘记包括一个操作时间,它对我来说平均为 1.5 毫秒。是的,我的带宽显示出可变性 - 但无论外部因素如何,花在其他操作上的时间应该明显减少

进一步增强

几何的预投影,请参阅此 question/answer .

几何简化,参见mapshaper.org (尽管我相信您已经这样做了)。

从 csv 或 topojson 中删除不必要的属性 - 你真的在使用 topojson 中的 population 字段吗,你是否需要 topojson 中的 libgeo 和 libgeo_m(例如:“libgeo”:“Puy-de- Dôme","libgeo_m":"PUY-DE-DÔME")?

关于javascript - d3js v5 + Topojson v3 关于加入 csv & json 的优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50006106/

相关文章:

javascript - 如何在 Sencha Touch 中的 Google map 上的 svg 上添加触摸并按住事件

javascript - 在不损失质量的情况下调整图像 JavaScript/jQuery 的大小

javascript - 正则表达式从域字符串中获取 SLD + TLD

javascript - 将Web Mercator磁贴重新投影到D3的任意投影?

javascript - 在 nvd3 结构中使用 d3 和 json 的多折线图

javascript - d3js v5 + topojson v3 以缩放为中心的正方形质心

javascript - 如何获取诺基亚 map 中可拖动标记的经度和纬度?

javascript - 如何使用 d3js 实现联合图

node.js - 将 shapefile 和 geoJson 转换为 TopoJson 和/或使用 geo2topo

json - Topojson:v0 和 v1 之间的差异列表?