使用 D3 的 projection.stream() 的正确方法是啥?
Posted
技术标签:
【中文标题】使用 D3 的 projection.stream() 的正确方法是啥?【英文标题】:What is the proper way to use D3's projection.stream()?使用 D3 的 projection.stream() 的正确方法是什么? 【发布时间】:2015-02-17 21:33:20 【问题描述】:所以我对D3's geo stream
API
进行了一些试验,感觉有些模糊。我一直在阅读这里的文档:
https://github.com/mbostock/d3/wiki/Geo-Streams
我有一个困惑点是流转换的正确实现。假设我创建了一个:
//a stream transform that applies a simple translate [20,5]:
var transform = d3.geo.transform(
point:function()this.stream.point(x+20,y+5)
)
根据文档,this.stream 引用“包装流”。但什么是流,真的吗?据我所知,它更像是一个过程,而不是显式的数据结构——一系列数据和函数调用来转换数据。上面的语法似乎表明包装的流只是包含“stream listeners”的对象
继续,我可以使用投影方法应用流变换:
//a path generator with the transform applied using the projection() method
var path = d3.geo.path().projection(transform);
虽然我不太了解底层机制,但效果似乎相对简单:路径生成器的底层变换函数使用变换后的x,y
参数调用。
对于我的用例,我认为这没有什么帮助,尤其是因为我的输入数据还没有被投影。我想先使用投影来转换数据,然后再转换那些输出的坐标。为此,是否有用于分层变换的通用模式?
我看到 D3
确实提供了 projection.stream(listener) 模式,该模式在应用侦听器之前首先应用投影变换,但我不确定如何实现这一点。侦听器参数应该是什么?这是一个示例:http://jsfiddle.net/kv7yn8rw/2/。
任何指导将不胜感激!
【问题讨论】:
您是否尝试使用此方法将投影的地图数据向右移动 20 像素并向下移动 5 像素?或者,当您提到分层变换时,您还想做更多的事情吗? 对不起,赏金没有产生任何答案。我开始查看源代码,但我最好的猜测是var path2 = d3.geo.path().projection( proj.stream(transform) );
应该适用于您的小提琴,但它仍然会抛出错误。当我有更多时间时,我可能会再次回来;我一直想进一步了解 d3.geo 方法的工作原理。
【参考方案1】:
the documentation 的一个关键事实是 “地理投影是流变换的一个例子。”
Streams 只允许在不保存中间数据的情况下多次转换(例如项目)数据。投影可以只是具有流属性的对象,例如proj_then_transform
下方。
链流的方式如下:
// stream 1
var proj = d3.geo.equirectangular();
// stream 2
var transform = d3.geo.transform(
point:function(x,y)this.stream.point(x+20,y+5)
);
// stream 1 then stream 2
var proj_then_transform =
stream: function(s)
return proj.stream(transform.stream(s));
;
我已使用可行的解决方案更新了示例: http://jsfiddle.net/cvs5d7o9/2/
【讨论】:
只是为了我正确理解事物的顺序,该函数称为 proj_then_transform,但看起来转换首先发生,然后被馈送到投影。应该是这样吗?以上是关于使用 D3 的 projection.stream() 的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章
在 D3 中放大和缩小时如何更改平移和缩放的速度(使用 zoom.on 和 d3.event.translate,d3.event.zoom)?