首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在地图上使用D3FC标签. to?

如何在地图上使用D3FC标签. to?
EN

Stack Overflow用户
提问于 2017-07-14 16:34:18
回答 1查看 184关注 0票数 1

我试图使用d3fc-label-label.jsd3.js相结合的方式在地图上定位标签。同时用basic d3标记地图函数工作得很好,该方法借助d3fc标签-label.js。 (很大程度上受这个例子的启发)生成了一个地图,所有标签都放在左上角。

下面是完成这项工作的javascript部分

代码语言:javascript
复制
var width = 1300,
    height = 960;

var projection = d3.geoMercator()
  .scale(500)
  // Center the Map to middle of shown area
  .center([10.0, 50.5])
  .translate([width / 2, height / 2]);

// ??
var path = d3.geoPath()
  .projection(projection)
  .pointRadius(2);

// Set svg width & height
var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);
// var g = svg.append("g");

d3.json("europe_wgs84.geojson", function(error, map_data) {
  if (error) return console.error(error);
  // var places = topojson.feature(map_data, map_data.objects.places);

  // "path" instead of ".subunit"
  svg.selectAll("path")
    .data(map_data.features)
  .enter().append("path")
    .attr("d", path)
    .attr("class", function(d) { return "label " + d.id})

  var labelPadding = 2;

  // the component used to render each label
  var textLabel = fc.layoutTextLabel()
    .padding(labelPadding)
    //.value(function(d) { return map_data.properties.iso; });
    .value(function(d) { return d.properties.iso; });

  // use simulate annealing to find minimum overlapping text label positions
  var strategy = fc.layoutGreedy();

  // create the layout that positions the labels
  var labels = fc.layoutLabel(strategy)
      .size(function(_, i, g) {
          // measure the label and add the required padding
          var textSize = d3.select(g[i])
              .select('text')
              .node()
              .getBBox();
          return [textSize.width + labelPadding * 2, textSize.height + labelPadding * 2];
      })
      .position(function(d) { return projection(d.geometry.coordinates); })
      .component(textLabel);

  // render!
  svg.datum(map_data.features)
       .call(labels);
});
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.0/d3.min.js"></script>

请参阅包含数据和HTML的要旨

我想这个问题与将标签正确地附加到地图的路径有关。可悲的是,我还没有弄明白,我会非常感谢任何帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-07-14 18:28:17

我认为问题在于你没有将单个坐标作为标签的位置传递。

LayoutLabel.position(访问器) 指定关联数组中每个项的位置。访问器函数在每个数据中只调用一次,并且应该将位置作为两个值x、y的数组返回。

在您展示的示例中,设计是基于变量places包含点几何学,正是在这些点上附加标签。在topojson中,我们发现places看起来像:

代码语言:javascript
复制
"places":{"type":"GeometryCollection","geometries":[{"type":"Point","coordinates":[5868,5064],"properties":{"name":"Ayr"}},{"type":"Point","coordinates":[7508,6637],"properties":{"name":"Aberdeen"}},{"type":"Point","coordinates":[6609,5933],"properties":{"name":"Perth"}},...

注意,每个点的geometries.coordinates包含一个坐标。但是,在您的代码中,d.geometry.coordinates包含一个坐标数组,因为它包含每个特性的整个路径的边界点。这将导致标签放置中的错误。相反,您可能需要使用path.centroid(d),这将返回位于每个国家/区域/路径中心的单个坐标。布局可能不是完美的,作为一个极端的例子,一系列国家被安排为同心圆环将具有相同的质心。下面是一个基本块,它使用path.centroid显示位置(这只显示位置--而不是标签的格式,因为我不熟悉这个库扩展)。

如果您想知道为什么链接示例的区域标签显示得很好,那么在示例中,每个区域都有一个附加在其质心的标签,完全绕过了d3fc标签布局:

代码语言:javascript
复制
  svg.selectAll(".subunit-label")
      .data(subunits.features)
    .enter().append("text")
      .attr("class", function(d) { return "subunit-label " + d.id; })
      .attr("transform", function(d) { return "translate(" + path.centroid(d) + ")"; })
      .attr("dy", ".35em")
      .text(function(d) { return d.properties.name; });
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45107825

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档