我试图使用d3fc-label-label.js和d3.js相结合的方式在地图上定位标签。同时用basic d3标记地图函数工作得很好,该方法借助d3fc标签-label.js。 (很大程度上受这个例子的启发)生成了一个地图,所有标签都放在左上角。
下面是完成这项工作的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);
});<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.0/d3.min.js"></script>
请参阅包含数据和HTML的要旨。
我想这个问题与将标签正确地附加到地图的路径有关。可悲的是,我还没有弄明白,我会非常感谢任何帮助!
发布于 2017-07-14 18:28:17
我认为问题在于你没有将单个坐标作为标签的位置传递。
LayoutLabel.position(访问器) 指定关联数组中每个项的位置。访问器函数在每个数据中只调用一次,并且应该将位置作为两个值x、y的数组返回。
在您展示的示例中,设计是基于变量places包含点几何学,正是在这些点上附加标签。在topojson中,我们发现places看起来像:
"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标签布局:
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; });https://stackoverflow.com/questions/45107825
复制相似问题