绘制SVG文本,大小和长度根据具体路径调整
Draw SVG text with size and lengthAdjust based on the specific path
这很特别。我有一些 pathes(将它们想象成地图上的河流)并希望它们给出一个 name.
此代码运行正常。它正在创建路径,然后在这些行上写入文本:
function draw_rivertext(){
var featureCollection = topojson.feature(currentMap, currentMap.objects.text);
svgmap.append("g")
.selectAll("path")
.data(featureCollection.features)
.enter().append("path")
.attr("d", path)
.attr("class", "helperline")
.attr("id", function(d) {return "path"+d.properties.id});
svgmap.append("text")
.selectAll("text")
.data(featureCollection.features)
.enter()
.append("textPath")
.attr("class", "helperline-text")
.attr("xlink:href", function(d) {return "#path"+d.properties.id})
.text(function(d) {return d.properties.name});
}
但问题是文本只有一个 字体大小。所以假设我有一条长河和一条短河。所以短河应该超小而不是完全相同的巨大尺寸。
所以我的想法是在正文上设置:
.attr("font-size", "10")
这里的值 10 需要是路径 ID 中的当前大小。我真的不知道该怎么做。
这里有一些关于这个主题的链接:
- https://www.safaribooksonline.com/library/view/svg-essentials/0596002238/ch08s05.html
- SVG textpath, determine when text goes beyond the path
- how to set font size based on container size?
- http://eyeseast.github.io/visible-data/2013/08/26/responsive-d3/
- https://milkator.wordpress.com/2013/02/25/making-a-map-of-germany-with-topojson/
我还发现一些在使用 jQuery 创建后重新采样字体大小等。那肯定是一个解决方案。获取路径大小;重新采样该值的文本属性。但我认为这不是一个合适的解决方案。
另一个想法是将 topojson 中的字体大小指定为自己的参数。但是天哪,这将是试错法,因为 QGIS 中没有为此进行真正的测量。
感谢 Lars Kotthoff 这是一个可行的解决方案:
svgmap.append("g")
.selectAll("path")
.data(featureCollection.features)
.enter().append("path")
.attr("d", path)
.attr("class", "helperline")
.attr("id", function(d) {return "path"+d.properties.id})
.each(function() { this.__data__.totalLength = this.getTotalLength(); });
svgmap.append("text")
.selectAll("text")
.data(featureCollection.features)
.enter()
.append("textPath")
.attr("class", "helperline-text")
.attr("xlink:href", function(d) {return "#path"+d.properties.id})
.attr("font-size", function(d) { return (d.totalLength/8); })
.text(function(d) {return d.properties.name});
除以 8 效果很好。现在唯一的问题是有些文字不合适,但 90% 看起来不错,而且计算出来的尺寸也很好。
对于我的案例,我决定自己计算每个元素的大小。所以这里更简单,但可能不是完美解决方案。
这很特别。我有一些 pathes(将它们想象成地图上的河流)并希望它们给出一个 name.
此代码运行正常。它正在创建路径,然后在这些行上写入文本:
function draw_rivertext(){
var featureCollection = topojson.feature(currentMap, currentMap.objects.text);
svgmap.append("g")
.selectAll("path")
.data(featureCollection.features)
.enter().append("path")
.attr("d", path)
.attr("class", "helperline")
.attr("id", function(d) {return "path"+d.properties.id});
svgmap.append("text")
.selectAll("text")
.data(featureCollection.features)
.enter()
.append("textPath")
.attr("class", "helperline-text")
.attr("xlink:href", function(d) {return "#path"+d.properties.id})
.text(function(d) {return d.properties.name});
}
但问题是文本只有一个 字体大小。所以假设我有一条长河和一条短河。所以短河应该超小而不是完全相同的巨大尺寸。
所以我的想法是在正文上设置:
.attr("font-size", "10")
这里的值 10 需要是路径 ID 中的当前大小。我真的不知道该怎么做。
这里有一些关于这个主题的链接:
- https://www.safaribooksonline.com/library/view/svg-essentials/0596002238/ch08s05.html
- SVG textpath, determine when text goes beyond the path
- how to set font size based on container size?
- http://eyeseast.github.io/visible-data/2013/08/26/responsive-d3/
- https://milkator.wordpress.com/2013/02/25/making-a-map-of-germany-with-topojson/
我还发现一些在使用 jQuery 创建后重新采样字体大小等。那肯定是一个解决方案。获取路径大小;重新采样该值的文本属性。但我认为这不是一个合适的解决方案。
另一个想法是将 topojson 中的字体大小指定为自己的参数。但是天哪,这将是试错法,因为 QGIS 中没有为此进行真正的测量。
感谢 Lars Kotthoff 这是一个可行的解决方案:
svgmap.append("g")
.selectAll("path")
.data(featureCollection.features)
.enter().append("path")
.attr("d", path)
.attr("class", "helperline")
.attr("id", function(d) {return "path"+d.properties.id})
.each(function() { this.__data__.totalLength = this.getTotalLength(); });
svgmap.append("text")
.selectAll("text")
.data(featureCollection.features)
.enter()
.append("textPath")
.attr("class", "helperline-text")
.attr("xlink:href", function(d) {return "#path"+d.properties.id})
.attr("font-size", function(d) { return (d.totalLength/8); })
.text(function(d) {return d.properties.name});
除以 8 效果很好。现在唯一的问题是有些文字不合适,但 90% 看起来不错,而且计算出来的尺寸也很好。
对于我的案例,我决定自己计算每个元素的大小。所以这里更简单,但可能不是完美解决方案。