-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathwaterfall-connectors.js
108 lines (98 loc) · 3.06 KB
/
waterfall-connectors.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
(function() {
'use strict';
/*
* Waterfall connectors are orthogonal series connectors which visually join
* column series together by spanning the top or bottom of adjacent columns.
*
*##### Accessors
*
* `x` - Used in placement of the connector lines.
* `y` - Used in placement of the connector lines.
* `span` - calculates the length of the connector line
* `classes` - applies the class to the connector lines.
*
* @name waterfallConnectors
*/
d4.feature('waterfallConnectors', function(name) {
return {
accessors: {
beforeRender: function(data) {
var d = data.map(function(o) {
return o.values[0];
});
return d4.flatten(d);
},
classes: function(d, i) {
return 'series' + i;
},
span: function() {
if (d4.isOrdinalScale(this.x)) {
return this.x.rangeBand();
} else {
return this.y.rangeBand();
}
},
x: function(d) {
if (d4.isOrdinalScale(this.x)) {
return this.x(d[this.x.$key]);
} else {
var width = 0;
var xVal = (d.y0 + d.y) - Math.max(0, d.y);
if (d.y > 0) {
width = Math.abs(this.x(d.y0) - this.x(d.y0 + d.y));
}
return this.x(xVal) + width;
}
},
y: function(d) {
if (d4.isOrdinalScale(this.x)) {
return this.y(d.y0 + d.y);
} else {
return this.y(d[this.y.$key]);
}
}
},
render: function(scope, data, selection) {
var group = d4.appendOnce(selection, 'g.' + name);
var lines = group.selectAll('line').data(data);
lines.enter().append('line');
lines.exit().remove();
lines
.attr('class', d4.functor(scope.accessors.classes).bind(this))
.attr('x1', function(d, i) {
if (i === 0) {
return 0;
}
return d4.functor(scope.accessors.x).bind(this)(data[i - 1]);
}.bind(this))
.attr('y1', function(d, i) {
if (i === 0) {
return 0;
}
return d4.functor(scope.accessors.y).bind(this)(data[i - 1]);
}.bind(this))
.attr('x2', function(d, i) {
if (i === 0) {
return 0;
}
if (d4.isOrdinalScale(this.x)) {
return d4.functor(scope.accessors.x).bind(this)(d) + d4.functor(scope.accessors.span).bind(this)();
} else {
return d4.functor(scope.accessors.x).bind(this)(data[i - 1]);
}
}.bind(this))
.attr('y2', function(d, i) {
if (i === 0) {
return 0;
}
if (d4.isOrdinalScale(this.x)) {
return d4.functor(scope.accessors.y).bind(this)(data[i - 1]);
} else {
return d4.functor(scope.accessors.y).bind(this)(d) + d4.functor(scope.accessors.span).bind(this)(d);
}
}.bind(this));
return lines;
}
};
});
}).call(this);