d3_rails 0.0.10 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|