What is the proper way to use D3's projection.stream()?

岁酱吖の 提交于 2020-01-13 07:32:48

问题


So I'm experimenting a bit with D3's geo stream API, and things feel a bit hazy. I've been reading through the documentation here:

https://github.com/mbostock/d3/wiki/Geo-Streams

One point of confusion I have is the proper implementation of stream transforms. Let's say I create one:

//a stream transform that applies a simple translate [20,5]:
var transform = d3.geo.transform({
    point:function(){this.stream.point(x+20,y+5)}
}) 

Per the documentation, this.stream references the "wrapped stream." But what is the stream, really? From what I can gather, it is more of a procedure than explicit data structure--a sequence of data and function calls to transform the data. The syntax above seems to suggest that the wrapped stream is simply the object containing "stream listeners"

Moving on, I'm able to apply the stream transform using the projection method:

//a path generator with the transform applied using the projection() method
var path = d3.geo.path().projection(transform);

While I don't quite understand the underlying mechanics, the effect seems relatively straightforward: the underlying transform function of the path generator is called with transformed x,y arguments.

For my use case, I don't find this that helpful, particularly because my input data is not already projected. I'd like to use a projection to transform the data first, then transform those outputted coordinates. To that end, is there a general pattern for layering transforms?

I see that D3 does provide the projection.stream(listener) pattern which applies the projecting transform first, before applying the listener, but I'm not sure how to implement this. What should the listener argument be? Here's an example: http://jsfiddle.net/kv7yn8rw/2/.

Any guidance would be greatly appreciated!


回答1:


A key fact from the documentation is that "a geographic projection is one example of a stream transform."

Streams just allow one to transform (e.g. project) data multiple times without saving the intermediate data. A projection can just be an object with a stream attribute, e.g. proj_then_transform below.

The way to chain streams is as follows:

// 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)); 
        }
     };

I've updated the example with a working solution: http://jsfiddle.net/cvs5d7o9/2/



来源:https://stackoverflow.com/questions/27557724/what-is-the-proper-way-to-use-d3s-projection-stream

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!