Commit b0686e2a authored by Mike Bostock's avatar Mike Bostock

Merge branch '2.10.0'

parents 108d65da ee03eb6c
......@@ -4,6 +4,7 @@ NODE_PATH ?= ./node_modules
JS_COMPILER = $(NODE_PATH)/uglify-js/bin/uglifyjs
JS_BEAUTIFIER = $(NODE_PATH)/uglify-js/bin/uglifyjs -b -i 2 -nm -ns
JS_TESTER = $(NODE_PATH)/vows/bin/vows
LOCALE ?= en_US
all: \
d3.v2.js \
......@@ -19,7 +20,7 @@ all: \
d3.svg.js \
d3.behavior.js \
d3.layout.js \
d3.csv.js \
d3.dsv.js \
d3.geo.js \
d3.geom.js \
d3.time.js \
......@@ -80,6 +81,9 @@ d3.core.js: \
src/core/uninterpolate.js \
src/core/rgb.js \
src/core/hsl.js \
src/core/hcl.js \
src/core/lab.js \
src/core/xyz.js \
src/core/selection.js \
src/core/selection-select.js \
src/core/selection-selectAll.js \
......@@ -118,6 +122,7 @@ d3.core.js: \
src/core/transition-duration.js \
src/core/transition-each.js \
src/core/transition-transition.js \
src/core/tween.js \
src/core/timer.js \
src/core/mouse.js \
src/core/touches.js \
......@@ -136,6 +141,7 @@ d3.scale.js: \
src/scale/category.js \
src/scale/quantile.js \
src/scale/quantize.js \
src/scale/threshold.js \
src/scale/identity.js
d3.svg.js: \
......@@ -188,13 +194,14 @@ d3.geo.js: \
src/geo/greatArc.js \
src/geo/greatCircle.js
d3.csv.js: \
src/csv/csv.js \
src/csv/parse.js \
src/csv/format.js
d3.dsv.js: \
src/dsv/dsv.js \
src/dsv/csv.js \
src/dsv/tsv.js
d3.time.js: \
src/time/time.js \
src/time/format-$(LOCALE).js \
src/time/format.js \
src/time/format-utc.js \
src/time/format-iso.js \
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
circle {
stroke: #fff;
stroke-width: 1.5px;
}
text {
font: 10px sans-serif;
}
......@@ -4,7 +4,8 @@ var r = 960,
var bubble = d3.layout.pack()
.sort(null)
.size([r, r]);
.size([r, r])
.padding(1.5);
var vis = d3.select("#chart").append("svg")
.attr("width", r)
......
Hello World
42 """fish"""
......@@ -2,13 +2,15 @@
<body>
<script src="../../d3.v2.js"></script>
<script>
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500);
var g = svg.append("g")
.attr("transform", "translate(100,100)")
.append("g");
.append("g")
.attr("transform", "matrix(1 0 0 1 0 0)rotate(0)");
var rect = g.append("rect")
.attr("x", -25)
......@@ -18,5 +20,6 @@ var rect = g.append("rect")
g.transition()
.duration(3000)
.attr("transform", "matrix(1 0 0 1 100 100)rotate(360)");
.attrTween("transform", d3.tween("matrix(1 0 0 1 100 100)rotate(360)", d3.interpolateString));
</script>
......@@ -2,13 +2,15 @@
<body>
<script src="../../d3.v2.js"></script>
<script>
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500);
var g = svg.append("g")
.attr("transform", "translate(100,100)")
.append("g");
.append("g")
.attr("transform", "translate(0,0)rotate(0)");
var rect = g.append("rect")
.attr("x", -25)
......@@ -18,5 +20,6 @@ var rect = g.append("rect")
g.transition()
.duration(3000)
.attr("transform", "translate(100,100)rotate(360)");
.attrTween("transform", d3.tween("translate(100,100)rotate(360)", d3.interpolateString));
</script>
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="../../d3.v2.js"></script>
<script>
var width = 960,
height = 500;
var cross = d3.svg.symbol()
.type("cross")
.size(10000);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + (width / 2) + "," + (height / 2) + ")");
svg.append("path")
.style("fill", "steelblue")
.attr("d", cross);
svg.append("path")
.style("fill", "darkgreen")
.attr("d", cross)
.attr("transform", "rotate(45 200,200)");
svg.append("path")
.style("fill", "white")
.style("fill-opacity", .2)
.style("stroke", "steelblue")
.style("stroke-width", "4px")
.attr("d", cross)
.transition()
.duration(1000)
.style("stroke", "darkgreen")
.attr("transform", "rotate(45 200,200)");
</script>
......@@ -51,14 +51,14 @@ var tests = [
{start: 225, end: 170, expected: [-135.00, -148.75, -162.50, -176.25, 170.00]},
{start: -170, end: -225, expected: [-170.00, 176.25, 162.50, 148.75, 135.00]},
{start: -225, end: -170, expected: [ 135.00, 148.75, 162.50, 176.25, -170.00]},
{start: -170, end: 170, expected: [-170.00, -85.00, 0.00, 85.00, 170.00]},
{start: -170, end: 170, expected: [-170.00, -175.00, 180.00, 175.00, 170.00]},
{start: -170, end: 0, expected: [-170.00, -127.50, -85.00, -42.50, 0.00]},
{start: 170, end: 0, expected: [ 170.00, 127.50, 85.00, 42.50, 0.00]},
{start: -180, end: 90, expected: [-180.00, -112.50, -45.00, 22.50, 90.00]},
{start: -180, end: 90, expected: [ 180.00, 157.50, 135.00, 112.50, 90.00]},
{start: 180, end: 90, expected: [ 180.00, 157.50, 135.00, 112.50, 90.00]},
{start: -180, end: -90, expected: [-180.00, -157.50, -135.00, -112.50, -90.00]},
{start: 180, end: -90, expected: [ 180.00, 112.50, 45.00, -22.50, -90.00]},
{start: 780, end: -90, expected: [ 60.00, -157.50, -15.00, 127.50, -90.00]}
{start: 180, end: -90, expected: [ 180.00, -157.50, -135.00, -112.50, -90.00]},
{start: 780, end: -90, expected: [ 60.00, 22.50, -15.00, -52.50, -90.00]}
];
var tr = d3.select("tbody").selectAll("tr")
......@@ -118,7 +118,11 @@ gb.append("circle")
function animateExpected(d) {
d3.select(this).transition()
.duration(2500)
.attrTween("transform", function(d) { return d3.interpolateString("rotate(" + d.start + ")", "rotate(" + d.end + ")"); })
.attrTween("transform", function(d) {
var a = d.start % 360, b = d.end % 360;
if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
return d3.interpolateString("rotate(" + a + ")", "rotate(" + b + ")");
})
.each("end", animateExpected);
}
......
{
"name": "d3",
"version": "2.9.7",
"version": "2.10.0",
"description": "A small, free JavaScript library for manipulating documents based on data.",
"keywords": [
"dom",
......
function d3_collapse(s) {
return s.replace(/^\s+|\s+$/g, "").replace(/\s+/g, " ");
return s.trim().replace(/\s+/g, " ");
}
d3 = {version: "2.9.7"}; // semver
d3 = {version: "2.10.0"}; // semver
......@@ -38,7 +38,7 @@ d3.format = function(specifier) {
if (integer && (value % 1)) return "";
// Convert negative to positive, and record the sign prefix.
var negative = (value < 0) && (value = -value) ? "\u2212" : sign;
var negative = (value < 0) && (value = -value) ? "-" : sign;
// Apply the scale, computing it from the value's exponent for si format.
if (scale < 0) {
......
d3.hcl = function(h, c, l) {
return arguments.length === 1
? (h instanceof d3_Hcl ? d3_hcl(h.h, h.c, h.l)
: (h instanceof d3_Lab ? d3_lab_hcl(h.l, h.a, h.b)
: d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b)))
: d3_hcl(+h, +c, +l);
};
function d3_hcl(h, c, l) {
return new d3_Hcl(h, c, l);
}
function d3_Hcl(h, c, l) {
this.h = h;
this.c = c;
this.l = l;
}
d3_Hcl.prototype.brighter = function(k) {
return d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)));
};
d3_Hcl.prototype.darker = function(k) {
return d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)));
};
d3_Hcl.prototype.rgb = function() {
return d3_hcl_lab(this.h, this.c, this.l).rgb();
};
d3_Hcl.prototype.toString = function() {
return this.rgb() + "";
};
function d3_hcl_lab(h, c, l) {
return d3_lab(l, Math.cos(h *= Math.PI / 180) * c, Math.sin(h) * c);
}
......@@ -93,8 +93,6 @@ d3.interpolateString = function(a, b) {
};
d3.interpolateTransform = function(a, b) {
if ((n = d3_interpolateTransformSimilar(a, b))) return n;
var s = [], // string constants and placeholders
q = [], // number interpolators
n,
......@@ -146,112 +144,6 @@ d3.interpolateTransform = function(a, b) {
};
};
var d3_interpolateTransformTypes = [
"",
"",
"translate",
"scale",
"rotate",
"skewX",
"skewY"
];
// If both the ‘from’ and ‘to’ transforms have the same number of transform
// functions and corresponding functions in each transform list are of the same
// type, each transform function is animated with its corresponding destination
// function in isolation using the rules described above. The individual values
// are then applied as a list to produce resulting transform value.
var d3_interpolateTransformSimilar = function(a, b) {
var ga = document.createElementNS(d3.ns.prefix.svg, "g"),
gb = document.createElementNS(d3.ns.prefix.svg, "g");
return (d3_interpolateTransformSimilar = function(a, b) {
ga.setAttribute("transform", a);
gb.setAttribute("transform", b);
a = ga.transform.baseVal;
b = gb.transform.baseVal;
var sa = [],
sb = [],
i = -1,
n = a.numberOfItems,
m = b.numberOfItems,
ta,
tb,
type;
// If one of the ‘from’ or ‘to’ transforms is "none", the ‘none’ is replaced
// by an equivalent identity function list for the corresponding transform
// function list. Otherwise, if the transform function lists do not have the
// same number of items, the transforms are each converted into the
// equivalent matrix value and animation proceeds using the rule for a
// single function above.
if (m !== n) {
if (!m) b = d3_interpolateTransformIdentity(a);
else if (!n) a = d3_interpolateTransformIdentity(b), n = m;
else return;
}
// If both the ‘from’ and ‘to’ transforms are "none", there is no
// interpolation necessary.
else if (!m) return;
while (++i < n) {
ta = a.getItem(i);
tb = b.getItem(i);
type = ta.type;
// If the transform functions are not the same type, or the type is
// unknown, fallback to the decomposed transform transition.
if (type !== tb.type || !type) return; // unknown
switch (type) {
// For matrix, the matrix is decomposed using the method described by
// unmatrix into separate translation, scale, rotation and skew
// matrices, then each decomposed matrix is interpolated numerically,
// and finally combined in order to produce a resulting 3x2 matrix.
case 1: { // matrix
sa.push(new d3_transform(ta.matrix));
sb.push(new d3_transform(tb.matrix));
continue;
}
// For translate, scale, rotate and skew functions the individual
// components of the function are interpolated numerically.
case 2: { // translate
ra = ta.matrix.e + "," + ta.matrix.f;
rb = tb.matrix.e + "," + tb.matrix.f;
break;
}
case 3: { // scale
ra = ta.matrix.a + "," + ta.matrix.d;
rb = tb.matrix.a + "," + tb.matrix.d;
break;
}
default: { // rotate, skew
ra = ta.angle;
rb = tb.angle;
}
}
sa.push(type = d3_interpolateTransformTypes[type], "(", ra, ")");
sb.push(type, "(", rb, ")");
}
return d3.interpolateString(sa.join(""), sb.join(""));
})(a, b);
};
function d3_interpolateTransformIdentity(a) {
return {
getItem: function(i) {
return {
type: a.getItem(i).type,
angle: 0,
matrix: d3_transformIdentity
};
}
};
}
d3.interpolateRgb = function(a, b) {
a = d3.rgb(a);
b = d3.rgb(b);
......@@ -281,7 +173,36 @@ d3.interpolateHsl = function(a, b) {
l1 = b.l - l0;
if (h1 > 180) h1 -= 360; else if (h1 < -180) h1 += 360; // shortest path
return function(t) {
return d3_hsl_rgb(h0 + h1 * t, s0 + s1 * t, l0 + l1 * t).toString();
return d3_hsl_rgb(h0 + h1 * t, s0 + s1 * t, l0 + l1 * t) + "";
};
};
d3.interpolateLab = function(a, b) {
a = d3.lab(a);
b = d3.lab(b);
var al = a.l,
aa = a.a,
ab = a.b,
bl = b.l - al,
ba = b.a - aa,
bb = b.b - ab;
return function(t) {
return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + "";
};
};
d3.interpolateHcl = function(a, b) {
a = d3.hcl(a);
b = d3.hcl(b);
var ah = a.h,
ac = a.c,
al = a.l,
bh = b.h - ah,
bc = b.c - ac,
bl = b.l - al;
if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; // shortest path
return function(t) {
return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + "";
};
};
......@@ -325,8 +246,8 @@ d3.interpolateObject = function(a, b) {
var d3_interpolate_number = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;
function d3_interpolateByName(n) {
return n == "transform"
function d3_interpolateByName(name) {
return name == "transform"
? d3.interpolateTransform
: d3.interpolate;
}
......
d3.lab = function(l, a, b) {
return arguments.length === 1
? (l instanceof d3_Lab ? d3_lab(l.l, l.a, l.b)
: (l instanceof d3_Hcl ? d3_hcl_lab(l.l, l.c, l.h)
: d3_rgb_lab((l = d3.rgb(l)).r, l.g, l.b)))
: d3_lab(+l, +a, +b);
};
function d3_lab(l, a, b) {
return new d3_Lab(l, a, b);
}
function d3_Lab(l, a, b) {
this.l = l;
this.a = a;
this.b = b;
}
// Corresponds roughly to RGB brighter/darker
var d3_lab_K = 18;
// D65 standard referent
var d3_lab_X = 0.950470,
d3_lab_Y = 1,
d3_lab_Z = 1.088830;
d3_Lab.prototype.brighter = function(k) {
return d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);
};
d3_Lab.prototype.darker = function(k) {
return d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);
};
d3_Lab.prototype.rgb = function() {
return d3_lab_rgb(this.l, this.a, this.b);
};
d3_Lab.prototype.toString = function() {
return this.rgb() + "";
};
function d3_lab_rgb(l, a, b) {
var y = (l + 16) / 116,
x = y + a / 500,
z = y - b / 200;
x = d3_lab_xyz(x) * d3_lab_X;
y = d3_lab_xyz(y) * d3_lab_Y;
z = d3_lab_xyz(z) * d3_lab_Z;
return d3_rgb(
d3_xyz_rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z),
d3_xyz_rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),
d3_xyz_rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z)
);
}
function d3_lab_hcl(l, a, b) {
return d3_hcl(Math.atan2(b, a) / Math.PI * 180, Math.sqrt(a * a + b * b), l);
}
function d3_lab_xyz(x) {
return x > 0.206893034 ? x * x * x : (x - 4 / 29) / 7.787037;
}
d3.random = {
normal: function(mean, deviation) {
if (arguments.length < 2) deviation = 1;
if (arguments.length < 1) mean = 0;
normal: function(µ, σ) {
var n = arguments.length;
if (n < 2) σ = 1;
if (n < 1) µ = 0;
return function() {
var x, y, r;
do {
......@@ -9,7 +10,22 @@ d3.random = {
y = Math.random() * 2 - 1;
r = x * x + y * y;
} while (!r || r > 1);
return mean + deviation * x * Math.sqrt(-2 * Math.log(r) / r);
return µ + σ * x * Math.sqrt(-2 * Math.log(r) / r);
};
},
logNormal: function(µ, σ) {
var n = arguments.length;
if (n < 2) σ = 1;
if (n < 1) µ = 0;
var random = d3.random.normal();
return function() {
return Math.exp(µ + σ * random());
};
},
irwinHall: function(m) {
return function() {
for (var s = 0, j = 0; j < m; j++) s += Math.random();
return s / m;
};
}
};
......@@ -124,6 +124,20 @@ function d3_rgb_hsl(r, g, b) {
return d3_hsl(h, s, l);
}
function d3_rgb_lab(r, g, b) {
r = d3_rgb_xyz(r);
g = d3_rgb_xyz(g);
b = d3_rgb_xyz(b);
var x = d3_xyz_lab((0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / d3_lab_X),
y = d3_xyz_lab((0.2126729 * r + 0.7151522 * g + 0.0721750 * b) / d3_lab_Y),
z = d3_xyz_lab((0.0193339 * r + 0.1191920 * g + 0.9503041 * b) / d3_lab_Z);
return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z));
}
function d3_rgb_xyz(r) {
return (r /= 255) <= 0.04045 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4);
}
function d3_rgb_parseNumber(c) { // either integer or percentage
var f = parseFloat(c);
return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
......
d3_selectionPrototype.attr = function(name, value) {
name = d3.ns.qualify(name);
// If no value is specified, return the first value.
if (arguments.length < 2) {
// For attr(string), return the attribute value for the first node.
if (typeof name === "string") {
var node = this.node();
name = d3.ns.qualify(name);
return name.local
? node.getAttributeNS(name.space, name.local)
: node.getAttribute(name);
}
// For attr(object), the object specifies the names and values of the
// attributes to set or remove. The values may be functions that are
// evaluated for each element.
for (value in name) this.each(d3_selection_attr(value, name[value]));
return this;
}
return this.each(d3_selection_attr(name, value));
};
function d3_selection_attr(name, value) {
name = d3.ns.qualify(name);
// For attr(string, null), remove the attribute with the specified name.
function attrNull() {
this.removeAttribute(name);
}
function attrNullNS() {
this.removeAttributeNS(name.space, name.local);
}
// For attr(string, string), set the attribute with the specified name.
function attrConstant() {
this.setAttribute(name, value);
}
function attrConstantNS() {
this.setAttributeNS(name.space, name.local, value);
}
// For attr(string, function), evaluate the function for each element, and set
// or remove the attribute as appropriate.
function attrFunction() {
var x = value.apply(this, arguments);
if (x == null) this.removeAttribute(name);
else this.setAttribute(name, x);
}
function attrFunctionNS() {
var x = value.apply(this, arguments);
if (x == null) this.removeAttributeNS(name.space, name.local);
else this.setAttributeNS(name.space, name.local, x);
}
return this.each(value == null
return value == null
? (name.local ? attrNullNS : attrNull) : (typeof value === "function"
? (name.local ? attrFunctionNS : attrFunction)
: (name.local ? attrConstantNS : attrConstant)));
};
: (name.local ? attrConstantNS : attrConstant));
}
d3_selectionPrototype.classed = function(name, value) {
var names = d3_collapse(name).split(" "),
n = names.length,
if (arguments.length < 2) {
// For classed(string), return true only if the first node has the specified
// class or classes. Note that even if the browser supports DOMTokenList, it
// probably doesn't support it on SVG elements (which can be animated).