chartx 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/.gitmodules +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +145 -0
- data/Rakefile +1 -0
- data/chartx.gemspec +40 -0
- data/lib/chartx/engine.rb +11 -0
- data/lib/chartx/helper.rb +184 -0
- data/lib/chartx/version.rb +3 -0
- data/lib/chartx.rb +3 -0
- data/screenshots/barchart.png +0 -0
- data/screenshots/bulletchart.png +0 -0
- data/screenshots/horizontalbarchart.png +0 -0
- data/screenshots/linechart.png +0 -0
- data/screenshots/linewithfocuschart.png +0 -0
- data/screenshots/multibarchart2.png +0 -0
- data/screenshots/piechart.png +0 -0
- data/screenshots/scatterchart.png +0 -0
- data/screenshots/stackedareachart.png +0 -0
- data/screenshots/stackedareachart3.png +0 -0
- data/vendor/assets/javascripts/chartx-core.js +9 -0
- data/vendor/assets/javascripts/chartx-models.js +2 -0
- data/vendor/assets/javascripts/nvd3/.gitignore +27 -0
- data/vendor/assets/javascripts/nvd3/.jshintrc +3 -0
- data/vendor/assets/javascripts/nvd3/LICENSE.md +49 -0
- data/vendor/assets/javascripts/nvd3/README.md +1 -0
- data/vendor/assets/javascripts/nvd3/lib/cie.js +155 -0
- data/vendor/assets/javascripts/nvd3/lib/crossfilter.js +1180 -0
- data/vendor/assets/javascripts/nvd3/lib/crossfilter.min.js +1 -0
- data/vendor/assets/javascripts/nvd3/lib/d3.js +8798 -0
- data/vendor/assets/javascripts/nvd3/lib/d3.min.js +5 -0
- data/vendor/assets/javascripts/nvd3/lib/fisheye.js +86 -0
- data/vendor/assets/javascripts/nvd3/lib/hive.js +80 -0
- data/vendor/assets/javascripts/nvd3/lib/horizon.js +192 -0
- data/vendor/assets/javascripts/nvd3/lib/sankey.js +292 -0
- data/vendor/assets/javascripts/nvd3/nv.d3.js +13048 -0
- data/vendor/assets/javascripts/nvd3/nv.d3.min.js +6 -0
- data/vendor/assets/javascripts/nvd3/src/core.js +118 -0
- data/vendor/assets/javascripts/nvd3/src/intro.js +1 -0
- data/vendor/assets/javascripts/nvd3/src/models/axis.js +398 -0
- data/vendor/assets/javascripts/nvd3/src/models/boilerplate.js +102 -0
- data/vendor/assets/javascripts/nvd3/src/models/bullet.js +377 -0
- data/vendor/assets/javascripts/nvd3/src/models/bulletChart.js +341 -0
- data/vendor/assets/javascripts/nvd3/src/models/cumulativeLineChart.js +685 -0
- data/vendor/assets/javascripts/nvd3/src/models/discreteBar.js +327 -0
- data/vendor/assets/javascripts/nvd3/src/models/discreteBarChart.js +290 -0
- data/vendor/assets/javascripts/nvd3/src/models/distribution.js +146 -0
- data/vendor/assets/javascripts/nvd3/src/models/historicalBar.js +289 -0
- data/vendor/assets/javascripts/nvd3/src/models/historicalBarChart.js +421 -0
- data/vendor/assets/javascripts/nvd3/src/models/indentedTree.js +317 -0
- data/vendor/assets/javascripts/nvd3/src/models/legend.js +207 -0
- data/vendor/assets/javascripts/nvd3/src/models/line.js +284 -0
- data/vendor/assets/javascripts/nvd3/src/models/lineChart.js +421 -0
- data/vendor/assets/javascripts/nvd3/src/models/linePlusBarChart.js +455 -0
- data/vendor/assets/javascripts/nvd3/src/models/linePlusBarWithFocusChart.js +665 -0
- data/vendor/assets/javascripts/nvd3/src/models/lineWithFisheye.js +197 -0
- data/vendor/assets/javascripts/nvd3/src/models/lineWithFisheyeChart.js +319 -0
- data/vendor/assets/javascripts/nvd3/src/models/lineWithFocusChart.js +560 -0
- data/vendor/assets/javascripts/nvd3/src/models/multiBar.js +442 -0
- data/vendor/assets/javascripts/nvd3/src/models/multiBarChart.js +506 -0
- data/vendor/assets/javascripts/nvd3/src/models/multiBarHorizontal.js +420 -0
- data/vendor/assets/javascripts/nvd3/src/models/multiBarHorizontalChart.js +448 -0
- data/vendor/assets/javascripts/nvd3/src/models/multiBarTimeSeries.js +371 -0
- data/vendor/assets/javascripts/nvd3/src/models/multiBarTimeSeriesChart.js +403 -0
- data/vendor/assets/javascripts/nvd3/src/models/multiChart.js +444 -0
- data/vendor/assets/javascripts/nvd3/src/models/ohlcBar.js +365 -0
- data/vendor/assets/javascripts/nvd3/src/models/parallelCoordinates.js +238 -0
- data/vendor/assets/javascripts/nvd3/src/models/pie.js +386 -0
- data/vendor/assets/javascripts/nvd3/src/models/pieChart.js +302 -0
- data/vendor/assets/javascripts/nvd3/src/models/scatter.js +660 -0
- data/vendor/assets/javascripts/nvd3/src/models/scatterChart.js +614 -0
- data/vendor/assets/javascripts/nvd3/src/models/scatterPlusLineChart.js +610 -0
- data/vendor/assets/javascripts/nvd3/src/models/sparkline.js +179 -0
- data/vendor/assets/javascripts/nvd3/src/models/sparklinePlus.js +293 -0
- data/vendor/assets/javascripts/nvd3/src/models/stackedArea.js +336 -0
- data/vendor/assets/javascripts/nvd3/src/models/stackedAreaChart.js +490 -0
- data/vendor/assets/javascripts/nvd3/src/nv.d3.css +704 -0
- data/vendor/assets/javascripts/nvd3/src/outro.js +1 -0
- data/vendor/assets/javascripts/nvd3/src/tooltip.js +133 -0
- data/vendor/assets/javascripts/nvd3/src/utils.js +118 -0
- data/vendor/assets/javascripts/set-env.js.erb +1 -0
- data/vendor/assets/stylesheets/chartx.css +3 -0
- metadata +189 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
d3.horizon = function() {
|
|
3
|
+
var bands = 1, // between 1 and 5, typically
|
|
4
|
+
mode = "offset", // or mirror
|
|
5
|
+
interpolate = "linear", // or basis, monotone, step-before, etc.
|
|
6
|
+
x = d3_horizonX,
|
|
7
|
+
y = d3_horizonY,
|
|
8
|
+
w = 960,
|
|
9
|
+
h = 40,
|
|
10
|
+
duration = 0;
|
|
11
|
+
|
|
12
|
+
var color = d3.scale.linear()
|
|
13
|
+
.domain([-1, 0, 1])
|
|
14
|
+
.range(["#d62728", "#fff", "#1f77b4"]);
|
|
15
|
+
|
|
16
|
+
// For each small multiple…
|
|
17
|
+
function horizon(g) {
|
|
18
|
+
g.each(function(d, i) {
|
|
19
|
+
var g = d3.select(this),
|
|
20
|
+
n = 2 * bands + 1,
|
|
21
|
+
xMin = Infinity,
|
|
22
|
+
xMax = -Infinity,
|
|
23
|
+
yMax = -Infinity,
|
|
24
|
+
x0, // old x-scale
|
|
25
|
+
y0, // old y-scale
|
|
26
|
+
id; // unique id for paths
|
|
27
|
+
|
|
28
|
+
// Compute x- and y-values along with extents.
|
|
29
|
+
var data = d.map(function(d, i) {
|
|
30
|
+
var xv = x.call(this, d, i),
|
|
31
|
+
yv = y.call(this, d, i);
|
|
32
|
+
if (xv < xMin) xMin = xv;
|
|
33
|
+
if (xv > xMax) xMax = xv;
|
|
34
|
+
if (-yv > yMax) yMax = -yv;
|
|
35
|
+
if (yv > yMax) yMax = yv;
|
|
36
|
+
return [xv, yv];
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Compute the new x- and y-scales, and transform.
|
|
40
|
+
var x1 = d3.scale.linear().domain([xMin, xMax]).range([0, w]),
|
|
41
|
+
y1 = d3.scale.linear().domain([0, yMax]).range([0, h * bands]),
|
|
42
|
+
t1 = d3_horizonTransform(bands, h, mode);
|
|
43
|
+
|
|
44
|
+
// Retrieve the old scales, if this is an update.
|
|
45
|
+
if (this.__chart__) {
|
|
46
|
+
x0 = this.__chart__.x;
|
|
47
|
+
y0 = this.__chart__.y;
|
|
48
|
+
t0 = this.__chart__.t;
|
|
49
|
+
id = this.__chart__.id;
|
|
50
|
+
} else {
|
|
51
|
+
x0 = x1.copy();
|
|
52
|
+
y0 = y1.copy();
|
|
53
|
+
t0 = t1;
|
|
54
|
+
id = ++d3_horizonId;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// We'll use a defs to store the area path and the clip path.
|
|
58
|
+
var defs = g.selectAll("defs")
|
|
59
|
+
.data([null]);
|
|
60
|
+
|
|
61
|
+
// The clip path is a simple rect.
|
|
62
|
+
defs.enter().append("defs").append("clipPath")
|
|
63
|
+
.attr("id", "d3_horizon_clip" + id)
|
|
64
|
+
.append("rect")
|
|
65
|
+
.attr("width", w)
|
|
66
|
+
.attr("height", h);
|
|
67
|
+
|
|
68
|
+
defs.select("rect").transition()
|
|
69
|
+
.duration(duration)
|
|
70
|
+
.attr("width", w)
|
|
71
|
+
.attr("height", h);
|
|
72
|
+
|
|
73
|
+
// We'll use a container to clip all horizon layers at once.
|
|
74
|
+
g.selectAll("g")
|
|
75
|
+
.data([null])
|
|
76
|
+
.enter().append("g")
|
|
77
|
+
.attr("clip-path", "url(#d3_horizon_clip" + id + ")");
|
|
78
|
+
|
|
79
|
+
// Instantiate each copy of the path with different transforms.
|
|
80
|
+
var path = g.select("g").selectAll("path")
|
|
81
|
+
.data(d3.range(-1, -bands - 1, -1).concat(d3.range(1, bands + 1)), Number);
|
|
82
|
+
|
|
83
|
+
var d0 = d3_horizonArea
|
|
84
|
+
.interpolate(interpolate)
|
|
85
|
+
.x(function(d) { return x0(d[0]); })
|
|
86
|
+
.y0(h * bands)
|
|
87
|
+
.y1(function(d) { return h * bands - y0(d[1]); })
|
|
88
|
+
(data);
|
|
89
|
+
|
|
90
|
+
var d1 = d3_horizonArea
|
|
91
|
+
.x(function(d) { return x1(d[0]); })
|
|
92
|
+
.y1(function(d) { return h * bands - y1(d[1]); })
|
|
93
|
+
(data);
|
|
94
|
+
|
|
95
|
+
path.enter().append("path")
|
|
96
|
+
.style("fill", color)
|
|
97
|
+
.attr("transform", t0)
|
|
98
|
+
.attr("d", d0);
|
|
99
|
+
|
|
100
|
+
path.transition()
|
|
101
|
+
.duration(duration)
|
|
102
|
+
.style("fill", color)
|
|
103
|
+
.attr("transform", t1)
|
|
104
|
+
.attr("d", d1);
|
|
105
|
+
|
|
106
|
+
path.exit().transition()
|
|
107
|
+
.duration(duration)
|
|
108
|
+
.attr("transform", t1)
|
|
109
|
+
.attr("d", d1)
|
|
110
|
+
.remove();
|
|
111
|
+
|
|
112
|
+
// Stash the new scales.
|
|
113
|
+
this.__chart__ = {x: x1, y: y1, t: t1, id: id};
|
|
114
|
+
});
|
|
115
|
+
d3.timer.flush();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
horizon.duration = function(x) {
|
|
119
|
+
if (!arguments.length) return duration;
|
|
120
|
+
duration = +x;
|
|
121
|
+
return horizon;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
horizon.bands = function(x) {
|
|
125
|
+
if (!arguments.length) return bands;
|
|
126
|
+
bands = +x;
|
|
127
|
+
color.domain([-bands, 0, bands]);
|
|
128
|
+
return horizon;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
horizon.mode = function(x) {
|
|
132
|
+
if (!arguments.length) return mode;
|
|
133
|
+
mode = x + "";
|
|
134
|
+
return horizon;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
horizon.colors = function(x) {
|
|
138
|
+
if (!arguments.length) return color.range();
|
|
139
|
+
color.range(x);
|
|
140
|
+
return horizon;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
horizon.interpolate = function(x) {
|
|
144
|
+
if (!arguments.length) return interpolate;
|
|
145
|
+
interpolate = x + "";
|
|
146
|
+
return horizon;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
horizon.x = function(z) {
|
|
150
|
+
if (!arguments.length) return x;
|
|
151
|
+
x = z;
|
|
152
|
+
return horizon;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
horizon.y = function(z) {
|
|
156
|
+
if (!arguments.length) return y;
|
|
157
|
+
y = z;
|
|
158
|
+
return horizon;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
horizon.width = function(x) {
|
|
162
|
+
if (!arguments.length) return w;
|
|
163
|
+
w = +x;
|
|
164
|
+
return horizon;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
horizon.height = function(x) {
|
|
168
|
+
if (!arguments.length) return h;
|
|
169
|
+
h = +x;
|
|
170
|
+
return horizon;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
return horizon;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
var d3_horizonArea = d3.svg.area(),
|
|
177
|
+
d3_horizonId = 0;
|
|
178
|
+
|
|
179
|
+
function d3_horizonX(d) {
|
|
180
|
+
return d[0];
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function d3_horizonY(d) {
|
|
184
|
+
return d[1];
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function d3_horizonTransform(bands, h, mode) {
|
|
188
|
+
return mode == "offset"
|
|
189
|
+
? function(d) { return "translate(0," + (d + (d < 0) - bands) * h + ")"; }
|
|
190
|
+
: function(d) { return (d < 0 ? "scale(1,-1)" : "") + "translate(0," + (d - bands) * h + ")"; };
|
|
191
|
+
}
|
|
192
|
+
})();
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
d3.sankey = function() {
|
|
2
|
+
var sankey = {},
|
|
3
|
+
nodeWidth = 24,
|
|
4
|
+
nodePadding = 8,
|
|
5
|
+
size = [1, 1],
|
|
6
|
+
nodes = [],
|
|
7
|
+
links = [];
|
|
8
|
+
|
|
9
|
+
sankey.nodeWidth = function(_) {
|
|
10
|
+
if (!arguments.length) return nodeWidth;
|
|
11
|
+
nodeWidth = +_;
|
|
12
|
+
return sankey;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
sankey.nodePadding = function(_) {
|
|
16
|
+
if (!arguments.length) return nodePadding;
|
|
17
|
+
nodePadding = +_;
|
|
18
|
+
return sankey;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
sankey.nodes = function(_) {
|
|
22
|
+
if (!arguments.length) return nodes;
|
|
23
|
+
nodes = _;
|
|
24
|
+
return sankey;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
sankey.links = function(_) {
|
|
28
|
+
if (!arguments.length) return links;
|
|
29
|
+
links = _;
|
|
30
|
+
return sankey;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
sankey.size = function(_) {
|
|
34
|
+
if (!arguments.length) return size;
|
|
35
|
+
size = _;
|
|
36
|
+
return sankey;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
sankey.layout = function(iterations) {
|
|
40
|
+
computeNodeLinks();
|
|
41
|
+
computeNodeValues();
|
|
42
|
+
computeNodeBreadths();
|
|
43
|
+
computeNodeDepths(iterations);
|
|
44
|
+
computeLinkDepths();
|
|
45
|
+
return sankey;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
sankey.relayout = function() {
|
|
49
|
+
computeLinkDepths();
|
|
50
|
+
return sankey;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
sankey.link = function() {
|
|
54
|
+
var curvature = .5;
|
|
55
|
+
|
|
56
|
+
function link(d) {
|
|
57
|
+
var x0 = d.source.x + d.source.dx,
|
|
58
|
+
x1 = d.target.x,
|
|
59
|
+
xi = d3.interpolateNumber(x0, x1),
|
|
60
|
+
x2 = xi(curvature),
|
|
61
|
+
x3 = xi(1 - curvature),
|
|
62
|
+
y0 = d.source.y + d.sy + d.dy / 2,
|
|
63
|
+
y1 = d.target.y + d.ty + d.dy / 2;
|
|
64
|
+
return "M" + x0 + "," + y0
|
|
65
|
+
+ "C" + x2 + "," + y0
|
|
66
|
+
+ " " + x3 + "," + y1
|
|
67
|
+
+ " " + x1 + "," + y1;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
link.curvature = function(_) {
|
|
71
|
+
if (!arguments.length) return curvature;
|
|
72
|
+
curvature = +_;
|
|
73
|
+
return link;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
return link;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Populate the sourceLinks and targetLinks for each node.
|
|
80
|
+
// Also, if the source and target are not objects, assume they are indices.
|
|
81
|
+
function computeNodeLinks() {
|
|
82
|
+
nodes.forEach(function(node) {
|
|
83
|
+
node.sourceLinks = [];
|
|
84
|
+
node.targetLinks = [];
|
|
85
|
+
});
|
|
86
|
+
links.forEach(function(link) {
|
|
87
|
+
var source = link.source,
|
|
88
|
+
target = link.target;
|
|
89
|
+
if (typeof source === "number") source = link.source = nodes[link.source];
|
|
90
|
+
if (typeof target === "number") target = link.target = nodes[link.target];
|
|
91
|
+
source.sourceLinks.push(link);
|
|
92
|
+
target.targetLinks.push(link);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Compute the value (size) of each node by summing the associated links.
|
|
97
|
+
function computeNodeValues() {
|
|
98
|
+
nodes.forEach(function(node) {
|
|
99
|
+
node.value = Math.max(
|
|
100
|
+
d3.sum(node.sourceLinks, value),
|
|
101
|
+
d3.sum(node.targetLinks, value)
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Iteratively assign the breadth (x-position) for each node.
|
|
107
|
+
// Nodes are assigned the maximum breadth of incoming neighbors plus one;
|
|
108
|
+
// nodes with no incoming links are assigned breadth zero, while
|
|
109
|
+
// nodes with no outgoing links are assigned the maximum breadth.
|
|
110
|
+
function computeNodeBreadths() {
|
|
111
|
+
var remainingNodes = nodes,
|
|
112
|
+
nextNodes,
|
|
113
|
+
x = 0;
|
|
114
|
+
|
|
115
|
+
while (remainingNodes.length) {
|
|
116
|
+
nextNodes = [];
|
|
117
|
+
remainingNodes.forEach(function(node) {
|
|
118
|
+
node.x = x;
|
|
119
|
+
node.dx = nodeWidth;
|
|
120
|
+
node.sourceLinks.forEach(function(link) {
|
|
121
|
+
nextNodes.push(link.target);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
remainingNodes = nextNodes;
|
|
125
|
+
++x;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
//
|
|
129
|
+
moveSinksRight(x);
|
|
130
|
+
scaleNodeBreadths((size[0] - nodeWidth) / (x - 1));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function moveSourcesRight() {
|
|
134
|
+
nodes.forEach(function(node) {
|
|
135
|
+
if (!node.targetLinks.length) {
|
|
136
|
+
node.x = d3.min(node.sourceLinks, function(d) { return d.target.x; }) - 1;
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function moveSinksRight(x) {
|
|
142
|
+
nodes.forEach(function(node) {
|
|
143
|
+
if (!node.sourceLinks.length) {
|
|
144
|
+
node.x = x - 1;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function scaleNodeBreadths(kx) {
|
|
150
|
+
nodes.forEach(function(node) {
|
|
151
|
+
node.x *= kx;
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function computeNodeDepths(iterations) {
|
|
156
|
+
var nodesByBreadth = d3.nest()
|
|
157
|
+
.key(function(d) { return d.x; })
|
|
158
|
+
.sortKeys(d3.ascending)
|
|
159
|
+
.entries(nodes)
|
|
160
|
+
.map(function(d) { return d.values; });
|
|
161
|
+
|
|
162
|
+
//
|
|
163
|
+
initializeNodeDepth();
|
|
164
|
+
resolveCollisions();
|
|
165
|
+
for (var alpha = 1; iterations > 0; --iterations) {
|
|
166
|
+
relaxRightToLeft(alpha *= .99);
|
|
167
|
+
resolveCollisions();
|
|
168
|
+
relaxLeftToRight(alpha);
|
|
169
|
+
resolveCollisions();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function initializeNodeDepth() {
|
|
173
|
+
var ky = d3.min(nodesByBreadth, function(nodes) {
|
|
174
|
+
return (size[1] - (nodes.length - 1) * nodePadding) / d3.sum(nodes, value);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
nodesByBreadth.forEach(function(nodes) {
|
|
178
|
+
nodes.forEach(function(node, i) {
|
|
179
|
+
node.y = i;
|
|
180
|
+
node.dy = node.value * ky;
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
links.forEach(function(link) {
|
|
185
|
+
link.dy = link.value * ky;
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function relaxLeftToRight(alpha) {
|
|
190
|
+
nodesByBreadth.forEach(function(nodes, breadth) {
|
|
191
|
+
nodes.forEach(function(node) {
|
|
192
|
+
if (node.targetLinks.length) {
|
|
193
|
+
var y = d3.sum(node.targetLinks, weightedSource) / d3.sum(node.targetLinks, value);
|
|
194
|
+
node.y += (y - center(node)) * alpha;
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
function weightedSource(link) {
|
|
200
|
+
return center(link.source) * link.value;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function relaxRightToLeft(alpha) {
|
|
205
|
+
nodesByBreadth.slice().reverse().forEach(function(nodes) {
|
|
206
|
+
nodes.forEach(function(node) {
|
|
207
|
+
if (node.sourceLinks.length) {
|
|
208
|
+
var y = d3.sum(node.sourceLinks, weightedTarget) / d3.sum(node.sourceLinks, value);
|
|
209
|
+
node.y += (y - center(node)) * alpha;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
function weightedTarget(link) {
|
|
215
|
+
return center(link.target) * link.value;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function resolveCollisions() {
|
|
220
|
+
nodesByBreadth.forEach(function(nodes) {
|
|
221
|
+
var node,
|
|
222
|
+
dy,
|
|
223
|
+
y0 = 0,
|
|
224
|
+
n = nodes.length,
|
|
225
|
+
i;
|
|
226
|
+
|
|
227
|
+
// Push any overlapping nodes down.
|
|
228
|
+
nodes.sort(ascendingDepth);
|
|
229
|
+
for (i = 0; i < n; ++i) {
|
|
230
|
+
node = nodes[i];
|
|
231
|
+
dy = y0 - node.y;
|
|
232
|
+
if (dy > 0) node.y += dy;
|
|
233
|
+
y0 = node.y + node.dy + nodePadding;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// If the bottommost node goes outside the bounds, push it back up.
|
|
237
|
+
dy = y0 - nodePadding - size[1];
|
|
238
|
+
if (dy > 0) {
|
|
239
|
+
y0 = node.y -= dy;
|
|
240
|
+
|
|
241
|
+
// Push any overlapping nodes back up.
|
|
242
|
+
for (i = n - 2; i >= 0; --i) {
|
|
243
|
+
node = nodes[i];
|
|
244
|
+
dy = node.y + node.dy + nodePadding - y0;
|
|
245
|
+
if (dy > 0) node.y -= dy;
|
|
246
|
+
y0 = node.y;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function ascendingDepth(a, b) {
|
|
253
|
+
return a.y - b.y;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function computeLinkDepths() {
|
|
258
|
+
nodes.forEach(function(node) {
|
|
259
|
+
node.sourceLinks.sort(ascendingTargetDepth);
|
|
260
|
+
node.targetLinks.sort(ascendingSourceDepth);
|
|
261
|
+
});
|
|
262
|
+
nodes.forEach(function(node) {
|
|
263
|
+
var sy = 0, ty = 0;
|
|
264
|
+
node.sourceLinks.forEach(function(link) {
|
|
265
|
+
link.sy = sy;
|
|
266
|
+
sy += link.dy;
|
|
267
|
+
});
|
|
268
|
+
node.targetLinks.forEach(function(link) {
|
|
269
|
+
link.ty = ty;
|
|
270
|
+
ty += link.dy;
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
function ascendingSourceDepth(a, b) {
|
|
275
|
+
return a.source.y - b.source.y;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function ascendingTargetDepth(a, b) {
|
|
279
|
+
return a.target.y - b.target.y;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
function center(node) {
|
|
284
|
+
return node.y + node.dy / 2;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function value(link) {
|
|
288
|
+
return link.value;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return sankey;
|
|
292
|
+
};
|