我有一些使用d3.geo绘制的geoJson数据。
当我写这样的东西时
d3.select("svg")
...
.attr("d", function(d) {
return path({
type:"MultiPoint",
coordinates: get_activity_coords_(d.activities)
});
})我总是给每个坐标取一个圆。坐标表示旅程中各个停止点的位置。我喜欢的是第一个坐标和最后一个坐标的不同形状。
使用MultiPoint是否有可能做到这一点,是否有一个我可以效仿的例子?我可以一个接一个地画点,但我记得我读到MultiPoint要快得多。另外,代码读起来要清楚得多。
非常感谢。
发布于 2014-03-20 16:06:59
对于MultiPoint geoJSON和d3.geo.path,您不能做不同的形状。您可以使用根据函数改变半径,但是看起来您只能将其设置为每个特性,而不是每个点,因此您必须将您的一组点分解为多个特性,并失去使用单个元素所带来的任何性能好处。
然而,要做到这一点,还有其他的方法。
正如您所提到的,一个选项是为每个点<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> 元素的顶点连接,并使用 谱线标记 绘制点符号。
你的做法是:
<defs>元素(可以是硬编码的,也可以是动态的d3),并在其中定义开始、中间和结束标记点。(您可以使用d3.svg.symbol()函数来绘制路径,或者创建自己的路径,或者使用图像,这取决于您自己。)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()函数将这些线作为地图功能来绘制,因为它会将这条线分解成曲线,以匹配地图投影中的经度和纬度线的曲线;要使直线标记正常工作,路径需要只是点之间的一个简单的直线连接。)marker-start、marker-mid和marker-end属性设置为引用正确标记元素的id值。为了让您开始,下面是一个使用d3动态生成行标记的示例:
https://stackoverflow.com/questions/22529038
复制相似问题