-
Notifications
You must be signed in to change notification settings - Fork 46
/
arc-series.js
105 lines (91 loc) · 3.4 KB
/
arc-series.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
(function() {
'use strict';
/*
* Arc series is a collection of arcs suitable for those needed by pie and donut charts.
* Many of the accessors of this feature proxy directly to D3's arc object:
* https://github.com/mbostock/d3/wiki/SVG-Shapes#arc
*
*##### Accessors
*
* `centroid` - proxied accessor to the navtive d3 function
* `classes` - classes assigned to the arc label.
* `duration` - time in milliseconds for the transition to occur.
* `endAngle` - proxied accessor to the navtive d3 function
* `innerRadius` - proxied accessor to the navtive d3 function
* `key` - unique identifier used for linking the element during d3's transition process
* `outerRadius` - proxied accessor to the navtive d3 function
* `startAngle` - proxied accessor to the navtive d3 function
* `x` - position across the x axis
* `y` - position across the y axis
*
* @name arcSeries
*/
d4.feature('arcSeries', function(name) {
var arc = d3.svg.arc();
return {
accessors: {
classes: function(d, n) {
return 'arc stroke fill series' + n;
},
duration: 750,
key: d4.functor(d4.defaultKey),
x: function() {
return this.width / 2;
},
y: function() {
return this.height / 2;
}
},
proxies: [{
target: arc
}],
render: function(scope, data, selection) {
// extracted from: http://bl.ocks.org/mbostock/1346410
// Store the displayed angles in _current.
// Then, interpolate from _current to the new angles.
// During the transition, _current is updated in-place by d3.interpolate.
var arcTween = function(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function(t) {
return arc(i(t));
};
};
// FIXME: radius and arcWidth are assumed to be provided by the enclosing chart. maybe we should default back to a feature based implementation if it doesn't find it?
var r = d4.functor(this.radius).bind(this)(),
x = d4.functor(scope.accessors.x).bind(this)(),
y = d4.functor(scope.accessors.y).bind(this)(),
aw = d4.functor(this.arcWidth).bind(this)(r);
arc
.innerRadius(r)
.outerRadius(r - aw);
var group = d4.appendOnce(selection, 'g.' + name);
var arcGroups = group.selectAll('g.' + name + '-group')
.data(data);
arcGroups.enter().append('g');
arcGroups.attr('class', name + '-group')
.attr('transform', 'translate(' + x + ',' + y + ')');
var arcs = arcGroups.selectAll('path')
.data(function(d) {
return d.values;
}, d4.functor(scope.accessors.key).bind(this));
arcs.enter().append('path')
.each(function(d) {
this._current = d;
});
// update
arcs.transition()
.duration(d4.functor(scope.accessors.duration).bind(this)())
.attrTween('d', arcTween);
// create new elements as needed
arcs.attr('class', d4.functor(scope.accessors.classes).bind(this))
.attr('data-key', d4.functor(scope.accessors.key).bind(this))
.attr('d', arc);
//remove old elements as needed
arcs.exit().remove();
arcGroups.exit().remove();
return arc;
}
};
});
}).call(this);