What is d3.geo.pipeline?
If you follow Mike Bostock's bl.ocks, you know that for the past 8 months d3.geo.pipeline () has been a frequent component of his projects.
But what does he do?
You can see that he set up the pipelines like this:
var sketch = d3.geo.pipeline()
.source(d3.geo.jsonSource)
.pipe(resample, .020)
.pipe(jitter, .004)
.pipe(smooth, .005)
.sink(d3.geo.jsonSink);
The d3.geo wiki lacks documentation .
Some embellished JS in unreleased D3 used in the sample code show this feature:
lo.geo.pipeline = function() {
var n = [];
return {
source: function() {
return n[0] = arguments, this
},
pipe: function() {
return n.push(arguments), this
},
sink: function() {
for (var t, e = arguments[0].apply(null, [].slice.call(arguments, 1)), r = e; t = n.pop();) {
var u = [].slice.call(t, 1);
u.push(e), e = t[0].apply(null, u)
}
return function() {
return e.apply(this, arguments), r.value && r.value()
}
}
}
It also appears in these bl.ocks:
source to share
I'm not familiar with d3.js
, but I looked at its source code and found that this feature is on a branch graphics-pipeline
.
For example you can find related code here: https://github.com/mbostock/d3/commit/a3f2adab7f85e2a0c82288ead88c1e484c9e3ea3
A small piece of code to illustrate how it works:
var pipeline = function () {
var pipes = [];
return {
source: function () {
pipes[0] = arguments;
return this;
},
pipe: function () {
pipes.push(arguments);
return this;
},
sink: function () {
var sink = arguments[0].apply(null, [].slice.call(arguments, 1)),
pipe;
while (pipe = pipes.pop()) {
var args = [].slice.call(pipe, 1);
args.push(sink);
sink = pipe[0].apply(null, args);
}
return sink;
}
};
};
var log = document.getElementById('log');
function f() {
var argsAsString = Array.prototype.join.call(arguments, ', ');
var resultName = 'r' + f.callCounter++;
log.innerHTML += resultName + ' = f(' + argsAsString + ')<br>';
return resultName;
}
f.callCounter = 1;
pipeline().
source(f, 'a', 1).
pipe(f, 'b', 2).
pipe(f, 'c', 3).
sink(f, 'd', 4);
<div id="log"></div>
A few comments about this function:
- Methods
source
andpipe
work with the same private propertypipes
. The only difference is that itsource
sets the initial value forpipes
(pipes[0]
) when each callpipe
pushes a new pipe into the collection. - The previous fact gives us knowledge about the internal structure
d3.geo.jsonSource
. It should be similar to the arguments passed topipe
: the first argument is something called (a function), the rest of the arguments are parameters. - Suppose that
arguments = [f, a, b, c]
. Then the JavaScript templatearguments[0].apply(null, [].slice.call(arguments, 1))
meansf(a, b, c)
. You can see several places where it is used in implementationsink
.
With regard to practical use.
We can use it if we need a "chain" (or "pipe") of data processing. For example, if we have code like this:
function f(a, b, previousResult)
{
return a * b + (previousResult || 0);
}
var p = pipeline().
source(f, 1, 1).
pipe(f, 2, 10).
pipe(f, 3, 100).
sink(f, 4, 1000);
Then the result (value p
) will be 4321
.
In this particular case, we need to clarify what d3.geo.jsonSink
and is d3.geo.jsonSource
, but I hope I helped you see the meaning of the function pipeline
.
source to share