首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在d3.geo MultiPoint中,如何为不同的点提供不同的形状?

在d3.geo MultiPoint中,如何为不同的点提供不同的形状?
EN

Stack Overflow用户
提问于 2014-03-20 09:48:39
回答 1查看 1.5K关注 0票数 4

我有一些使用d3.geo绘制的geoJson数据。

当我写这样的东西时

代码语言:javascript
复制
d3.select("svg")
   ... 
   .attr("d", function(d) {
                return path({
                    type:"MultiPoint",
                    coordinates: get_activity_coords_(d.activities)
                });
   })

我总是给每个坐标取一个圆。坐标表示旅程中各个停止点的位置。我喜欢的是第一个坐标和最后一个坐标的不同形状。

使用MultiPoint是否有可能做到这一点,是否有一个我可以效仿的例子?我可以一个接一个地画点,但我记得我读到MultiPoint要快得多。另外,代码读起来要清楚得多。

非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-20 16:06:59

对于MultiPoint geoJSON和d3.geo.path,您不能做不同的形状。您可以使用根据函数改变半径,但是看起来您只能将其设置为每个特性,而不是每个点,因此您必须将您的一组点分解为多个特性,并失去使用单个元素所带来的任何性能好处。

然而,要做到这一点,还有其他的方法。

正如您所提到的,一个选项是为每个点<path> 创建一个嵌套的选择,其中包含一个单独的元素,并使用d3.svg.symbol()函数绘制每个路径。然后,可以根据数据或索引自定义符号函数。

代码语言:javascript
复制
var trips = d3.select("svg").selectAll("g.trips")
               .data(/*The data you were currently using for each path,
                       now gets to a group of paths */)
               .attr("class", "trips"); 
               //also set any other properties for the each trip as a whole

var pointSymbol = d3.svg.symbol().type(function(d,i){
                    if (i === 0) 
                        //this is the first point within its groups
                        return "cross";
                    if ( this === this.parentNode.querySelector("path:last-of-type") )
                        //this is the last point within its group
                        return "square";
                    //else:
                    return "circle";
               });


var points = trips.selectAll("path")
               .data(function(d) {
                   return get_activity_coords_(d.activities);
                   //return the array of point objects
                })
               .attr("transform", function(d){ 
                         /* calculate the position of the point using 
                            your projection function directly */
                })
               .attr("d", pointSymbol);

另一个选项允许您为第一点和最后一点(但所有中间点都是相同的)设置自定义形状,它是将这些点作为单个不可见的<path> 元素的顶点连接,并使用 谱线标记 绘制点符号。

你的做法是:

  1. 在SVG中创建一个<defs>元素(可以是硬编码的,也可以是动态的d3),并在其中定义开始、中间和结束标记点。(您可以使用d3.svg.symbol()函数来绘制路径,或者创建自己的路径,或者使用图像,这取决于您自己。)
  2. 使用d3.svg.line()函数根据点坐标数组创建路径的"d“属性;这条线的x和y访问器函数应该使用映射所使用的投影函数从该点的坐标获取x/y位置。为了避免计算两次投影,可以将投影坐标保存在数据对象中: 变量multipointLine = d3.svg.line() .x(函数(d,i) { d.projectedCoords =投影(D);返回d.projectedCoords;}) .y(函数(D){返回d.projectedCoords1;}); (您不能使用d3.geo.path()函数将这些线作为地图功能来绘制,因为它会将这条线分解成曲线,以匹配地图投影中的经度和纬度线的曲线;要使直线标记正常工作,路径需要只是点之间的一个简单的直线连接。)
  3. 将该路径上的样式设置为无笔画和不填充,因此该行本身不会显示,但随后将行上的marker-startmarker-midmarker-end属性设置为引用正确标记元素的id值。

为了让您开始,下面是一个使用d3动态生成行标记的示例:

是否可以同时使用d3.svg.symbol和svg.marker?

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22529038

复制
相关文章

相似问题

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