代码之家  ›  专栏  ›  技术社区  ›  weslleywang

d3.js如何在div中拟合多个多边形

  •  2
  • weslleywang  · 技术社区  · 8 年前

    1. 我在看geoJson,然后迷路了。我应该使用geoJson,还是只使用带有点数组的简单json?
    2. 我试过mbostock的 Custom Projection ,则我的绘图不适合我的分区。也尝试了 Identity projection of map in d3.js ,但投影不正确,应为20简单框。 enter image description here
    3. 我喜欢附加一个图像文件(jpg,png,…)在svg的后面。我该怎么做?我应该在json/geojson文件中包含一个边界框,以便更容易对齐吗?
    4. 我喜欢用单独加载的数据给每个多边形上色,我应该怎么做?

    test json file geojson格式

    谢谢 韦斯

    1 回复  |  直到 8 年前
        1
  •  1
  •   Andrew Reid    8 年前

    您可以使用geojson,以及 geoTransform geoIdentity 预测这些用于平面坐标,而通常为d3。地质投影旨在获取地球仪上的点并将其投影到平面上。这就是为什么自定义投影可能会导致一些奇怪的形状,这取决于您如何定义它。

    地理身份 选项可能是最简单的:它投影平面几何体,并让您可以访问d3投影方法,如 .fitExtent .fitSize . 为此, fitSize 最合适的方法是,它接受geoJson对象(featureCollection),并将其包含的功能转换和缩放为包含在指定大小内:。 fitExtent([width,height],geoJson object) :

    var projection = d3.geoIdentity()   
      .fitSize([width,height],data);  // the area the features will be fitted to
    

    当需要利润时,可以使用fitExtent。fitSize假设左侧或顶部没有边距,请参阅文档 here .

    如果使用 没有 .fitSize尺寸 ,坐标值将被解释为像素值。如果您的数据方面与svg容器的方面不匹配,那么该功能将以尽可能多的宽度或高度放置在最佳位置(fitSize不会扭曲方面)。如果将图像放置在数据后面,请确保图像的纵横比与svg相同,并占用相同的像素空间。

    另一个问题是地理标识可能会导致颠倒(因为svg y值从顶部的零开始,随着下降而增加,这与许多其他约定相反)。

    要翻转y轴,请使用 reflectY(true) :

     var projection = d3.geoIdentity()
      .reflectY(true)
      .fitSize([width,height],data);
    

    最后,添加时,请确保使用 geoJson.features ,否则,将单个项目绑定到enter选择,并将其呈现为单个路径。您希望将每个特征绑定到不同的元素。

    this block 对于所有内容(我将使用一个片段,但json将压倒它)。


    虽然我已经给多边形上色来演示每个多边形的范围,但你可以用各种不同的方式给它们上色。您可以拥有一个与定义颜色的每个特征关联的属性:

    {"type":"Feature","id":"loc781","properties":{"color":"yellow"},"geometry":}...
    

    .attr("fill", function(d) { return d.properties.color; })

    或属性中的值,您可以使用该值根据比例进行着色:

    {"type":"Feature","id":"loc781","properties":{"value":10},"geometry":}...
    

    var scale = d3.scaleLinear().domain([0,50]).range([yellow,blue])

    在附加多边形时:

    .attr("fill", function(d) { return scale(d.properties.value); })

    在我的块示例中,我只使用了序数比例和所附加特征的索引:

    var color = d3.scaleOrdinal(d3.schemeCategory20);

    在附加矩形时:

    .attr("fill", function(d,i) { return color(i); });


    question and answer 寻找潜在的解决方案。


    最后,如果放置数千个元素,可能需要切换到画布进行渲染,这相当简单,但问题不同。