简化D3js' SVG路径生成字符串

时间:2016-03-31 13:01:06

标签: javascript d3.js svg projection geo

我正在尝试使用惊人的D3js地理模块优化我生成的SVG。

我使用d3.geo.path作为SVG路径的d属性生成器:

path = d3.geo.path().projection(config.projection); // projection is initialized somewhere else

然后使用它来渲染这样的路径:

svg.selectAll(".country")
     .data(countries)
     .enter()
     .insert("path", ".graticule")
     .attr({
         class: "country",
         d: path
     })

我得到的路径字符串就像这样:

M713.601085,459.8780053259876L714.7443994399441,460.08170562468473L715.0310281028103,460.5903728431771L715.0310281028103...

可以看出,有些数字非常长,小数点太多而且在我目前的分辨率下并没有真正有用,这会堵塞DOM并使调试这些路径变得迟钝(也有很多,因为它&# 39;绘制了许多国家的世界地图。)

所以我的第一种方法是为pathSimplified

创建这个path包装器
// Path simplified: take some decimals out of the 'd' string
pathSimplified = function (d) {
        return path(d).replace(/(\.\d{4})\d+/g, '$1');
    };

然后使用它代替path

    //...
    .attr({
         class: "country",
         d: pathSimplified
     })

这是有效的,现在我只获得路径字符串上每个值的4位小数。像这样:

M713.6010,459.8780L714.7443,460.0817L715.0310,460.5903L715.0310...

我的问题是:它能以更好,更少的hackish方式完成吗?在D3js的path函数吐出之后调整字符串是不对的,并且在路径本身的某个点指定舍入会很好。投影...

1 个答案:

答案 0 :(得分:2)

你的想法很好,简化折线很有帮助,但你可以做的不仅仅是截断坐标:存在折线简化的算法,可能会给你带来更好的结果。

例如,请查看Ramer-Douglas-Peucker algorithm。它在像Simplify.js这样的库中实现(查看该页面上的演示),这也允许您使用容差进行调整。 你必须将这条线作为一组x / y坐标来传递,但我相信这样做并不复杂。

我还注意到d3 geo投影允许使用精确参数(例如here),也许有类似你忽略的东西?无论如何,通常总是可以使用simplify.js简化自己的坐标。