d3.js - 在 d3.geo MultiPoint 如何为不同的点提供不同的形状?

标签 d3.js geo

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

当我写类似的东西时

d3.select("svg")
   ... 
   .attr("d", function(d) {
                return path({
                    type:"MultiPoint",
                    coordinates: get_activity_coords_(d.activities)
                });
   })

我总是为每个坐标得到一个圆圈。坐标表示旅程的各个停靠点的位置。我更喜欢第一个和最后一个坐标的不同形状。

是否可以使用 MultiPoint 执行此操作,是否有我可以遵循的示例?我可以一个一个地绘制点,但我记得读过 MultiPoint 的速度要快得多。另外,代码会更清晰易读。

非常感谢。

最佳答案

您不能使用 d3.geo.path 为 MultiPoint geoJSON 做不同的形状.您可以 change the radius based on a function ,但看起来您只能为每个功能而不是每个点设置它,因此您必须将您的一组点分解为多个功能,并失去使用单个元素的任何性能优势。

但是,还有其他方法可以做到这一点。

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

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>元素和使用 line markers绘制点符号 .

你的方法是:
  • 创建一个 <defs> SVG 中的元素(硬编码或使用 d3 动态),并在其中定义开始、中间和结束标记点。 (你可以使用 d3.svg.symbol() 函数来绘制路径,或者自己制作,或者使用图像,这取决于你。)
  • 使用 d3.svg.line()函数根据您的点坐标数组创建路径的“d”属性;线的 x 和 y 访问器函数应该使用您用于 map 的投影函数从该点的坐标中获取 x/y 位置。为了避免计算两次投影,您可以将投影坐标保存在数据对象中:
     var multipointLine = d3.svg.line()
                          .x(function(d,i) {
                              d.projectedCoords = projection(d);
                              return d.projectedCoords[0];
                            })
                          .y(function(d){ return d.projectedCoords[1];});
    

    (您不能使用 d3.geo.path() 函数将线条绘制为 map 特征,因为它会将线条分解为曲线以匹配 map 投影中的经纬度曲线;要使线条标记起作用,路径只需是点之间的简单直线连接。)
  • 将该路径上的样式设置为无描边和无填充,这样线条本身就不会出现,然后设置 marker-start , marker-midmarker-end行上的属性以引用正确标记元素的 id 值。

  • 为了让您开始,这里有一个使用 d3 动态生成线标记的示例:
    Is it possible to use d3.svg.symbol along with svg.marker

    关于d3.js - 在 d3.geo MultiPoint 如何为不同的点提供不同的形状?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22529038/

    相关文章:

    javascript - 最新版本的 angularjs 和 d3js 支持 SVG

    javascript - 为什么这个 d3 示例中的圆圈不移动?

    php - 用户位置数据聚类

    python - 在 map 上可视化饼图

    r - 如何在 map 上以最少的重叠绘制网络

    javascript - 使用 D3.js 的多面积图

    javascript - Ajax 在等待 d3 graphs/.json 响应时加载图形? ( rails )

    php - 获取路线的算法

    r - 从坐标生成多边形

    javascript - 无法将城市隐藏在旋转的地球后面