d3_rails 0.0.10 → 0.1.0
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/README.md +4 -0
- data/lib/d3_rails/version.rb +1 -1
- data/vendor/assets/javascripts/d3.chart.js +0 -0
- data/vendor/assets/javascripts/d3.geo.js +0 -0
- data/vendor/assets/javascripts/d3.geom.js +11 -1
- data/vendor/assets/javascripts/d3.js +549 -84
- data/vendor/assets/javascripts/d3.layout.js +21 -18
- data/vendor/assets/javascripts/d3.time.js +0 -0
- data/vendor/assets/javascripts/{d3-csv.js → d3_csv.js} +0 -0
- metadata +9 -9
data/README.md
CHANGED
@@ -12,6 +12,10 @@ handle interactivity, and incorporate smooth transitions and staged animations
|
|
12
12
|
into your pages. You can use D3 as a visualization framework (like Protovis),
|
13
13
|
or you can use it to build dynamic pages (like jQuery).
|
14
14
|
|
15
|
+
# D3 Version
|
16
|
+
|
17
|
+
The current release of this gem is using **D3 v=2.5.0**
|
18
|
+
|
15
19
|
### Installation
|
16
20
|
|
17
21
|
This gem should work out of the box. All you have to do is add the gem to your Gemfile:
|
data/lib/d3_rails/version.rb
CHANGED
File without changes
|
File without changes
|
@@ -268,6 +268,17 @@ function d3_geom_polygonIntersect(c, d, a, b) {
|
|
268
268
|
// http://blog.thejit.org/assets/voronoijs/voronoi.js
|
269
269
|
// See lib/jit/LICENSE for details.
|
270
270
|
|
271
|
+
// Notes:
|
272
|
+
//
|
273
|
+
// This implementation does not clip the returned polygons, so if you want to
|
274
|
+
// clip them to a particular shape you will need to do that either in SVG or by
|
275
|
+
// post-processing with d3.geom.polygon's clip method.
|
276
|
+
//
|
277
|
+
// If any vertices are coincident or have NaN positions, the behavior of this
|
278
|
+
// method is undefined. Most likely invalid polygons will be returned. You
|
279
|
+
// should filter invalid points, and consolidate coincident points, before
|
280
|
+
// computing the tessellation.
|
281
|
+
|
271
282
|
/**
|
272
283
|
* @param vertices [[x1, y1], [x2, y2], …]
|
273
284
|
* @returns polygons [[[x1, y1], [x2, y2], …], …]
|
@@ -275,7 +286,6 @@ function d3_geom_polygonIntersect(c, d, a, b) {
|
|
275
286
|
d3.geom.voronoi = function(vertices) {
|
276
287
|
var polygons = vertices.map(function() { return []; });
|
277
288
|
|
278
|
-
// Note: we expect the caller to clip the polygons, if needed.
|
279
289
|
d3_voronoi_tessellate(vertices, function(e) {
|
280
290
|
var s1,
|
281
291
|
s2,
|
@@ -10,7 +10,7 @@ try {
|
|
10
10
|
d3_style_setProperty.call(this, name, value + "", priority);
|
11
11
|
};
|
12
12
|
}
|
13
|
-
d3 = {version: "2.
|
13
|
+
d3 = {version: "2.5.0"}; // semver
|
14
14
|
var d3_array = d3_arraySlice; // conversion for NodeLists
|
15
15
|
|
16
16
|
function d3_arrayCopy(pseudoarray) {
|
@@ -105,6 +105,42 @@ d3.max = function(array, f) {
|
|
105
105
|
}
|
106
106
|
return a;
|
107
107
|
};
|
108
|
+
d3.extent = function(array, f) {
|
109
|
+
var i = -1,
|
110
|
+
n = array.length,
|
111
|
+
a,
|
112
|
+
b,
|
113
|
+
c;
|
114
|
+
if (arguments.length === 1) {
|
115
|
+
while (++i < n && ((a = c = array[i]) == null || a != a)) a = c = undefined;
|
116
|
+
while (++i < n) if ((b = array[i]) != null) {
|
117
|
+
if (a > b) a = b;
|
118
|
+
if (c < b) c = b;
|
119
|
+
}
|
120
|
+
} else {
|
121
|
+
while (++i < n && ((a = c = f.call(array, array[i], i)) == null || a != a)) a = undefined;
|
122
|
+
while (++i < n) if ((b = f.call(array, array[i], i)) != null) {
|
123
|
+
if (a > b) a = b;
|
124
|
+
if (c < b) c = b;
|
125
|
+
}
|
126
|
+
}
|
127
|
+
return [a, c];
|
128
|
+
};
|
129
|
+
d3.random = {
|
130
|
+
normal: function(mean, deviation) {
|
131
|
+
if (arguments.length < 2) deviation = 1;
|
132
|
+
if (arguments.length < 1) mean = 0;
|
133
|
+
return function() {
|
134
|
+
var x, y, r;
|
135
|
+
do {
|
136
|
+
x = Math.random() * 2 - 1;
|
137
|
+
y = Math.random() * 2 - 1;
|
138
|
+
r = x * x + y * y;
|
139
|
+
} while (!r || r > 1);
|
140
|
+
return mean + deviation * x * Math.sqrt(-2 * Math.log(r) / r);
|
141
|
+
};
|
142
|
+
}
|
143
|
+
};
|
108
144
|
function d3_number(x) {
|
109
145
|
return x != null && !isNaN(x);
|
110
146
|
}
|
@@ -438,47 +474,59 @@ d3.ns = {
|
|
438
474
|
}
|
439
475
|
|
440
476
|
};
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
type = arguments[i];
|
447
|
-
dispatch[type] = d3_dispatch(type);
|
448
|
-
}
|
477
|
+
d3.dispatch = function() {
|
478
|
+
var dispatch = new d3_dispatch(),
|
479
|
+
i = -1,
|
480
|
+
n = arguments.length;
|
481
|
+
while (++i < n) dispatch[arguments[i]] = d3_dispatch_event();
|
449
482
|
return dispatch;
|
450
483
|
};
|
451
484
|
|
452
|
-
function d3_dispatch(
|
453
|
-
var dispatch = {},
|
454
|
-
listeners = [];
|
485
|
+
function d3_dispatch() {}
|
455
486
|
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
}
|
460
|
-
listeners.push({listener: listener, on: true});
|
461
|
-
return dispatch;
|
462
|
-
};
|
487
|
+
d3_dispatch.prototype.on = function(type, listener) {
|
488
|
+
var i = type.indexOf("."),
|
489
|
+
name = "";
|
463
490
|
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
491
|
+
// Extract optional namespace, e.g., "click.foo"
|
492
|
+
if (i > 0) {
|
493
|
+
name = type.substring(i + 1);
|
494
|
+
type = type.substring(0, i);
|
495
|
+
}
|
496
|
+
|
497
|
+
this[type].on(name, listener);
|
498
|
+
};
|
499
|
+
|
500
|
+
function d3_dispatch_event() {
|
501
|
+
var listeners = [],
|
502
|
+
listenerByName = {};
|
503
|
+
|
504
|
+
function dispatch() {
|
505
|
+
var z = listeners, // defensive reference
|
506
|
+
i = -1,
|
507
|
+
n = z.length,
|
508
|
+
l;
|
509
|
+
while (++i < n) if ((l = z[i])._on) l.apply(this, arguments);
|
510
|
+
}
|
511
|
+
|
512
|
+
dispatch.on = function(name, listener) {
|
513
|
+
var l, i;
|
514
|
+
|
515
|
+
// remove the old listener, if any
|
516
|
+
if (l = listenerByName[name]) {
|
517
|
+
l._on = false;
|
518
|
+
listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1));
|
519
|
+
delete listenerByName[name];
|
472
520
|
}
|
473
|
-
return dispatch;
|
474
|
-
};
|
475
521
|
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
522
|
+
// add the new listener, if any
|
523
|
+
if (listener) {
|
524
|
+
listener._on = true;
|
525
|
+
listeners.push(listener);
|
526
|
+
listenerByName[name] = listener;
|
481
527
|
}
|
528
|
+
|
529
|
+
return dispatch;
|
482
530
|
};
|
483
531
|
|
484
532
|
return dispatch;
|
@@ -732,6 +780,11 @@ function d3_ease_bounce(t) {
|
|
732
780
|
: 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
|
733
781
|
}
|
734
782
|
d3.event = null;
|
783
|
+
|
784
|
+
function d3_eventCancel() {
|
785
|
+
d3.event.stopPropagation();
|
786
|
+
d3.event.preventDefault();
|
787
|
+
}
|
735
788
|
d3.interpolate = function(a, b) {
|
736
789
|
var i = d3.interpolators.length, f;
|
737
790
|
while (--i >= 0 && !(f = d3.interpolators[i](a, b)));
|
@@ -826,6 +879,10 @@ d3.interpolateString = function(a, b) {
|
|
826
879
|
};
|
827
880
|
};
|
828
881
|
|
882
|
+
d3.interpolateTransform = function(a, b) {
|
883
|
+
return d3.interpolateString(d3.transform(a) + "", d3.transform(b) + "");
|
884
|
+
};
|
885
|
+
|
829
886
|
d3.interpolateRgb = function(a, b) {
|
830
887
|
a = d3.rgb(a);
|
831
888
|
b = d3.rgb(b);
|
@@ -896,20 +953,19 @@ d3.interpolateObject = function(a, b) {
|
|
896
953
|
};
|
897
954
|
}
|
898
955
|
|
899
|
-
var d3_interpolate_number = /[-+]?(?:\d
|
900
|
-
d3_interpolate_rgb = {background: 1, fill: 1, stroke: 1};
|
956
|
+
var d3_interpolate_number = /[-+]?(?:\d*\.?\d+)(?:[eE][-+]?\d+)?/g;
|
901
957
|
|
902
958
|
function d3_interpolateByName(n) {
|
903
|
-
return n
|
904
|
-
? d3.
|
959
|
+
return n == "transform"
|
960
|
+
? d3.interpolateTransform
|
905
961
|
: d3.interpolate;
|
906
962
|
}
|
907
963
|
|
908
964
|
d3.interpolators = [
|
909
965
|
d3.interpolateObject,
|
910
966
|
function(a, b) { return (b instanceof Array) && d3.interpolateArray(a, b); },
|
911
|
-
function(a, b) { return (typeof b === "string") && d3.interpolateString(
|
912
|
-
function(a, b) { return (typeof b === "string" ? b in d3_rgb_names || /^(#|rgb\(|hsl\()/.test(b) : b instanceof d3_Rgb || b instanceof d3_Hsl) && d3.interpolateRgb(
|
967
|
+
function(a, b) { return (typeof b === "string") && d3.interpolateString(a + "", b); },
|
968
|
+
function(a, b) { return (typeof b === "string" ? b in d3_rgb_names || /^(#|rgb\(|hsl\()/.test(b) : b instanceof d3_Rgb || b instanceof d3_Hsl) && d3.interpolateRgb(a + "", b); },
|
913
969
|
function(a, b) { return (typeof b === "number") && d3.interpolateNumber(+a, b); }
|
914
970
|
];
|
915
971
|
function d3_uninterpolateNumber(a, b) {
|
@@ -1871,7 +1927,7 @@ function d3_transition(groups, id, time) {
|
|
1871
1927
|
|
1872
1928
|
groups.each = function(type, listener) {
|
1873
1929
|
if (arguments.length < 2) return d3_transition_each.call(groups, type);
|
1874
|
-
event
|
1930
|
+
event.on(type, listener);
|
1875
1931
|
return groups;
|
1876
1932
|
};
|
1877
1933
|
|
@@ -1897,7 +1953,7 @@ function d3_transition(groups, id, time) {
|
|
1897
1953
|
}
|
1898
1954
|
}
|
1899
1955
|
|
1900
|
-
event.start.
|
1956
|
+
event.start.call(node, d, i);
|
1901
1957
|
if (!tick(elapsed)) d3.timer(tick, 0, time);
|
1902
1958
|
return 1;
|
1903
1959
|
}
|
@@ -1916,7 +1972,7 @@ function d3_transition(groups, id, time) {
|
|
1916
1972
|
if (t >= 1) {
|
1917
1973
|
stop();
|
1918
1974
|
d3_transitionInheritId = id;
|
1919
|
-
event.end.
|
1975
|
+
event.end.call(node, d, i);
|
1920
1976
|
d3_transitionInheritId = 0;
|
1921
1977
|
return 1;
|
1922
1978
|
}
|
@@ -1939,17 +1995,18 @@ function d3_transitionNull(d, i, a) {
|
|
1939
1995
|
return a != "" && d3_transitionRemove;
|
1940
1996
|
}
|
1941
1997
|
|
1942
|
-
function d3_transitionTween(b) {
|
1998
|
+
function d3_transitionTween(name, b) {
|
1999
|
+
var interpolate = d3_interpolateByName(name);
|
1943
2000
|
|
1944
2001
|
function transitionFunction(d, i, a) {
|
1945
2002
|
var v = b.call(this, d, i);
|
1946
2003
|
return v == null
|
1947
2004
|
? a != "" && d3_transitionRemove
|
1948
|
-
: a != v &&
|
2005
|
+
: a != v && interpolate(a, v);
|
1949
2006
|
}
|
1950
2007
|
|
1951
2008
|
function transitionString(d, i, a) {
|
1952
|
-
return a != b &&
|
2009
|
+
return a != b && interpolate(a, b);
|
1953
2010
|
}
|
1954
2011
|
|
1955
2012
|
return typeof b === "function" ? transitionFunction
|
@@ -2014,7 +2071,7 @@ d3_transitionPrototype.selectAll = function(selector) {
|
|
2014
2071
|
return d3_transition(subgroups, this.id, this.time).ease(this.ease());
|
2015
2072
|
};
|
2016
2073
|
d3_transitionPrototype.attr = function(name, value) {
|
2017
|
-
return this.attrTween(name, d3_transitionTween(value));
|
2074
|
+
return this.attrTween(name, d3_transitionTween(name, value));
|
2018
2075
|
};
|
2019
2076
|
|
2020
2077
|
d3_transitionPrototype.attrTween = function(nameNS, tween) {
|
@@ -2038,7 +2095,7 @@ d3_transitionPrototype.attrTween = function(nameNS, tween) {
|
|
2038
2095
|
};
|
2039
2096
|
d3_transitionPrototype.style = function(name, value, priority) {
|
2040
2097
|
if (arguments.length < 3) priority = "";
|
2041
|
-
return this.styleTween(name, d3_transitionTween(value), priority);
|
2098
|
+
return this.styleTween(name, d3_transitionTween(name, value), priority);
|
2042
2099
|
};
|
2043
2100
|
|
2044
2101
|
d3_transitionPrototype.styleTween = function(name, tween, priority) {
|
@@ -2191,6 +2248,54 @@ var d3_timer_frame = window.requestAnimationFrame
|
|
2191
2248
|
|| window.oRequestAnimationFrame
|
2192
2249
|
|| window.msRequestAnimationFrame
|
2193
2250
|
|| function(callback) { setTimeout(callback, 17); };
|
2251
|
+
d3.transform = function(string) {
|
2252
|
+
d3_transformG.setAttribute("transform", string);
|
2253
|
+
return new d3_transform(d3_transformG.transform.baseVal.consolidate().matrix);
|
2254
|
+
};
|
2255
|
+
|
2256
|
+
// Compute x-scale and normalize the first row.
|
2257
|
+
// Compute shear and make second row orthogonal to first.
|
2258
|
+
// Compute y-scale and normalize the second row.
|
2259
|
+
// Finally, compute the rotation.
|
2260
|
+
function d3_transform(m) {
|
2261
|
+
var r0 = [m.a, m.b],
|
2262
|
+
r1 = [m.c, m.d],
|
2263
|
+
kx = d3_transformNormalize(r0),
|
2264
|
+
kz = d3_transformDot(r0, r1),
|
2265
|
+
ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz));
|
2266
|
+
this.translate = [m.e, m.f];
|
2267
|
+
this.rotate = Math.atan2(m.b, m.a) * d3_transformDegrees;
|
2268
|
+
this.scale = [kx, ky || 0];
|
2269
|
+
this.skew = ky ? kz / ky * d3_transformDegrees : 0;
|
2270
|
+
};
|
2271
|
+
|
2272
|
+
d3_transform.prototype.toString = function() {
|
2273
|
+
return "translate(" + this.translate
|
2274
|
+
+ ")rotate(" + this.rotate
|
2275
|
+
+ ")skewX(" + this.skew
|
2276
|
+
+ ")scale(" + this.scale
|
2277
|
+
+ ")";
|
2278
|
+
};
|
2279
|
+
|
2280
|
+
function d3_transformDot(a, b) {
|
2281
|
+
return a[0] * b[0] + a[1] * b[1];
|
2282
|
+
}
|
2283
|
+
|
2284
|
+
function d3_transformNormalize(a) {
|
2285
|
+
var k = Math.sqrt(d3_transformDot(a, a));
|
2286
|
+
a[0] /= k;
|
2287
|
+
a[1] /= k;
|
2288
|
+
return k;
|
2289
|
+
}
|
2290
|
+
|
2291
|
+
function d3_transformCombine(a, b, k) {
|
2292
|
+
a[0] += k * b[0];
|
2293
|
+
a[1] += k * b[1];
|
2294
|
+
return a;
|
2295
|
+
}
|
2296
|
+
|
2297
|
+
var d3_transformG = document.createElementNS(d3.ns.prefix.svg, "g"),
|
2298
|
+
d3_transformDegrees = 180 / Math.PI;
|
2194
2299
|
function d3_noop() {}
|
2195
2300
|
d3.scale = {};
|
2196
2301
|
|
@@ -2515,6 +2620,10 @@ function d3_scale_ordinal(domain, ranger) {
|
|
2515
2620
|
return range[((index[x] || (index[x] = domain.push(x))) - 1) % range.length];
|
2516
2621
|
}
|
2517
2622
|
|
2623
|
+
function steps(start, step) {
|
2624
|
+
return d3.range(domain.length).map(function(i) { return start + step * i; });
|
2625
|
+
}
|
2626
|
+
|
2518
2627
|
scale.domain = function(x) {
|
2519
2628
|
if (!arguments.length) return domain;
|
2520
2629
|
domain = [];
|
@@ -2537,7 +2646,7 @@ function d3_scale_ordinal(domain, ranger) {
|
|
2537
2646
|
var start = x[0],
|
2538
2647
|
stop = x[1],
|
2539
2648
|
step = (stop - start) / (domain.length - 1 + padding);
|
2540
|
-
range = domain.length < 2 ?
|
2649
|
+
range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step);
|
2541
2650
|
rangeBand = 0;
|
2542
2651
|
ranger = {t: "rangePoints", x: x, p: padding};
|
2543
2652
|
return scale;
|
@@ -2548,7 +2657,7 @@ function d3_scale_ordinal(domain, ranger) {
|
|
2548
2657
|
var start = x[0],
|
2549
2658
|
stop = x[1],
|
2550
2659
|
step = (stop - start) / (domain.length + padding);
|
2551
|
-
range =
|
2660
|
+
range = steps(start + step * padding, step);
|
2552
2661
|
rangeBand = step * (1 - padding);
|
2553
2662
|
ranger = {t: "rangeBands", x: x, p: padding};
|
2554
2663
|
return scale;
|
@@ -2558,9 +2667,8 @@ function d3_scale_ordinal(domain, ranger) {
|
|
2558
2667
|
if (arguments.length < 2) padding = 0;
|
2559
2668
|
var start = x[0],
|
2560
2669
|
stop = x[1],
|
2561
|
-
step = Math.floor((stop - start) / (domain.length + padding))
|
2562
|
-
|
2563
|
-
range = d3.range(start + Math.round(err / 2), stop, step);
|
2670
|
+
step = Math.floor((stop - start) / (domain.length + padding));
|
2671
|
+
range = steps(start + Math.round((stop - start - (domain.length - padding) * step) / 2), step);
|
2564
2672
|
rangeBand = Math.round(step * (1 - padding));
|
2565
2673
|
ranger = {t: "rangeRoundBands", x: x, p: padding};
|
2566
2674
|
return scale;
|
@@ -3529,8 +3637,9 @@ function d3_svg_mousePoint(container, e) {
|
|
3529
3637
|
point = point.matrixTransform(container.getScreenCTM().inverse());
|
3530
3638
|
return [point.x, point.y];
|
3531
3639
|
};
|
3532
|
-
d3.svg.touches = function(container) {
|
3533
|
-
|
3640
|
+
d3.svg.touches = function(container, touches) {
|
3641
|
+
if (arguments.length < 2) touches = d3.event.touches;
|
3642
|
+
|
3534
3643
|
return touches ? d3_array(touches).map(function(touch) {
|
3535
3644
|
var point = d3_svg_mousePoint(container, touch);
|
3536
3645
|
point.identifier = touch.identifier;
|
@@ -3820,6 +3929,341 @@ function d3_svg_axisSubdivide(scale, ticks, m) {
|
|
3820
3929
|
}
|
3821
3930
|
return subticks;
|
3822
3931
|
}
|
3932
|
+
d3.svg.brush = function() {
|
3933
|
+
var event = d3.dispatch("brushstart", "brush", "brushend"),
|
3934
|
+
x, // x-scale, optional
|
3935
|
+
y, // y-scale, optional
|
3936
|
+
extent = [[0, 0], [0, 0]]; // [x0, y0], [x1, y1]
|
3937
|
+
|
3938
|
+
function brush(g) {
|
3939
|
+
var resizes = x && y ? ["n", "e", "s", "w", "nw", "ne", "se", "sw"]
|
3940
|
+
: x ? ["e", "w"]
|
3941
|
+
: y ? ["n", "s"]
|
3942
|
+
: [];
|
3943
|
+
|
3944
|
+
g.each(function() {
|
3945
|
+
var g = d3.select(this).on("mousedown.brush", down),
|
3946
|
+
bg = g.selectAll(".background").data([,]),
|
3947
|
+
fg = g.selectAll(".extent").data([,]),
|
3948
|
+
tz = g.selectAll(".resize").data(resizes, String),
|
3949
|
+
e;
|
3950
|
+
|
3951
|
+
// An invisible, mouseable area for starting a new brush.
|
3952
|
+
bg.enter().append("svg:rect")
|
3953
|
+
.attr("class", "background")
|
3954
|
+
.style("visibility", "hidden")
|
3955
|
+
.style("pointer-events", "all")
|
3956
|
+
.style("cursor", "crosshair");
|
3957
|
+
|
3958
|
+
// The visible brush extent; style this as you like!
|
3959
|
+
fg.enter().append("svg:rect")
|
3960
|
+
.attr("class", "extent")
|
3961
|
+
.style("cursor", "move");
|
3962
|
+
|
3963
|
+
// More invisible rects for resizing the extent.
|
3964
|
+
tz.enter().append("svg:rect")
|
3965
|
+
.attr("class", function(d) { return "resize " + d; })
|
3966
|
+
.attr("width", 6)
|
3967
|
+
.attr("height", 6)
|
3968
|
+
.style("visibility", "hidden")
|
3969
|
+
.style("pointer-events", brush.empty() ? "none" : "all")
|
3970
|
+
.style("cursor", function(d) { return d3_svg_brushCursor[d]; });
|
3971
|
+
|
3972
|
+
// Remove any superfluous resizers.
|
3973
|
+
tz.exit().remove();
|
3974
|
+
|
3975
|
+
// Initialize the background to fill the defined range.
|
3976
|
+
// If the range isn't defined, you can post-process.
|
3977
|
+
if (x) {
|
3978
|
+
e = d3_scaleExtent(x.range());
|
3979
|
+
bg.attr("x", e[0]).attr("width", e[1] - e[0]);
|
3980
|
+
d3_svg_brushRedrawX(g, extent);
|
3981
|
+
}
|
3982
|
+
if (y) {
|
3983
|
+
e = d3_scaleExtent(y.range());
|
3984
|
+
bg.attr("y", e[0]).attr("height", e[1] - e[0]);
|
3985
|
+
d3_svg_brushRedrawY(g, extent);
|
3986
|
+
}
|
3987
|
+
});
|
3988
|
+
}
|
3989
|
+
|
3990
|
+
function down() {
|
3991
|
+
var target = d3.select(d3.event.target);
|
3992
|
+
|
3993
|
+
// Store some global state for the duration of the brush gesture.
|
3994
|
+
d3_svg_brush = brush;
|
3995
|
+
d3_svg_brushTarget = this;
|
3996
|
+
d3_svg_brushExtent = extent;
|
3997
|
+
d3_svg_brushOffset = d3.svg.mouse(d3_svg_brushTarget);
|
3998
|
+
|
3999
|
+
// If the extent was clicked on, drag rather than brush;
|
4000
|
+
// store the offset between the mouse and extent origin instead.
|
4001
|
+
if (d3_svg_brushDrag = target.classed("extent")) {
|
4002
|
+
d3_svg_brushOffset[0] = extent[0][0] - d3_svg_brushOffset[0];
|
4003
|
+
d3_svg_brushOffset[1] = extent[0][1] - d3_svg_brushOffset[1];
|
4004
|
+
}
|
4005
|
+
|
4006
|
+
// If a resizer was clicked on, record which side is to be resized.
|
4007
|
+
// Also, set the offset to the opposite side.
|
4008
|
+
else if (target.classed("resize")) {
|
4009
|
+
d3_svg_brushResize = d3.event.target.__data__;
|
4010
|
+
d3_svg_brushOffset[0] = extent[+/w$/.test(d3_svg_brushResize)][0];
|
4011
|
+
d3_svg_brushOffset[1] = extent[+/^n/.test(d3_svg_brushResize)][1];
|
4012
|
+
}
|
4013
|
+
|
4014
|
+
// If the ALT key is down when starting a brush, the center is at the mouse.
|
4015
|
+
else if (d3.event.altKey) {
|
4016
|
+
d3_svg_brushCenter = d3_svg_brushOffset.slice();
|
4017
|
+
}
|
4018
|
+
|
4019
|
+
// Restrict which dimensions are resized.
|
4020
|
+
d3_svg_brushX = !/^(n|s)$/.test(d3_svg_brushResize) && x;
|
4021
|
+
d3_svg_brushY = !/^(e|w)$/.test(d3_svg_brushResize) && y;
|
4022
|
+
|
4023
|
+
// Notify listeners.
|
4024
|
+
d3_svg_brushDispatch = dispatcher(this, arguments);
|
4025
|
+
d3_svg_brushDispatch("brushstart");
|
4026
|
+
d3_svg_brushMove();
|
4027
|
+
d3_eventCancel();
|
4028
|
+
}
|
4029
|
+
|
4030
|
+
function dispatcher(that, argumentz) {
|
4031
|
+
return function(type) {
|
4032
|
+
var e = d3.event;
|
4033
|
+
try {
|
4034
|
+
d3.event = {type: type, target: brush};
|
4035
|
+
event[type].apply(that, argumentz);
|
4036
|
+
} finally {
|
4037
|
+
d3.event = e;
|
4038
|
+
}
|
4039
|
+
};
|
4040
|
+
}
|
4041
|
+
|
4042
|
+
brush.x = function(z) {
|
4043
|
+
if (!arguments.length) return x;
|
4044
|
+
x = z;
|
4045
|
+
return brush;
|
4046
|
+
};
|
4047
|
+
|
4048
|
+
brush.y = function(z) {
|
4049
|
+
if (!arguments.length) return y;
|
4050
|
+
y = z;
|
4051
|
+
return brush;
|
4052
|
+
};
|
4053
|
+
|
4054
|
+
brush.extent = function(z) {
|
4055
|
+
var x0, x1, y0, y1, t;
|
4056
|
+
|
4057
|
+
// Invert the pixel extent to data-space.
|
4058
|
+
if (!arguments.length) {
|
4059
|
+
if (x) {
|
4060
|
+
x0 = x.invert(extent[0][0]), x1 = x.invert(extent[1][0]);
|
4061
|
+
if (x1 < x0) t = x0, x0 = x1, x1 = t;
|
4062
|
+
}
|
4063
|
+
if (y) {
|
4064
|
+
y0 = y.invert(extent[0][1]), y1 = y.invert(extent[1][1]);
|
4065
|
+
if (y1 < y0) t = y0, y0 = y1, y1 = t;
|
4066
|
+
}
|
4067
|
+
return x && y ? [[x0, y0], [x1, y1]] : x ? [x0, x1] : y && [y0, y1];
|
4068
|
+
}
|
4069
|
+
|
4070
|
+
// Scale the data-space extent to pixels.
|
4071
|
+
if (x) {
|
4072
|
+
x0 = z[0], x1 = z[1];
|
4073
|
+
if (y) x0 = x0[0], x1 = x1[0];
|
4074
|
+
x0 = x(x0), x1 = x(x1);
|
4075
|
+
if (x1 < x0) t = x0, x0 = x1, x1 = t;
|
4076
|
+
extent[0][0] = x0, extent[1][0] = x1;
|
4077
|
+
}
|
4078
|
+
if (y) {
|
4079
|
+
y0 = z[0], y1 = z[1];
|
4080
|
+
if (x) y0 = y0[1], y1 = y1[1];
|
4081
|
+
y0 = y(y0), y1 = y(y1);
|
4082
|
+
if (y1 < y0) t = y0, y0 = y1, y1 = t;
|
4083
|
+
extent[0][1] = y0, extent[1][1] = y1;
|
4084
|
+
}
|
4085
|
+
|
4086
|
+
return brush;
|
4087
|
+
};
|
4088
|
+
|
4089
|
+
brush.clear = function() {
|
4090
|
+
extent[0][0] =
|
4091
|
+
extent[0][1] =
|
4092
|
+
extent[1][0] =
|
4093
|
+
extent[1][1] = 0;
|
4094
|
+
return brush;
|
4095
|
+
};
|
4096
|
+
|
4097
|
+
brush.empty = function() {
|
4098
|
+
return (x && extent[0][0] === extent[1][0])
|
4099
|
+
|| (y && extent[0][1] === extent[1][1]);
|
4100
|
+
};
|
4101
|
+
|
4102
|
+
brush.on = function(type, listener) {
|
4103
|
+
event.on(type, listener);
|
4104
|
+
return brush;
|
4105
|
+
};
|
4106
|
+
|
4107
|
+
d3.select(window)
|
4108
|
+
.on("mousemove.brush", d3_svg_brushMove)
|
4109
|
+
.on("mouseup.brush", d3_svg_brushUp)
|
4110
|
+
.on("keydown.brush", d3_svg_brushKeydown)
|
4111
|
+
.on("keyup.brush", d3_svg_brushKeyup);
|
4112
|
+
|
4113
|
+
return brush;
|
4114
|
+
};
|
4115
|
+
|
4116
|
+
var d3_svg_brush,
|
4117
|
+
d3_svg_brushDispatch,
|
4118
|
+
d3_svg_brushTarget,
|
4119
|
+
d3_svg_brushX,
|
4120
|
+
d3_svg_brushY,
|
4121
|
+
d3_svg_brushExtent,
|
4122
|
+
d3_svg_brushDrag,
|
4123
|
+
d3_svg_brushResize,
|
4124
|
+
d3_svg_brushCenter,
|
4125
|
+
d3_svg_brushOffset;
|
4126
|
+
|
4127
|
+
function d3_svg_brushRedrawX(g, extent) {
|
4128
|
+
g.select(".extent").attr("x", extent[0][0]);
|
4129
|
+
g.selectAll(".n,.s,.w,.nw,.sw").attr("x", extent[0][0] - 2);
|
4130
|
+
g.selectAll(".e,.ne,.se").attr("x", extent[1][0] - 3);
|
4131
|
+
g.selectAll(".extent,.n,.s").attr("width", extent[1][0] - extent[0][0]);
|
4132
|
+
}
|
4133
|
+
|
4134
|
+
function d3_svg_brushRedrawY(g, extent) {
|
4135
|
+
g.select(".extent").attr("y", extent[0][1]);
|
4136
|
+
g.selectAll(".n,.e,.w,.nw,.ne").attr("y", extent[0][1] - 3);
|
4137
|
+
g.selectAll(".s,.se,.sw").attr("y", extent[1][1] - 4);
|
4138
|
+
g.selectAll(".extent,.e,.w").attr("height", extent[1][1] - extent[0][1]);
|
4139
|
+
}
|
4140
|
+
|
4141
|
+
function d3_svg_brushKeydown() {
|
4142
|
+
if (d3.event.keyCode == 32 && d3_svg_brushTarget && !d3_svg_brushDrag) {
|
4143
|
+
d3_svg_brushCenter = null;
|
4144
|
+
d3_svg_brushOffset[0] -= d3_svg_brushExtent[1][0];
|
4145
|
+
d3_svg_brushOffset[1] -= d3_svg_brushExtent[1][1];
|
4146
|
+
d3_svg_brushDrag = 2;
|
4147
|
+
d3_eventCancel();
|
4148
|
+
}
|
4149
|
+
}
|
4150
|
+
|
4151
|
+
function d3_svg_brushKeyup() {
|
4152
|
+
if (d3.event.keyCode == 32 && d3_svg_brushDrag == 2) {
|
4153
|
+
d3_svg_brushOffset[0] += d3_svg_brushExtent[1][0];
|
4154
|
+
d3_svg_brushOffset[1] += d3_svg_brushExtent[1][1];
|
4155
|
+
d3_svg_brushDrag = 0;
|
4156
|
+
d3_eventCancel();
|
4157
|
+
}
|
4158
|
+
}
|
4159
|
+
|
4160
|
+
function d3_svg_brushMove() {
|
4161
|
+
if (d3_svg_brushOffset) {
|
4162
|
+
var mouse = d3.svg.mouse(d3_svg_brushTarget),
|
4163
|
+
g = d3.select(d3_svg_brushTarget);
|
4164
|
+
|
4165
|
+
if (!d3_svg_brushDrag) {
|
4166
|
+
|
4167
|
+
// If needed, determine the center from the current extent.
|
4168
|
+
if (d3.event.altKey) {
|
4169
|
+
if (!d3_svg_brushCenter) {
|
4170
|
+
d3_svg_brushCenter = [
|
4171
|
+
(d3_svg_brushExtent[0][0] + d3_svg_brushExtent[1][0]) / 2,
|
4172
|
+
(d3_svg_brushExtent[0][1] + d3_svg_brushExtent[1][1]) / 2
|
4173
|
+
];
|
4174
|
+
}
|
4175
|
+
|
4176
|
+
// Update the offset, for when the ALT key is released.
|
4177
|
+
d3_svg_brushOffset[0] = d3_svg_brushExtent[+(mouse[0] < d3_svg_brushCenter[0])][0];
|
4178
|
+
d3_svg_brushOffset[1] = d3_svg_brushExtent[+(mouse[1] < d3_svg_brushCenter[1])][1];
|
4179
|
+
}
|
4180
|
+
|
4181
|
+
// When the ALT key is released, we clear the center.
|
4182
|
+
else d3_svg_brushCenter = null;
|
4183
|
+
}
|
4184
|
+
|
4185
|
+
// Update the brush extent for each dimension.
|
4186
|
+
if (d3_svg_brushX) {
|
4187
|
+
d3_svg_brushMove1(mouse, d3_svg_brushX, 0);
|
4188
|
+
d3_svg_brushRedrawX(g, d3_svg_brushExtent);
|
4189
|
+
}
|
4190
|
+
if (d3_svg_brushY) {
|
4191
|
+
d3_svg_brushMove1(mouse, d3_svg_brushY, 1);
|
4192
|
+
d3_svg_brushRedrawY(g, d3_svg_brushExtent);
|
4193
|
+
}
|
4194
|
+
|
4195
|
+
// Notify listeners.
|
4196
|
+
d3_svg_brushDispatch("brush");
|
4197
|
+
}
|
4198
|
+
}
|
4199
|
+
|
4200
|
+
function d3_svg_brushMove1(mouse, scale, i) {
|
4201
|
+
var range = d3_scaleExtent(scale.range()),
|
4202
|
+
offset = d3_svg_brushOffset[i],
|
4203
|
+
size = d3_svg_brushExtent[1][i] - d3_svg_brushExtent[0][i],
|
4204
|
+
min,
|
4205
|
+
max;
|
4206
|
+
|
4207
|
+
// When dragging, reduce the range by the extent size and offset.
|
4208
|
+
if (d3_svg_brushDrag) {
|
4209
|
+
range[0] -= offset;
|
4210
|
+
range[1] -= size + offset;
|
4211
|
+
}
|
4212
|
+
|
4213
|
+
// Clamp the mouse so that the extent fits within the range extent.
|
4214
|
+
min = Math.max(range[0], Math.min(range[1], mouse[i]));
|
4215
|
+
|
4216
|
+
// Compute the new extent bounds.
|
4217
|
+
if (d3_svg_brushDrag) {
|
4218
|
+
max = (min += offset) + size;
|
4219
|
+
} else {
|
4220
|
+
|
4221
|
+
// If the ALT key is pressed, then preserve the center of the extent.
|
4222
|
+
if (d3_svg_brushCenter) offset = Math.max(range[0], Math.min(range[1], 2 * d3_svg_brushCenter[i] - min));
|
4223
|
+
|
4224
|
+
// Compute the min and max of the offset and mouse.
|
4225
|
+
if (offset < min) {
|
4226
|
+
max = min;
|
4227
|
+
min = offset;
|
4228
|
+
} else {
|
4229
|
+
max = offset;
|
4230
|
+
}
|
4231
|
+
}
|
4232
|
+
|
4233
|
+
// Update the stored bounds.
|
4234
|
+
d3_svg_brushExtent[0][i] = min;
|
4235
|
+
d3_svg_brushExtent[1][i] = max;
|
4236
|
+
}
|
4237
|
+
|
4238
|
+
function d3_svg_brushUp() {
|
4239
|
+
if (d3_svg_brushOffset) {
|
4240
|
+
d3_svg_brushMove();
|
4241
|
+
d3.select(d3_svg_brushTarget).selectAll(".resize").style("pointer-events", d3_svg_brush.empty() ? "none" : "all");
|
4242
|
+
d3_svg_brushDispatch("brushend");
|
4243
|
+
d3_svg_brush =
|
4244
|
+
d3_svg_brushDispatch =
|
4245
|
+
d3_svg_brushTarget =
|
4246
|
+
d3_svg_brushX =
|
4247
|
+
d3_svg_brushY =
|
4248
|
+
d3_svg_brushExtent =
|
4249
|
+
d3_svg_brushDrag =
|
4250
|
+
d3_svg_brushResize =
|
4251
|
+
d3_svg_brushCenter =
|
4252
|
+
d3_svg_brushOffset = null;
|
4253
|
+
d3_eventCancel();
|
4254
|
+
}
|
4255
|
+
}
|
4256
|
+
|
4257
|
+
var d3_svg_brushCursor = {
|
4258
|
+
n: "ns-resize",
|
4259
|
+
e: "ew-resize",
|
4260
|
+
s: "ns-resize",
|
4261
|
+
w: "ew-resize",
|
4262
|
+
nw: "nwse-resize",
|
4263
|
+
ne: "nesw-resize",
|
4264
|
+
se: "nwse-resize",
|
4265
|
+
sw: "nesw-resize"
|
4266
|
+
};
|
3823
4267
|
d3.behavior = {};
|
3824
4268
|
d3.behavior.drag = function() {
|
3825
4269
|
var event = d3.dispatch("drag", "dragstart", "dragend");
|
@@ -3852,7 +4296,7 @@ d3.behavior.drag = function() {
|
|
3852
4296
|
}
|
3853
4297
|
|
3854
4298
|
drag.on = function(type, listener) {
|
3855
|
-
event
|
4299
|
+
event.on(type, listener);
|
3856
4300
|
return drag;
|
3857
4301
|
};
|
3858
4302
|
|
@@ -3880,7 +4324,7 @@ function d3_behavior_dragDispatch(type) {
|
|
3880
4324
|
|
3881
4325
|
try {
|
3882
4326
|
d3.event = {dx: dx, dy: dy};
|
3883
|
-
d3_behavior_dragEvent[type].
|
4327
|
+
d3_behavior_dragEvent[type].apply(d3_behavior_dragTarget, d3_behavior_dragArguments);
|
3884
4328
|
} finally {
|
3885
4329
|
d3.event = o;
|
3886
4330
|
}
|
@@ -3888,10 +4332,10 @@ function d3_behavior_dragDispatch(type) {
|
|
3888
4332
|
o.preventDefault();
|
3889
4333
|
}
|
3890
4334
|
|
3891
|
-
function d3_behavior_dragPoint(container) {
|
3892
|
-
|
3893
|
-
|
3894
|
-
|
4335
|
+
function d3_behavior_dragPoint(container, type) {
|
4336
|
+
// TODO Track touch points by identifier.
|
4337
|
+
var t = d3.event.changedTouches;
|
4338
|
+
return t ? d3.svg.touches(container, t)[0] : d3.svg.mouse(container);
|
3895
4339
|
}
|
3896
4340
|
|
3897
4341
|
function d3_behavior_dragMove() {
|
@@ -3902,7 +4346,7 @@ function d3_behavior_dragMove() {
|
|
3902
4346
|
if (!parent) return d3_behavior_dragUp();
|
3903
4347
|
|
3904
4348
|
d3_behavior_dragDispatch("drag");
|
3905
|
-
|
4349
|
+
d3_eventCancel();
|
3906
4350
|
}
|
3907
4351
|
|
3908
4352
|
function d3_behavior_dragUp() {
|
@@ -3914,27 +4358,22 @@ function d3_behavior_dragUp() {
|
|
3914
4358
|
// Also prevent the subsequent click from propagating (e.g., for anchors).
|
3915
4359
|
if (d3_behavior_dragMoved && d3_behavior_dragEventTarget === d3.event.target) {
|
3916
4360
|
d3_behavior_dragStopClick = true;
|
3917
|
-
|
4361
|
+
d3_eventCancel();
|
3918
4362
|
}
|
3919
4363
|
}
|
3920
4364
|
|
3921
4365
|
function d3_behavior_dragClick() {
|
3922
4366
|
if (d3_behavior_dragStopClick && d3_behavior_dragEventTarget === d3.event.target) {
|
3923
|
-
|
4367
|
+
d3_eventCancel();
|
3924
4368
|
d3_behavior_dragStopClick = false;
|
3925
4369
|
d3_behavior_dragEventTarget = null;
|
3926
4370
|
}
|
3927
4371
|
}
|
3928
|
-
|
3929
|
-
function d3_behavior_dragCancel() {
|
3930
|
-
d3.event.stopPropagation();
|
3931
|
-
d3.event.preventDefault();
|
3932
|
-
}
|
3933
4372
|
// TODO unbind zoom behavior?
|
3934
|
-
// TODO unbind listener?
|
3935
4373
|
d3.behavior.zoom = function() {
|
3936
4374
|
var xyz = [0, 0, 0],
|
3937
|
-
event = d3.dispatch("zoom")
|
4375
|
+
event = d3.dispatch("zoom"),
|
4376
|
+
extent = d3_behavior_zoomInfiniteExtent;
|
3938
4377
|
|
3939
4378
|
function zoom() {
|
3940
4379
|
this
|
@@ -3955,7 +4394,8 @@ d3.behavior.zoom = function() {
|
|
3955
4394
|
// snapshot the local context for subsequent dispatch
|
3956
4395
|
function start() {
|
3957
4396
|
d3_behavior_zoomXyz = xyz;
|
3958
|
-
|
4397
|
+
d3_behavior_zoomExtent = extent;
|
4398
|
+
d3_behavior_zoomDispatch = event.zoom;
|
3959
4399
|
d3_behavior_zoomEventTarget = d3.event.target;
|
3960
4400
|
d3_behavior_zoomTarget = this;
|
3961
4401
|
d3_behavior_zoomArguments = arguments;
|
@@ -3994,8 +4434,14 @@ d3.behavior.zoom = function() {
|
|
3994
4434
|
d3_behavior_zoomLast = now;
|
3995
4435
|
}
|
3996
4436
|
|
4437
|
+
zoom.extent = function(x) {
|
4438
|
+
if (!arguments.length) return extent;
|
4439
|
+
extent = x == null ? d3_behavior_zoomInfiniteExtent : x;
|
4440
|
+
return zoom;
|
4441
|
+
};
|
4442
|
+
|
3997
4443
|
zoom.on = function(type, listener) {
|
3998
|
-
event
|
4444
|
+
event.on(type, listener);
|
3999
4445
|
return zoom;
|
4000
4446
|
};
|
4001
4447
|
|
@@ -4008,6 +4454,7 @@ var d3_behavior_zoomDiv,
|
|
4008
4454
|
d3_behavior_zoomLocations = {}, // identifier -> location
|
4009
4455
|
d3_behavior_zoomLast = 0,
|
4010
4456
|
d3_behavior_zoomXyz,
|
4457
|
+
d3_behavior_zoomExtent,
|
4011
4458
|
d3_behavior_zoomDispatch,
|
4012
4459
|
d3_behavior_zoomEventTarget,
|
4013
4460
|
d3_behavior_zoomTarget,
|
@@ -4118,25 +4565,27 @@ function d3_behavior_zoomClick() {
|
|
4118
4565
|
}
|
4119
4566
|
|
4120
4567
|
function d3_behavior_zoomTo(z, x0, x1) {
|
4121
|
-
|
4122
|
-
|
4123
|
-
|
4124
|
-
|
4125
|
-
|
4568
|
+
z = d3_behavior_zoomExtentClamp(z, 2);
|
4569
|
+
var j = Math.pow(2, d3_behavior_zoomXyz[2]),
|
4570
|
+
k = Math.pow(2, z),
|
4571
|
+
K = Math.pow(2, (d3_behavior_zoomXyz[2] = z) - x1[2]),
|
4572
|
+
x_ = d3_behavior_zoomXyz[0],
|
4573
|
+
y_ = d3_behavior_zoomXyz[1],
|
4574
|
+
x = d3_behavior_zoomXyz[0] = d3_behavior_zoomExtentClamp((x0[0] - x1[0] * K), 0, k),
|
4575
|
+
y = d3_behavior_zoomXyz[1] = d3_behavior_zoomExtentClamp((x0[1] - x1[1] * K), 1, k),
|
4576
|
+
o = d3.event; // Events can be reentrant (e.g., focus).
|
4126
4577
|
|
4127
4578
|
d3.event = {
|
4128
4579
|
scale: k,
|
4129
4580
|
translate: [x, y],
|
4130
4581
|
transform: function(sx, sy) {
|
4131
|
-
if (sx) transform(sx, x);
|
4132
|
-
if (sy) transform(sy, y);
|
4582
|
+
if (sx) transform(sx, x_, x);
|
4583
|
+
if (sy) transform(sy, y_, y);
|
4133
4584
|
}
|
4134
4585
|
};
|
4135
4586
|
|
4136
|
-
function transform(scale,
|
4137
|
-
|
4138
|
-
range = scale.range().map(function(v) { return (v - o) / k; });
|
4139
|
-
scale.domain(domain).domain(range.map(scale.invert));
|
4587
|
+
function transform(scale, a, b) {
|
4588
|
+
scale.domain(scale.range().map(function(v) { return scale.invert(((v - b) * j) / k + a); }));
|
4140
4589
|
}
|
4141
4590
|
|
4142
4591
|
try {
|
@@ -4147,4 +4596,20 @@ function d3_behavior_zoomTo(z, x0, x1) {
|
|
4147
4596
|
|
4148
4597
|
o.preventDefault();
|
4149
4598
|
}
|
4599
|
+
|
4600
|
+
var d3_behavior_zoomInfiniteExtent = [
|
4601
|
+
[-Infinity, Infinity],
|
4602
|
+
[-Infinity, Infinity],
|
4603
|
+
[-Infinity, Infinity]
|
4604
|
+
];
|
4605
|
+
|
4606
|
+
function d3_behavior_zoomExtentClamp(x, i, k) {
|
4607
|
+
var range = d3_behavior_zoomExtent[i],
|
4608
|
+
r0 = range[0],
|
4609
|
+
r1 = range[1];
|
4610
|
+
return arguments.length === 3
|
4611
|
+
? Math.max(r1 * (r1 === Infinity ? -Infinity : 1 / k - 1),
|
4612
|
+
Math.min(r0 === -Infinity ? Infinity : r0, x / k)) * k
|
4613
|
+
: Math.max(r0, Math.min(r1, x));
|
4614
|
+
}
|
4150
4615
|
})();
|
@@ -113,16 +113,19 @@ d3.layout.chord = function() {
|
|
113
113
|
k = (2 * Math.PI - padding * n) / k;
|
114
114
|
|
115
115
|
// Compute the start and end angle for each group and subgroup.
|
116
|
+
// Note: Opera has a bug reordering object literal properties!
|
116
117
|
x = 0, i = -1; while (++i < n) {
|
117
118
|
x0 = x, j = -1; while (++j < n) {
|
118
119
|
var di = groupIndex[i],
|
119
120
|
dj = subgroupIndex[di][j],
|
120
|
-
v = matrix[di][dj]
|
121
|
+
v = matrix[di][dj],
|
122
|
+
a0 = x,
|
123
|
+
a1 = x += v * k;
|
121
124
|
subgroups[di + "-" + dj] = {
|
122
125
|
index: di,
|
123
126
|
subindex: dj,
|
124
|
-
startAngle:
|
125
|
-
endAngle:
|
127
|
+
startAngle: a0,
|
128
|
+
endAngle: a1,
|
126
129
|
value: v
|
127
130
|
};
|
128
131
|
}
|
@@ -315,14 +318,14 @@ d3.layout.force = function() {
|
|
315
318
|
}
|
316
319
|
}
|
317
320
|
|
318
|
-
event.tick
|
321
|
+
event.tick({type: "tick", alpha: alpha});
|
319
322
|
|
320
323
|
// simulated annealing, basically
|
321
324
|
return (alpha *= .99) < .005;
|
322
325
|
}
|
323
326
|
|
324
327
|
force.on = function(type, listener) {
|
325
|
-
event
|
328
|
+
event.on(type, listener);
|
326
329
|
return force;
|
327
330
|
};
|
328
331
|
|
@@ -602,33 +605,31 @@ d3.layout.partition = function() {
|
|
602
605
|
};
|
603
606
|
d3.layout.pie = function() {
|
604
607
|
var value = Number,
|
605
|
-
sort =
|
608
|
+
sort = d3_layout_pieSortByValue,
|
606
609
|
startAngle = 0,
|
607
610
|
endAngle = 2 * Math.PI;
|
608
611
|
|
609
612
|
function pie(data, i) {
|
610
613
|
|
614
|
+
// Compute the numeric values for each data element.
|
615
|
+
var values = data.map(function(d, i) { return +value.call(pie, d, i); });
|
616
|
+
|
611
617
|
// Compute the start angle.
|
612
618
|
var a = +(typeof startAngle === "function"
|
613
619
|
? startAngle.apply(this, arguments)
|
614
620
|
: startAngle);
|
615
621
|
|
616
|
-
// Compute the angular
|
617
|
-
var k = (typeof endAngle === "function"
|
622
|
+
// Compute the angular scale factor: from value to radians.
|
623
|
+
var k = ((typeof endAngle === "function"
|
618
624
|
? endAngle.apply(this, arguments)
|
619
|
-
: endAngle) - startAngle
|
625
|
+
: endAngle) - startAngle)
|
626
|
+
/ d3.sum(values);
|
620
627
|
|
621
628
|
// Optionally sort the data.
|
622
629
|
var index = d3.range(data.length);
|
623
|
-
if (sort != null) index.sort(
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
// Compute the numeric values for each data element.
|
628
|
-
var values = data.map(value);
|
629
|
-
|
630
|
-
// Convert k into a scale factor from value to angle, using the sum.
|
631
|
-
k /= values.reduce(function(p, d) { return p + d; }, 0);
|
630
|
+
if (sort != null) index.sort(sort === d3_layout_pieSortByValue
|
631
|
+
? function(i, j) { return values[j] - values[i]; }
|
632
|
+
: function(i, j) { return sort(data[i], data[j]); });
|
632
633
|
|
633
634
|
// Compute the arcs!
|
634
635
|
var arcs = index.map(function(i) {
|
@@ -695,6 +696,8 @@ d3.layout.pie = function() {
|
|
695
696
|
|
696
697
|
return pie;
|
697
698
|
};
|
699
|
+
|
700
|
+
var d3_layout_pieSortByValue = {};
|
698
701
|
// data is two-dimensional array of x,y; we populate y0
|
699
702
|
d3.layout.stack = function() {
|
700
703
|
var values = Object,
|
File without changes
|
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: d3_rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-11-06 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: railties
|
16
|
-
requirement: &
|
16
|
+
requirement: &70232077023480 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 3.1.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70232077023480
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: bundler
|
27
|
-
requirement: &
|
27
|
+
requirement: &70232077022480 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 1.0.0
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70232077022480
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rails
|
38
|
-
requirement: &
|
38
|
+
requirement: &70232077021620 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: '3.1'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70232077021620
|
47
47
|
description: Gem installation of javascript framework for data visualization, D3
|
48
48
|
email:
|
49
49
|
- han@logicallsat.com
|
@@ -63,7 +63,6 @@ files:
|
|
63
63
|
- vendor/assets/javascripts/.DS_Store
|
64
64
|
- vendor/assets/javascripts/LICENSE
|
65
65
|
- vendor/assets/javascripts/colorbrewer.js
|
66
|
-
- vendor/assets/javascripts/d3-csv.js
|
67
66
|
- vendor/assets/javascripts/d3.chart.js
|
68
67
|
- vendor/assets/javascripts/d3.csv.js
|
69
68
|
- vendor/assets/javascripts/d3.geo.js
|
@@ -72,6 +71,7 @@ files:
|
|
72
71
|
- vendor/assets/javascripts/d3.layout.js
|
73
72
|
- vendor/assets/javascripts/d3.min.js
|
74
73
|
- vendor/assets/javascripts/d3.time.js
|
74
|
+
- vendor/assets/javascripts/d3_csv.js
|
75
75
|
- vendor/assets/javascripts/d3_rails.js
|
76
76
|
- vendor/assets/javascripts/science.js
|
77
77
|
- vendor/assets/javascripts/science.lin.js
|