Merge branch 'mbostock-master' into kde

Add missing `d3.sum` source file too.

Conflicts:
	Makefile
	d3.chart.min.js
	d3.js
	d3.min.js
This commit is contained in:
Jason Davies 2011-05-23 09:45:34 +01:00
Родитель 266452fb77 71264282b4
Коммит 5f03fa2276
79 изменённых файлов: 2571 добавлений и 564 удалений

Просмотреть файл

@ -40,16 +40,19 @@ d3.core.js: \
src/core/min.js \
src/core/max.js \
src/core/sum.js \
src/core/bisect.js \
src/core/nest.js \
src/core/keys.js \
src/core/values.js \
src/core/entries.js \
src/core/permute.js \
src/core/merge.js \
src/core/split.js \
src/core/collapse.js \
src/core/call.js \
src/core/range.js \
src/core/requote.js \
src/core/round.js \
src/core/xhr.js \
src/core/text.js \
src/core/json.js \
@ -61,6 +64,7 @@ d3.core.js: \
src/core/ease.js \
src/core/event.js \
src/core/interpolate.js \
src/core/uninterpolate.js \
src/core/rgb.js \
src/core/hsl.js \
src/core/selection.js \
@ -70,6 +74,8 @@ d3.core.js: \
d3.scale.js: \
src/scale/scale.js \
src/scale/linear.js \
src/scale/bilinear.js \
src/scale/polylinear.js \
src/scale/log.js \
src/scale/pow.js \
src/scale/sqrt.js \
@ -86,6 +92,7 @@ d3.svg.js: \
src/svg/chord.js \
src/svg/diagonal.js \
src/svg/mouse.js \
src/svg/touches.js \
src/svg/symbol.js
d3.behavior.js: \
@ -168,20 +175,29 @@ d3.geom.js: \
tests: \
tests/test-append.test \
tests/test-attr.test \
tests/test-classed.test \
tests/test-call.test \
tests/test-csv-parse.test \
tests/test-format.test \
tests/test-insert.test \
tests/test-interpolate.test \
tests/test-keys.test \
tests/test-nest.test \
tests/test-permute.test \
tests/test-remove.test \
tests/test-rgb.test \
tests/test-round.test \
tests/test-hsl.test \
tests/test-time-format.test \
tests/test-time-parse.test \
tests/test-transition.test \
tests/test-scale-linear.test \
tests/test-scale-polylinear.test \
tests/test-scale-log.test \
tests/test-scale-sqrt.test \
tests/test-scale-pow.test \
tests/test-scale-quantile.test \
tests/test-bisect.test \
tests/test-stats-median.test \
tests/test-svg-arc.test \
tests/test-svg-area.test \

Просмотреть файл

@ -69,7 +69,7 @@ d3.behavior.zoom = function() {
}
// adjust zoom level
if (e.type == "dblclick") {
if (e.type === "dblclick") {
z = e.shiftKey ? Math.ceil(z - 1) : Math.floor(z + 1);
} else {
var delta = (e.wheelDelta / 120 || -e.detail) * .1;
@ -80,7 +80,7 @@ d3.behavior.zoom = function() {
if ((since > 9) && (Math.abs(e.wheelDelta) / since >= 50)) bug40441 = 1;
bug40441Last = now;
}
if (bug40441 == 1) delta *= .03;
if (bug40441 === 1) delta *= .03;
z += delta;
}

2
d3.behavior.min.js поставляемый
Просмотреть файл

@ -1 +1 @@
(function(){d3.behavior={},d3.behavior.zoom=function(){function m(a,b){function i(a,b){var c=a.__domain||(a.__domain=a.domain()),d=a.range().map(function(a){return(a-b)/h});a.domain(c).domain(d.map(a.invert))}var g=d3.event,h=Math.pow(2,e);d3.event={scale:h,translate:[c,d],transform:function(a,b){a&&i(a,c),b&&i(b,d)}};try{for(var j=0,k=f.length;j<k;j++)f[j].call(this,a,b)}finally{d3.event=g}}function l(f,g){var i=d3.event;if(!h){var j=d3.svg.mouse(this.nearestViewportElement||this);h={x0:c,y0:d,z0:e,x1:c-j[0],y1:d-j[1]}}if(i.type=="dblclick")e=i.shiftKey?Math.ceil(e-1):Math.floor(e+1);else{var k=(i.wheelDelta/120||-i.detail)*.1;if(a<0){var l=Date.now(),n=l-b;n>9&&Math.abs(i.wheelDelta)/n>=50&&(a=1),b=l}a==1&&(k*=.03),e+=k}var o=Math.pow(2,e-h.z0)-1;c=h.x0+h.x1*o,d=h.y0+h.y1*o,m.call(this,f,g)}function k(){g&&(j(),g=null)}function j(){h=null,g&&(c=d3.event.clientX+g.x0,d=d3.event.clientY+g.y0,m.call(g.target,g.data,g.index))}function i(a,b){g={x0:c-d3.event.clientX,y0:d-d3.event.clientY,target:this,data:a,index:b},d3.event.preventDefault(),window.focus()}function h(){var a=this.on("mousedown",i).on("mousewheel",l).on("DOMMouseScroll",l).on("dblclick",l);d3.select(window).on("mousemove",j).on("mouseup",k)}var a=/WebKit\/533/.test(navigator.userAgent)?-1:0,b=0,c=0,d=0,e=0,f=[],g,h;h.on=function(a,b){a=="zoom"&&f.push(b);return h};return h}})()
(function(){d3.behavior={},d3.behavior.zoom=function(){function m(a,b){function i(a,b){var c=a.__domain||(a.__domain=a.domain()),d=a.range().map(function(a){return(a-b)/h});a.domain(c).domain(d.map(a.invert))}var g=d3.event,h=Math.pow(2,e);d3.event={scale:h,translate:[c,d],transform:function(a,b){a&&i(a,c),b&&i(b,d)}};try{for(var j=0,k=f.length;j<k;j++)f[j].call(this,a,b)}finally{d3.event=g}}function l(f,g){var i=d3.event;if(!h){var j=d3.svg.mouse(this.nearestViewportElement||this);h={x0:c,y0:d,z0:e,x1:c-j[0],y1:d-j[1]}}if(i.type==="dblclick")e=i.shiftKey?Math.ceil(e-1):Math.floor(e+1);else{var k=(i.wheelDelta/120||-i.detail)*.1;if(a<0){var l=Date.now(),n=l-b;n>9&&Math.abs(i.wheelDelta)/n>=50&&(a=1),b=l}a===1&&(k*=.03),e+=k}var o=Math.pow(2,e-h.z0)-1;c=h.x0+h.x1*o,d=h.y0+h.y1*o,m.call(this,f,g)}function k(){g&&(j(),g=null)}function j(){h=null,g&&(c=d3.event.clientX+g.x0,d=d3.event.clientY+g.y0,m.call(g.target,g.data,g.index))}function i(a,b){g={x0:c-d3.event.clientX,y0:d-d3.event.clientY,target:this,data:a,index:b},d3.event.preventDefault(),window.focus()}function h(){var a=this.on("mousedown",i).on("mousewheel",l).on("DOMMouseScroll",l).on("dblclick",l);d3.select(window).on("mousemove",j).on("mouseup",k)}var a=/WebKit\/533/.test(navigator.userAgent)?-1:0,b=0,c=0,d=0,e=0,f=[],g,h;h.on=function(a,b){a=="zoom"&&f.push(b);return h};return h}})()

Просмотреть файл

@ -231,6 +231,7 @@ d3.chart.box = function() {
.style("opacity", 1e-6)
.remove();
});
d3.timer.flush();
}
box.width = function(x) {
@ -453,6 +454,7 @@ d3.chart.bullet = function() {
.attr("opacity", 1e-6)
.remove();
});
d3.timer.flush();
}
// left, right, top, bottom

2
d3.chart.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -30,25 +30,25 @@ d3.csv.parseRows = function(text, f) {
/** @private Returns the next token. */
function token() {
if (re.lastIndex == text.length) return EOF; // special case: end of file
if (re.lastIndex === text.length) return EOF; // special case: end of file
if (eol) { eol = false; return EOL; } // special case: end of line
// special case: quotes
var j = re.lastIndex;
if (text.charCodeAt(j) == 34) {
if (text.charCodeAt(j) === 34) {
var i = j;
while (i++ < text.length) {
if (text.charCodeAt(i) == 34) {
if (text.charCodeAt(i + 1) != 34) break;
if (text.charCodeAt(i) === 34) {
if (text.charCodeAt(i + 1) !== 34) break;
i++;
}
}
re.lastIndex = i + 2;
var c = text.charCodeAt(i + 1);
if (c == 13) {
if (c === 13) {
eol = true;
if (text.charCodeAt(i + 2) == 10) re.lastIndex++;
} else if (c == 10) {
if (text.charCodeAt(i + 2) === 10) re.lastIndex++;
} else if (c === 10) {
eol = true;
}
return text.substring(j + 1, i).replace(/""/g, "\"");
@ -57,7 +57,7 @@ d3.csv.parseRows = function(text, f) {
// common case
var m = re.exec(text);
if (m) {
eol = m[0].charCodeAt(0) != 44;
eol = m[0].charCodeAt(0) !== 44;
return text.substring(j, m.index);
}
re.lastIndex = text.length;

2
d3.csv.min.js поставляемый
Просмотреть файл

@ -1 +1 @@
(function(){function b(a){return/[",\n]/.test(a)?'"'+a.replace(/\"/g,'""')+'"':a}function a(a){return a.map(b).join(",")}d3.csv=function(a,b){d3.text(a,"text/csv",function(a){b(a&&d3.csv.parse(a))})},d3.csv.parse=function(a){var b;return d3.csv.parseRows(a,function(a,c){if(c){var d={},e=-1,f=b.length;while(++e<f)d[b[e]]=a[e];return d}b=a;return null})},d3.csv.parseRows=function(a,b){function j(){if(f.lastIndex==a.length)return d;if(i){i=!1;return c}var b=f.lastIndex;if(a.charCodeAt(b)==34){var e=b;while(e++<a.length)if(a.charCodeAt(e)==34){if(a.charCodeAt(e+1)!=34)break;e++}f.lastIndex=e+2;var g=a.charCodeAt(e+1);g==13?(i=!0,a.charCodeAt(e+2)==10&&f.lastIndex++):g==10&&(i=!0);return a.substring(b+1,e).replace(/""/g,'"')}var h=f.exec(a);if(h){i=h[0].charCodeAt(0)!=44;return a.substring(b,h.index)}f.lastIndex=a.length;return a.substring(b)}var c={},d={},e=[],f=/\r\n|[,\r\n]/g,g=0,h,i;f.lastIndex=0;while((h=j())!==d){var k=[];while(h!==c&&h!==d)k.push(h),h=j();if(b&&!(k=b(k,g++)))continue;e.push(k)}return e},d3.csv.format=function(b){return b.map(a).join("\n")}})()
(function(){function b(a){return/[",\n]/.test(a)?'"'+a.replace(/\"/g,'""')+'"':a}function a(a){return a.map(b).join(",")}d3.csv=function(a,b){d3.text(a,"text/csv",function(a){b(a&&d3.csv.parse(a))})},d3.csv.parse=function(a){var b;return d3.csv.parseRows(a,function(a,c){if(c){var d={},e=-1,f=b.length;while(++e<f)d[b[e]]=a[e];return d}b=a;return null})},d3.csv.parseRows=function(a,b){function j(){if(f.lastIndex===a.length)return d;if(i){i=!1;return c}var b=f.lastIndex;if(a.charCodeAt(b)===34){var e=b;while(e++<a.length)if(a.charCodeAt(e)===34){if(a.charCodeAt(e+1)!==34)break;e++}f.lastIndex=e+2;var g=a.charCodeAt(e+1);g===13?(i=!0,a.charCodeAt(e+2)===10&&f.lastIndex++):g===10&&(i=!0);return a.substring(b+1,e).replace(/""/g,'"')}var h=f.exec(a);if(h){i=h[0].charCodeAt(0)!==44;return a.substring(b,h.index)}f.lastIndex=a.length;return a.substring(b)}var c={},d={},e=[],f=/\r\n|[,\r\n]/g,g=0,h,i;f.lastIndex=0;while((h=j())!==d){var k=[];while(h!==c&&h!==d)k.push(h),h=j();if(b&&!(k=b(k,g++)))continue;e.push(k)}return e},d3.csv.format=function(b){return b.map(a).join("\n")}})()

Просмотреть файл

@ -154,7 +154,7 @@ d3.geo.path = function() {
projection = d3.geo.albersUsa();
function path(d, i) {
if (typeof pointRadius == "function") {
if (typeof pointRadius === "function") {
pointCircle = d3_path_circle(pointRadius.apply(this, arguments));
}
return d3_geo_pathType(pathTypes, d);
@ -405,7 +405,7 @@ d3.geo.path = function() {
};
path.pointRadius = function(x) {
if (typeof x == "function") pointRadius = x;
if (typeof x === "function") pointRadius = x;
else {
pointRadius = +x;
pointCircle = d3_path_circle(pointRadius);

Просмотреть файл

@ -29,12 +29,12 @@ d3.geom.contour = function(grid, start) {
if (grid(x, y )) i += 8;
// determine next direction
if (i == 6) {
dx = pdy == -1 ? -1 : 1;
if (i === 6) {
dx = pdy === -1 ? -1 : 1;
dy = 0;
} else if (i == 9) {
} else if (i === 9) {
dx = 0;
dy = pdx == 1 ? -1 : 1;
dy = pdx === 1 ? -1 : 1;
} else {
dx = d3_geom_contourDx[i];
dy = d3_geom_contourDy[i];
@ -68,7 +68,7 @@ function d3_geom_contourStart(grid) {
if (grid(x,y)) {
return [x,y];
}
if (x == 0) {
if (x === 0) {
x = y + 1;
y = 0;
} else {
@ -76,7 +76,8 @@ function d3_geom_contourStart(grid) {
y = y + 1;
}
}
}/**
}
/**
* Computes the 2D convex hull of a set of points using Graham's scanning
* algorithm. The algorithm has been implemented as described in Cormen,
* Leiserson, and Rivest's Introduction to Algorithms. The running time of
@ -105,7 +106,7 @@ d3.geom.hull = function(vertices) {
// calculate polar angles from ref point and sort
for (i=0; i<len; ++i) {
if (i == h) continue;
if (i === h) continue;
y1 = vertices[i][1] - vertices[h][1];
x1 = vertices[i][0] - vertices[h][0];
points.push({angle: Math.atan2(y1, x1), index: i});
@ -142,7 +143,7 @@ d3.geom.hull = function(vertices) {
// initialize the stack
stack.push(h);
for (i=0, j=0; i<2; ++j) {
if (points[j].index != -1) {
if (points[j].index !== -1) {
stack.push(points[j].index);
i++;
}
@ -151,7 +152,7 @@ d3.geom.hull = function(vertices) {
// do graham's scan
for (; j<plen; ++j) {
if (points[j].index == -1) continue; // skip tossed out points
if (points[j].index === -1) continue; // skip tossed out points
while (!d3_geom_hullCCW(stack[sp-2], stack[sp-1], points[j].index, vertices)) {
--sp;
}
@ -173,7 +174,8 @@ function d3_geom_hullCCW(i1, i2, i3, v) {
t = v[i2]; c = t[0]; d = t[1];
t = v[i3]; e = t[0]; f = t[1];
return ((f-b)*(c-a) - (d-b)*(e-a)) > 0;
}// Note: requires coordinates to be counterclockwise and convex!
}
// Note: requires coordinates to be counterclockwise and convex!
d3.geom.polygon = function(coordinates) {
coordinates.area = function() {
@ -281,14 +283,14 @@ d3.geom.voronoi = function(vertices) {
x2,
y1,
y2;
if (e.a == 1 && e.b >= 0) {
if (e.a === 1 && e.b >= 0) {
s1 = e.ep.r;
s2 = e.ep.l;
} else {
s1 = e.ep.l;
s2 = e.ep.r;
}
if (e.a == 1) {
if (e.a === 1) {
y1 = s1 ? s1.y : -1e6;
x1 = e.c - e.b * y1;
y2 = s2 ? s2.y : 1e6;
@ -463,8 +465,8 @@ function d3_voronoi_tessellate(vertices, callback) {
e = e2;
}
var rightOfSite = (xint >= e.region.r.x);
if ((rightOfSite && (el.side == "l")) ||
(!rightOfSite && (el.side == "r"))) {
if ((rightOfSite && (el.side === "l")) ||
(!rightOfSite && (el.side === "r"))) {
return null;
}
return {
@ -478,13 +480,13 @@ function d3_voronoi_tessellate(vertices, callback) {
topsite = e.region.r,
rightOfSite = (p.x > topsite.x);
if (rightOfSite && (he.side == "l")) {
if (rightOfSite && (he.side === "l")) {
return 1;
}
if (!rightOfSite && (he.side == "r")) {
if (!rightOfSite && (he.side === "r")) {
return 0;
}
if (e.a == 1) {
if (e.a === 1) {
var dyp = p.y - topsite.y,
dxp = p.x - topsite.x,
fast = 0,
@ -519,7 +521,7 @@ function d3_voronoi_tessellate(vertices, callback) {
above = (t1 * t1) > (t2 * t2 + t3 * t3);
}
return he.side == "l" ? above : !above;
return he.side === "l" ? above : !above;
},
endPoint: function(edge, side, site) {
@ -559,7 +561,7 @@ function d3_voronoi_tessellate(vertices, callback) {
ls.splice(i, 1);
},
empty: function() { return EventQueue.list.length == 0; },
empty: function() { return EventQueue.list.length === 0; },
nextEvent: function(he) {
for (var i=0, ls=EventQueue.list, l=ls.length; i<l; ++i) {

2
d3.geom.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

553
d3.js поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
(function(){d3 = {version: "1.14.2"}; // semver
(function(){d3 = {version: "1.17.0"}; // semver
if (!Date.now) Date.now = function() {
return +new Date();
};
@ -25,7 +25,7 @@ try {
d3_array = d3_arrayCopy;
}
d3.functor = function(v) {
return typeof v == "function" ? v : function() { return v; };
return typeof v === "function" ? v : function() { return v; };
};
// A getter-setter method that preserves the appropriate `this` context.
d3.rebind = function(object, method) {
@ -45,7 +45,7 @@ d3.min = function(array, f) {
n = array.length,
a = array[0],
b;
if (arguments.length == 1) {
if (arguments.length === 1) {
while (++i < n) if (a > (b = array[i])) a = b;
} else {
a = f(array[0]);
@ -58,7 +58,7 @@ d3.max = function(array, f) {
n = array.length,
a = array[0],
b;
if (arguments.length == 1) {
if (arguments.length === 1) {
while (++i < n) if (a < (b = array[i])) a = b;
} else {
a = f(a);
@ -73,6 +73,44 @@ d3.sum = function(x) {
while (++i < n) s += x[i];
return s;
};
// Locate the insertion point for x in a to maintain sorted order. The
// arguments lo and hi may be used to specify a subset of the array which should
// be considered; by default the entire array is used. If x is already present
// in a, the insertion point will be before (to the left of) any existing
// entries. The return value is suitable for use as the first argument to
// `array.splice` assuming that a is already sorted.
//
// The returned insertion point i partitions the array a into two halves so that
// all v < x for v in a[lo:i] for the left side and all v >= x for v in a[i:hi]
// for the right side.
d3.bisectLeft = function(a, x, lo, hi) {
if (arguments.length < 3) lo = 0;
if (arguments.length < 4) hi = a.length;
while (lo < hi) {
var mid = (lo + hi) >> 1;
if (a[mid] < x) lo = mid + 1;
else hi = mid;
}
return lo;
};
// Similar to bisectLeft, but returns an insertion point which comes after (to
// the right of) any existing entries of x in a.
//
// The returned insertion point i partitions the array into two halves so that
// all v <= x for v in a[lo:i] for the left side and all v > x for v in a[i:hi]
// for the right side.
d3.bisect =
d3.bisectRight = function(a, x, lo, hi) {
if (arguments.length < 3) lo = 0;
if (arguments.length < 4) hi = a.length;
while (lo < hi) {
var mid = (lo + hi) >> 1;
if (x < a[mid]) hi = mid;
else lo = mid + 1;
}
return lo;
};
d3.nest = function() {
var nest = {},
keys = [],
@ -175,6 +213,13 @@ d3.entries = function(map) {
for (var key in map) entries.push({key: key, value: map[key]});
return entries;
};
d3.permute = function(array, indexes) {
var permutes = [],
i = -1,
n = indexes.length;
while (++i < n) permutes[i] = array[indexes[i]];
return permutes;
};
d3.merge = function(arrays) {
return Array.prototype.concat.apply([], arrays);
};
@ -221,7 +266,7 @@ function d3_call(callback) {
* @param {number=} step
*/
d3.range = function(start, stop, step) {
if (arguments.length == 1) { stop = start; start = 0; }
if (arguments.length === 1) { stop = start; start = 0; }
if (step == null) step = 1;
if ((stop - start) / step == Infinity) throw new Error("infinite range");
var range = [],
@ -236,13 +281,18 @@ d3.requote = function(s) {
};
var d3_requote_re = /[\\\^\$\*\+\?\[\]\(\)\.\{\}]/g;
d3.round = function(x, n) {
return n
? Math.round(x * Math.pow(10, n)) * Math.pow(10, -n)
: Math.round(x);
};
d3.xhr = function(url, mime, callback) {
var req = new XMLHttpRequest();
if (arguments.length < 3) callback = mime;
else if (mime && req.overrideMimeType) req.overrideMimeType(mime);
req.open("GET", url, true);
req.onreadystatechange = function() {
if (req.readyState == 4) callback(req.status < 300 ? req : null);
if (req.readyState === 4) callback(req.status < 300 ? req : null);
};
req.send(null);
};
@ -345,7 +395,7 @@ function d3_dispatch(type) {
return dispatch;
};
// TODO align, type
// TODO align
d3.format = function(specifier) {
var match = d3_format_re.exec(specifier),
fill = match[1] || " ",
@ -354,23 +404,35 @@ d3.format = function(specifier) {
width = +match[6],
comma = match[7],
precision = match[8],
type = match[9];
type = match[9],
percentage = false,
integer = false;
if (precision) precision = precision.substring(1);
if (zfill) {
fill = "0"; // TODO align = "=";
if (comma) width -= Math.floor((width - 1) / 4);
}
if (type == "d") precision = "0";
switch (type) {
case "n": comma = true; type = "g"; break;
case "%": percentage = true; type = "f"; break;
case "p": percentage = true; type = "r"; break;
case "d": integer = true; precision = "0"; break;
}
type = d3_format_types[type] || d3_format_typeDefault;
return function(value) {
var number = +value,
var number = percentage ? value * 100 : +value,
negative = (number < 0) && (number = -number) ? "\u2212" : sign;
// Return the empty string for floats formatted as ints.
if ((type == "d") && (number % 1)) return "";
if (integer && (number % 1)) return "";
// Convert the input value to the desired precision.
if (precision) value = number.toFixed(precision);
else value = "" + number;
value = type(number, precision);
// If the fill character is 0, the sign and group is applied after the fill.
if (zfill) {
@ -387,6 +449,7 @@ d3.format = function(specifier) {
var length = value.length;
if (length < width) value = new Array(width - length + 1).join(fill) + value;
}
if (percentage) value += "%";
return value;
};
@ -395,6 +458,20 @@ d3.format = function(specifier) {
// [[fill]align][sign][#][0][width][,][.precision][type]
var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/;
var d3_format_types = {
g: function(x, p) { return x.toPrecision(p); },
e: function(x, p) { return x.toExponential(p); },
f: function(x, p) { return x.toFixed(p); },
r: function(x, p) {
var n = 1 + Math.floor(1e-15 + Math.log(x) / Math.LN10);
return d3.round(x, p - n).toFixed(Math.max(0, p - n));
}
};
function d3_format_typeDefault(x) {
return x + "";
}
// Apply comma grouping for thousands.
function d3_format_group(value) {
var i = value.lastIndexOf("."),
@ -527,8 +604,8 @@ function d3_ease_bounce(t) {
}
d3.event = null;
d3.interpolate = function(a, b) {
if (typeof b == "number") return d3.interpolateNumber(+a, b);
if (typeof b == "string") {
if (typeof b === "number") return d3.interpolateNumber(+a, b);
if (typeof b === "string") {
return (b in d3_rgb_names) || /^(#|rgb\(|hsl\()/.test(b)
? d3.interpolateRgb(String(a), b)
: d3.interpolateString(String(a), b);
@ -614,7 +691,7 @@ d3.interpolateString = function(a, b) {
}
// Special optimization for only a single match.
if (s.length == 1) {
if (s.length === 1) {
return s[0] == null ? q[0].x : function() { return b; };
}
@ -703,25 +780,63 @@ function d3_interpolateByName(n) {
? d3.interpolateRgb
: d3.interpolate;
}
/**
* @param {number=} g
* @param {number=} b
*/
function d3_uninterpolateNumber(a, b) {
b = 1 / (b - (a = +a));
return function(x) { return (x - a) * b; };
}
function d3_uninterpolateClamp(a, b) {
b = 1 / (b - (a = +a));
return function(x) { return Math.max(0, Math.min(1, (x - a) * b)); };
}
d3.rgb = function(r, g, b) {
return arguments.length == 1
return arguments.length === 1
? d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb)
: d3_rgb(~~r, ~~g, ~~b);
};
function d3_rgb(r, g, b) {
return {r: r, g: g, b: b, toString: d3_rgb_format};
return new d3_Rgb(r, g, b);
}
/** @this d3_rgb */
function d3_rgb_format() {
return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);
function d3_Rgb(r, g, b) {
this.r = r;
this.g = g;
this.b = b;
}
d3_Rgb.prototype.brighter = function(k) {
k = Math.pow(0.7, arguments.length ? k : 1);
var r = this.r,
g = this.g,
b = this.b,
i = 30;
if (!r && !g && !b) return d3_rgb(i, i, i);
if (r && r < i) r = i;
if (g && g < i) g = i;
if (b && b < i) b = i;
return d3_rgb(
Math.min(255, Math.floor(r / k)),
Math.min(255, Math.floor(g / k)),
Math.min(255, Math.floor(b / k)));
};
d3_Rgb.prototype.darker = function(k) {
k = Math.pow(0.7, arguments.length ? k : 1);
return d3_rgb(
Math.max(0, Math.floor(k * this.r)),
Math.max(0, Math.floor(k * this.g)),
Math.max(0, Math.floor(k * this.b)));
};
d3_Rgb.prototype.hsl = function() {
return d3_rgb_hsl(this.r, this.g, this.b);
};
d3_Rgb.prototype.toString = function() {
return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);
};
function d3_rgb_hex(v) {
return v < 0x10 ? "0" + v.toString(16) : v.toString(16);
}
@ -760,12 +875,12 @@ function d3_rgb_parse(format, rgb, hsl) {
if (name = d3_rgb_names[format]) return rgb(name.r, name.g, name.b);
/* Hexadecimal colors: #rgb and #rrggbb. */
if (format != null && format.charAt(0) == "#") {
if (format.length == 4) {
if (format != null && format.charAt(0) === "#") {
if (format.length === 4) {
r = format.charAt(1); r += r;
g = format.charAt(2); g += g;
b = format.charAt(3); b += b;
} else if (format.length == 7) {
} else if (format.length === 7) {
r = format.substring(1, 3);
g = format.substring(3, 5);
b = format.substring(5, 7);
@ -799,7 +914,7 @@ function d3_rgb_hsl(r, g, b) {
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;
return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
}
var d3_rgb_names = {
@ -958,25 +1073,40 @@ for (var d3_rgb_name in d3_rgb_names) {
d3_rgb,
d3_hsl_rgb);
}
/**
* @param {number=} s
* @param {number=} l
*/
d3.hsl = function(h, s, l) {
return arguments.length == 1
return arguments.length === 1
? d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl)
: d3_hsl(+h, +s, +l);
};
function d3_hsl(h, s, l) {
return {h: h, s: s, l: l, toString: d3_hsl_format};
return new d3_Hsl(h, s, l);
}
/** @this d3_hsl */
function d3_hsl_format() {
return "hsl(" + this.h + "," + this.s * 100 + "%," + this.l * 100 + "%)";
function d3_Hsl(h, s, l) {
this.h = h;
this.s = s;
this.l = l;
}
d3_Hsl.prototype.brighter = function(k) {
k = Math.pow(0.7, arguments.length ? k : 1);
return d3_hsl(this.h, this.s, this.l / k);
};
d3_Hsl.prototype.darker = function(k) {
k = Math.pow(0.7, arguments.length ? k : 1);
return d3_hsl(this.h, this.s, k * this.l);
};
d3_Hsl.prototype.rgb = function() {
return d3_hsl_rgb(this.h, this.s, this.l);
};
d3_Hsl.prototype.toString = function() {
return "hsl(" + this.h + "," + this.s * 100 + "%," + this.l * 100 + "%)";
};
function d3_hsl_rgb(h, s, l) {
var m1,
m2;
@ -1009,7 +1139,7 @@ var d3_select = function(s, n) { return n.querySelector(s); },
d3_selectAll = function(s, n) { return d3_array(n.querySelectorAll(s)); };
// Use Sizzle, if available.
if (typeof Sizzle == "function") {
if (typeof Sizzle === "function") {
d3_select = function(s, n) { return Sizzle(s, n)[0]; };
d3_selectAll = function(s, n) { return Sizzle.uniqueSort(Sizzle(s, n)); };
}
@ -1019,13 +1149,13 @@ d3_root[0].parentNode = document.documentElement;
// TODO fast singleton implementation!
d3.select = function(selector) {
return typeof selector == "string"
return typeof selector === "string"
? d3_root.select(selector)
: d3_selection([[selector]]); // assume node
};
d3.selectAll = function(selector) {
return typeof selector == "string"
return typeof selector === "string"
? d3_root.selectAll(selector)
: d3_selection([d3_array(selector)]); // assume node[]
};
@ -1204,7 +1334,7 @@ function d3_selection(groups) {
var i = -1,
n = groups.length,
group;
if (typeof data == "function") {
if (typeof data === "function") {
while (++i < n) {
bind(group = groups[i], data.call(group, group.parentNode.__data__, i));
}
@ -1301,7 +1431,7 @@ function d3_selection(groups) {
}
return groups.each(value == null
? (name.local ? attrNullNS : attrNull) : (typeof value == "function"
? (name.local ? attrNullNS : attrNull) : (typeof value === "function"
? (name.local ? attrFunctionNS : attrFunction)
: (name.local ? attrConstantNS : attrConstant)));
};
@ -1312,24 +1442,36 @@ function d3_selection(groups) {
// If no value is specified, return the first value.
if (arguments.length < 2) {
return first(function() {
if (c = this.classList) return c.contains(name);
var c = this.className;
re.lastIndex = 0;
return re.test(this.className);
return re.test(c.baseVal != null ? c.baseVal : c);
});
}
/** @this {Element} */
function classedAdd() {
var classes = this.className;
if (c = this.classList) return c.add(name);
var c = this.className,
cb = c.baseVal != null,
cv = cb ? c.baseVal : c;
re.lastIndex = 0;
if (!re.test(classes)) {
this.className = d3_collapse(classes + " " + name);
if (!re.test(cv)) {
cv = d3_collapse(cv + " " + name);
if (cb) c.baseVal = cv;
else this.className = cv;
}
}
/** @this {Element} */
function classedRemove() {
var classes = d3_collapse(this.className.replace(re, " "));
this.className = classes.length ? classes : null;
if (c = this.classList) return c.remove(name);
var c = this.className,
cb = c.baseVal != null,
cv = cb ? c.baseVal : c;
cv = d3_collapse(cv.replace(re, " "));
if (cb) c.baseVal = cv;
else this.className = cv;
}
/** @this {Element} */
@ -1339,7 +1481,7 @@ function d3_selection(groups) {
: classedRemove).call(this);
}
return groups.each(typeof value == "function"
return groups.each(typeof value === "function"
? classedFunction : value
? classedAdd
: classedRemove);
@ -1373,7 +1515,7 @@ function d3_selection(groups) {
}
return groups.each(value == null
? styleNull : (typeof value == "function"
? styleNull : (typeof value === "function"
? styleFunction : styleConstant));
};
@ -1405,7 +1547,7 @@ function d3_selection(groups) {
}
return groups.each(value == null
? propertyNull : (typeof value == "function"
? propertyNull : (typeof value === "function"
? propertyFunction : propertyConstant));
};
@ -1428,7 +1570,7 @@ function d3_selection(groups) {
this.textContent = value.apply(this, arguments);
}
return groups.each(typeof value == "function"
return groups.each(typeof value === "function"
? textFunction : textConstant);
};
@ -1451,7 +1593,7 @@ function d3_selection(groups) {
this.innerHTML = value.apply(this, arguments);
}
return groups.each(typeof value == "function"
return groups.each(typeof value === "function"
? htmlFunction : htmlConstant);
};
@ -1525,7 +1667,7 @@ function d3_selection(groups) {
// parse the type specifier
var i = type.indexOf("."),
typo = i == -1 ? type : type.substring(0, i),
typo = i === -1 ? type : type.substring(0, i),
name = "__on" + type;
// remove the old event listener, and add the new event listener
@ -1533,12 +1675,13 @@ function d3_selection(groups) {
if (this[name]) this.removeEventListener(typo, this[name], capture);
if (listener) this.addEventListener(typo, this[name] = l, capture);
// wrapped event listener that preserves d, i
// wrapped event listener that preserves i
var node = this;
function l(e) {
var o = d3.event; // Events can be reentrant (e.g., focus).
d3.event = e;
try {
listener.call(this, d, i);
listener.call(this, node.__data__, i);
} finally {
d3.event = o;
}
@ -1680,7 +1823,7 @@ function d3_transition(groups) {
var clear = true,
k = -1;
groups.each(function() {
if (stage[++k] == 2) return; // ended
if (stage[++k] === 2) return; // ended
var t = (elapsed - delay[k]) / duration[k],
tx = this.__transition__,
te, // ease(t)
@ -1700,7 +1843,7 @@ function d3_transition(groups) {
// 1 - In progress.
// 2 - Ended.
if (stage[k]) {
if (!tx || tx.active != transitionId) {
if (!tx || tx.active !== transitionId) {
stage[k] = 2;
return;
}
@ -1724,11 +1867,11 @@ function d3_transition(groups) {
for (tk in ik) ik[tk].call(this, te);
// Handle ending transitions.
if (t == 1) {
if (t === 1) {
stage[k] = 2;
if (tx.active == transitionId) {
if (tx.active === transitionId) {
var owner = tx.owner;
if (owner == transitionId) {
if (owner === transitionId) {
delete this.__transition__;
if (remove) this.parentNode.removeChild(this);
}
@ -1745,7 +1888,7 @@ function d3_transition(groups) {
transition.delay = function(value) {
var delayMin = Infinity,
k = -1;
if (typeof value == "function") {
if (typeof value === "function") {
groups.each(function(d, i) {
var x = delay[++k] = +value.apply(this, arguments);
if (x < delayMin) delayMin = x;
@ -1762,7 +1905,7 @@ function d3_transition(groups) {
transition.duration = function(value) {
var k = -1;
if (typeof value == "function") {
if (typeof value === "function") {
durationMax = 0;
groups.each(function(d, i) {
var x = duration[++k] = +value.apply(this, arguments);
@ -1778,7 +1921,7 @@ function d3_transition(groups) {
};
transition.ease = function(value) {
ease = typeof value == "function" ? value : d3.ease.apply(d3, arguments);
ease = typeof value === "function" ? value : d3.ease.apply(d3, arguments);
return transition;
};
@ -1830,7 +1973,7 @@ function d3_transition(groups) {
transition.text = function(value) {
tweens.text = function(d, i) {
this.textContent = typeof value == "function"
this.textContent = typeof value === "function"
? value.call(this, d, i)
: value;
};
@ -1867,7 +2010,7 @@ function d3_transition(groups) {
}
function d3_transitionTween(b) {
return typeof b == "function"
return typeof b === "function"
? function(d, i, a) { return d3.interpolate(a, String(b.call(this, d, i))); }
: (b = String(b), function(d, i, a) { return d3.interpolate(a, b); });
}
@ -1919,13 +2062,12 @@ function d3_timer(callback, delay) {
function d3_timer_step() {
var elapsed,
now = Date.now(),
t0 = null,
t1 = d3_timer_queue;
while (t1) {
elapsed = now - t1.then;
if (elapsed > t1.delay) t1.flush = t1.callback(elapsed);
t1 = (t0 = t1).next;
t1 = t1.next;
}
var delay = d3_timer_flush() - now;
@ -1941,6 +2083,20 @@ function d3_timer_step() {
}
}
d3.timer.flush = function() {
var elapsed,
now = Date.now(),
t1 = d3_timer_queue;
while (t1) {
elapsed = now - t1.then;
if (!t1.delay) t1.flush = t1.callback(elapsed);
t1 = t1.next;
}
d3_timer_flush();
};
// Flush after callbacks, to avoid concurrent queue modification.
function d3_timer_flush() {
var t0 = null,
@ -1965,42 +2121,40 @@ var d3_timer_frame = window.requestAnimationFrame
|| function(callback) { setTimeout(callback, 17); };
d3.scale = {};
d3.scale.linear = function() {
var x0 = 0,
x1 = 1,
y0 = 0,
y1 = 1,
kx = 1, // 1 / (x1 - x0)
ky = 1, // (x1 - x0) / (y1 - y0)
var domain = [0, 1],
range = [0, 1],
interpolate = d3.interpolate,
i = interpolate(y0, y1),
clamp = false;
clamp = false,
output,
input;
function rescale() {
var linear = domain.length == 2 ? d3_scale_bilinear : d3_scale_polylinear,
uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
output = linear(domain, range, uninterpolate, interpolate);
input = linear(range, domain, uninterpolate, d3.interpolate);
return scale;
}
function scale(x) {
x = (x - x0) * kx;
return i(clamp ? Math.max(0, Math.min(1, x)) : x);
return output(x);
}
// Note: requires range is coercible to number!
scale.invert = function(y) {
return (y - y0) * ky + x0;
return input(y);
};
scale.domain = function(x) {
if (!arguments.length) return [x0, x1];
x0 = +x[0];
x1 = +x[1];
kx = 1 / (x1 - x0);
ky = (x1 - x0) / (y1 - y0);
return scale;
if (!arguments.length) return domain;
domain = x.map(Number);
return rescale();
};
scale.range = function(x) {
if (!arguments.length) return [y0, y1];
y0 = x[0];
y1 = x[1];
ky = (x1 - x0) / (y1 - y0);
i = interpolate(y0, y1);
return scale;
if (!arguments.length) return range;
range = x;
return rescale();
};
scale.rangeRound = function(x) {
@ -2010,19 +2164,19 @@ d3.scale.linear = function() {
scale.clamp = function(x) {
if (!arguments.length) return clamp;
clamp = x;
return scale;
return rescale();
};
scale.interpolate = function(x) {
if (!arguments.length) return interpolate;
i = (interpolate = x)(y0, y1);
return scale;
interpolate = x;
return rescale();
};
// TODO Dates? Ugh.
function tickRange(m) {
var start = Math.min(x0, x1),
stop = Math.max(x0, x1),
var start = d3.min(domain),
stop = d3.max(domain),
span = stop - start,
step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)),
err = m / (span / step);
@ -2050,8 +2204,31 @@ d3.scale.linear = function() {
return d3.format(",." + n + "f");
};
return scale;
return rescale();
};
function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
var u = uninterpolate(domain[0], domain[1]),
i = interpolate(range[0], range[1]);
return function(x) {
return i(u(x));
};
}
function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
var u = [],
i = [],
j = 0,
n = domain.length;
while (++j < n) {
u.push(uninterpolate(domain[j - 1], domain[j]));
i.push(interpolate(range[j - 1], range[j]));
}
return function(x) {
var j = d3.bisect(domain, x, 1, domain.length - 1) - 1;
return i[j](u[j](x));
};
}
d3.scale.log = function() {
var linear = d3.scale.linear(),
log = d3_scale_log,
@ -2306,26 +2483,21 @@ d3.scale.quantile = function() {
thresholds = [];
function rescale() {
var i = -1,
n = thresholds.length = range.length,
k = domain.length / n;
while (++i < n) thresholds[i] = domain[~~(i * k)];
var k = 0,
n = domain.length,
q = range.length,
i;
thresholds.length = Math.max(0, q - 1);
while (++k < q) {
thresholds[k - 1] = (i = n * k / q) % 1
? domain[~~i]
: (domain[i = ~~i] + domain[i - 1]) / 2;
}
function quantile(value) {
if (isNaN(value = +value)) return NaN;
var low = 0, high = thresholds.length - 1;
while (low <= high) {
var mid = (low + high) >> 1, midValue = thresholds[mid];
if (midValue < value) low = mid + 1;
else if (midValue > value) high = mid - 1;
else return mid;
}
return high < 0 ? 0 : high;
}
function scale(x) {
return range[quantile(x)];
if (isNaN(x = +x)) return NaN;
return range[d3.bisect(thresholds, x)];
}
scale.domain = function(x) {
@ -2520,8 +2692,8 @@ function d3_svg_linePoints(self, d, x, y) {
var points = [],
i = -1,
n = d.length,
fx = typeof x == "function",
fy = typeof y == "function",
fx = typeof x === "function",
fy = typeof y === "function",
value;
if (fx && fy) {
while (++i < n) points.push([
@ -2554,9 +2726,12 @@ var d3_svg_lineInterpolators = {
"step-before": d3_svg_lineStepBefore,
"step-after": d3_svg_lineStepAfter,
"basis": d3_svg_lineBasis,
"basis-open": d3_svg_lineBasisOpen,
"basis-closed": d3_svg_lineBasisClosed,
"cardinal": d3_svg_lineCardinal,
"cardinal-closed": d3_svg_lineCardinalClosed
"cardinal-open": d3_svg_lineCardinalOpen,
"cardinal-closed": d3_svg_lineCardinalClosed,
"monotone": d3_svg_lineMonotone
};
// Linear interpolation; generates "L" commands.
@ -2592,6 +2767,14 @@ function d3_svg_lineStepAfter(points) {
return path.join("");
}
// Open cardinal spline interpolation; generates "C" commands.
function d3_svg_lineCardinalOpen(points, tension) {
return points.length < 4
? d3_svg_lineLinear(points)
: points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1),
d3_svg_lineCardinalTangents(points, tension));
}
// Closed cardinal spline interpolation; generates "C" commands.
function d3_svg_lineCardinalClosed(points, tension) {
return points.length < 3
@ -2674,7 +2857,7 @@ function d3_svg_lineCardinalTangents(points, tension) {
return tangents;
}
// Open B-spline interpolation; generates "C" commands.
// B-spline interpolation; generates "C" commands.
function d3_svg_lineBasis(points) {
if (points.length < 3) return d3_svg_lineLinear(points);
var path = [],
@ -2702,6 +2885,31 @@ function d3_svg_lineBasis(points) {
return path.join("");
}
// Open B-spline interpolation; generates "C" commands.
function d3_svg_lineBasisOpen(points) {
if (points.length < 4) return d3_svg_lineLinear(points);
var path = [],
i = -1,
n = points.length,
pi,
px = [0],
py = [0];
while (++i < 3) {
pi = points[i];
px.push(pi[0]);
py.push(pi[1]);
}
path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px)
+ "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py));
--i; while (++i < n) {
pi = points[i];
px.shift(); px.push(pi[0]);
py.shift(); py.push(pi[1]);
d3_svg_lineBasisBezier(path, px, py);
}
return path.join("");
}
// Closed B-spline interpolation; generates "C" commands.
function d3_svg_lineBasisClosed(points) {
var path,
@ -2751,6 +2959,89 @@ function d3_svg_lineBasisBezier(path, x, y) {
",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x),
",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y));
}
// Computes the slope from points p0 to p1.
function d3_svg_lineSlope(p0, p1) {
return (p1[1] - p0[1]) / (p1[0] - p0[0]);
}
// Compute three-point differences for the given points.
// http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Finite_difference
function d3_svg_lineFiniteDifferences(points) {
var i = 0,
j = points.length - 1,
m = [],
p0 = points[0],
p1 = points[1],
d = m[0] = d3_svg_lineSlope(p0, p1);
while (++i < j) {
m[i] = d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]));
}
m[i] = d;
return m;
}
// Interpolates the given points using Fritsch-Carlson Monotone cubic Hermite
// interpolation. Returns an array of tangent vectors. For details, see
// http://en.wikipedia.org/wiki/Monotone_cubic_interpolation
function d3_svg_lineMonotoneTangents(points) {
var tangents = [],
d,
a,
b,
s,
m = d3_svg_lineFiniteDifferences(points),
i = -1,
j = points.length - 1;
// The first two steps are done by computing finite-differences:
// 1. Compute the slopes of the secant lines between successive points.
// 2. Initialize the tangents at every point as the average of the secants.
// Then, for each segment…
while (++i < j) {
d = d3_svg_lineSlope(points[i], points[i + 1]);
// 3. If two successive yk = y{k + 1} are equal (i.e., d is zero), then set
// mk = m{k + 1} = 0 as the spline connecting these points must be flat to
// preserve monotonicity. Ignore step 4 and 5 for those k.
if (Math.abs(d) < 1e-6) {
m[i] = m[i + 1] = 0;
} else {
// 4. Let ak = mk / dk and bk = m{k + 1} / dk.
a = m[i] / d;
b = m[i + 1] / d;
// 5. Prevent overshoot and ensure monotonicity by restricting the
// magnitude of vector <ak, bk> to a circle of radius 3.
s = a * a + b * b;
if (s > 9) {
s = d * 3 / Math.sqrt(s);
m[i] = s * a;
m[i + 1] = s * b;
}
}
}
// Compute the normalized tangent vector from the slopes. Note that if x is
// not monotonic, it's possible that the slope will be infinite, so we protect
// against NaN by setting the coordinate to zero.
i = -1; while (++i <= j) {
s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0])
/ (6 * (1 + m[i] * m[i]));
tangents.push([s || 0, m[i] * s || 0]);
}
return tangents;
}
function d3_svg_lineMonotone(points) {
return points.length < 3
? d3_svg_lineLinear(points)
: points[0] +
d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points));
}
d3.svg.area = function() {
var x = d3_svg_lineX,
y0 = d3_svg_areaY0,
@ -2942,6 +3233,13 @@ function d3_svg_diagonalProjection(d) {
return [d.x, d.y];
}
d3.svg.mouse = function(container) {
return d3_svg_mousePoint(container, d3.event);
};
// https://bugs.webkit.org/show_bug.cgi?id=44083
var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0;
function d3_svg_mousePoint(container, e) {
var point = (container.ownerSVGElement || container).createSVGPoint();
if ((d3_mouse_bug44083 < 0) && (window.scrollX || window.scrollY)) {
var svg = d3.select(document.body)
@ -2954,18 +3252,23 @@ d3.svg.mouse = function(container) {
svg.remove();
}
if (d3_mouse_bug44083) {
point.x = d3.event.pageX;
point.y = d3.event.pageY;
point.x = e.pageX;
point.y = e.pageY;
} else {
point.x = d3.event.clientX;
point.y = d3.event.clientY;
point.x = e.clientX;
point.y = e.clientY;
}
point = point.matrixTransform(container.getScreenCTM().inverse());
return [point.x, point.y];
};
// https://bugs.webkit.org/show_bug.cgi?id=44083
var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0;
d3.svg.touches = function(container) {
var touches = d3.event.touches;
return touches ? d3_array(touches).map(function(touch) {
var point = d3_svg_mousePoint(container, touch);
point.identifier = touch.identifier;
return point;
}) : [];
};
d3.svg.symbol = function() {
var type = d3_svg_symbolType,
size = d3_svg_symbolSize;

Просмотреть файл

@ -550,12 +550,12 @@ d3.layout.pie = function() {
function pie(data, i) {
// Compute the start angle.
var a = +(typeof startAngle == "function"
var a = +(typeof startAngle === "function"
? startAngle.apply(this, arguments)
: startAngle);
// Compute the angular range (end - start).
var k = (typeof endAngle == "function"
var k = (typeof endAngle === "function"
? endAngle.apply(this, arguments)
: endAngle) - startAngle;
@ -636,49 +636,104 @@ d3.layout.pie = function() {
return pie;
};
// data is two-dimensional array of x,y; we populate y0
// TODO perhaps make the `x`, `y` and `y0` structure customizable
d3.layout.stack = function() {
var order = "default",
offset = "zero";
var values = Object,
order = d3_layout_stackOrders["default"],
offset = d3_layout_stackOffsets["zero"],
out = d3_layout_stackOut,
x = d3_layout_stackX,
y = d3_layout_stackY;
function stack(data) {
var n = data.length,
m = data[0].length,
function stack(data, index) {
// Convert series to canonical two-dimensional representation.
var series = data.map(function(d, i) {
return values.call(stack, d, i);
});
// Convert each series to canonical [[x,y]] representation.
var points = series.map(function(d, i) {
return d.map(function(v, i) {
return [x.call(stack, v, i), y.call(stack, v, i)];
});
});
// Compute the order of series, and permute them.
var orders = order.call(stack, points, index);
series = d3.permute(series, orders);
points = d3.permute(points, orders);
// Compute the baseline…
var offsets = offset.call(stack, points, index);
// And propagate it to other series.
var n = series.length,
m = series[0].length,
i,
j,
y0;
// compute the order of series
var index = d3_layout_stackOrders[order](data);
// set y0 on the baseline
d3_layout_stackOffsets[offset](data, index);
// propagate offset to other series
o;
for (j = 0; j < m; ++j) {
for (i = 1, y0 = data[index[0]][j].y0; i < n; ++i) {
data[index[i]][j].y0 = y0 += data[index[i - 1]][j].y;
out.call(stack, series[0][j], o = offsets[j], points[0][j][1]);
for (i = 1; i < n; ++i) {
out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]);
}
}
return data;
}
stack.values = function(x) {
if (!arguments.length) return values;
values = x;
return stack;
};
stack.order = function(x) {
if (!arguments.length) return order;
order = x;
order = typeof x === "function" ? x : d3_layout_stackOrders[x];
return stack;
};
stack.offset = function(x) {
if (!arguments.length) return offset;
offset = x;
offset = typeof x === "function" ? x : d3_layout_stackOffsets[x];
return stack;
};
stack.x = function(z) {
if (!arguments.length) return x;
x = z;
return stack;
};
stack.y = function(z) {
if (!arguments.length) return y;
y = z;
return stack;
};
stack.out = function(z) {
if (!arguments.length) return out;
out = z;
return stack;
};
return stack;
}
function d3_layout_stackX(d) {
return d.x;
}
function d3_layout_stackY(d) {
return d.y;
}
function d3_layout_stackOut(d, y0, y) {
d.y0 = y0;
d.y = y;
}
var d3_layout_stackOrders = {
"inside-out": function(data) {
@ -692,7 +747,7 @@ var d3_layout_stackOrders = {
bottom = 0,
tops = [],
bottoms = [];
for (i = 0; i < n; i++) {
for (i = 0; i < n; ++i) {
j = index[i];
if (top < bottom) {
top += sums[j];
@ -717,25 +772,27 @@ var d3_layout_stackOrders = {
var d3_layout_stackOffsets = {
"silhouette": function(data, index) {
"silhouette": function(data) {
var n = data.length,
m = data[0].length,
sums = [],
max = 0,
i,
j,
o;
o,
y0 = [];
for (j = 0; j < m; ++j) {
for (i = 0, o = 0; i < n; i++) o += data[i][j].y;
for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
if (o > max) max = o;
sums.push(o);
}
for (j = 0, i = index[0]; j < m; ++j) {
data[i][j].y0 = (max - sums[j]) / 2;
for (j = 0; j < m; ++j) {
y0[j] = (max - sums[j]) / 2;
}
return y0;
},
"wiggle": function(data, index) {
"wiggle": function(data) {
var n = data.length,
x = data[0],
m = x.length,
@ -743,51 +800,64 @@ var d3_layout_stackOffsets = {
i,
j,
k,
ii,
ik,
i0 = index[0],
s1,
s2,
s3,
dx,
o,
o0;
data[i0][0].y0 = o = o0 = 0;
o0,
y0 = [];
y0[0] = o = o0 = 0;
for (j = 1; j < m; ++j) {
for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j].y;
for (i = 0, s2 = 0, dx = x[j].x - x[j - 1].x; i < n; ++i) {
for (k = 0, ii = index[i], s3 = (data[ii][j].y - data[ii][j - 1].y) / (2 * dx); k < i; ++k) {
s3 += (data[ik = index[k]][j].y - data[ik][j - 1].y) / dx;
for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1];
for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) {
for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) {
s3 += (data[k][j][1] - data[k][j - 1][1]) / dx;
}
s2 += s3 * data[ii][j].y;
s2 += s3 * data[i][j][1];
}
data[i0][j].y0 = o -= s1 ? s2 / s1 * dx : 0;
y0[j] = o -= s1 ? s2 / s1 * dx : 0;
if (o < o0) o0 = o;
}
for (j = 0; j < m; ++j) data[i0][j].y0 -= o0;
for (j = 0; j < m; ++j) y0[j] -= o0;
return y0;
},
"zero": function(data, index) {
var j = 0,
"expand": function(data) {
var n = data.length,
m = data[0].length,
i0 = index[0];
for (; j < m; ++j) data[i0][j].y0 = 0;
k = 1 / n,
i,
j,
o,
y0 = [];
for (j = 0; j < m; ++j) {
for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
if (o) for (i = 0; i < n; i++) data[i][j][1] /= o;
else for (i = 0; i < n; i++) data[i][j][1] = k;
}
for (j = 0; j < m; ++j) y0[j] = 0;
return y0;
},
"zero": function(data) {
var j = -1,
m = data[0].length,
y0 = [];
while (++j < m) y0[j] = 0;
return y0;
}
};
function d3_layout_stackReduceSum(d) {
return d.reduce(d3_layout_stackSum, 0);
}
function d3_layout_stackMaxIndex(array) {
var i = 1,
j = 0,
v = array[0].y,
v = array[0][1],
k,
n = array.length;
for (; i < n; ++i) {
if ((k = array[i].y) > v) {
if ((k = array[i][1]) > v) {
j = i;
v = k;
}
@ -795,87 +865,114 @@ function d3_layout_stackMaxIndex(array) {
return j;
}
function d3_layout_stackReduceSum(d) {
return d.reduce(d3_layout_stackSum, 0);
}
function d3_layout_stackSum(p, d) {
return p + d.y;
return p + d[1];
}
d3.layout.histogram = function() {
var frequency = true,
value = Number,
ticksFunction = d3_layout_histogramTicks;
valuer = Number,
ranger = d3_layout_histogramRange,
binner = d3_layout_histogramBinSturges;
function histogram(data, i) {
var x = data.map(value), bins = [];
// Initialize default ticks.
var ticks = ticksFunction.call(this, data, i);
var bins = [],
values = data.map(valuer, this),
range = ranger.call(this, values, i),
thresholds = binner.call(this, range, values, i),
bin,
i = -1,
n = values.length,
m = thresholds.length - 1,
k = frequency ? 1 / n : 1,
x;
// Initialize the bins.
for (var i = 0; i < ticks.length - 1; i++) {
var bin = bins[i] = [];
bin.x = ticks[i];
bin.dx = ticks[i + 1] - ticks[i];
while (++i < m) {
bin = bins[i] = [];
bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]);
bin.y = 0;
}
// Count the number of samples per bin.
for (var i = 0; i < x.length; i++) {
var j = d3_layout_histogramSearchIndex(ticks, x[i]) - 1,
bin = bins[Math.max(0, Math.min(bins.length - 1, j))];
bin.y++;
// Fill the bins, ignoring values outside the range.
i = -1; while(++i < n) {
x = values[i];
if ((x >= range[0]) && (x <= range[1])) {
bin = bins[d3.bisect(thresholds, x, 1, m) - 1];
bin.y += k;
bin.push(data[i]);
}
// Convert frequencies to probabilities.
if (!frequency) for (var i = 0; i < bins.length; i++) {
bins[i].y /= x.length;
}
return bins;
}
// Specifies how to extract a value from the associated data. The default
// value function is `Number`, which is equivalent to the identity function.
histogram.value = function(x) {
if (!arguments.length) return valuer;
valuer = x;
return histogram;
};
// Specifies the range of the histogram. Values outside the specified range
// will be ignored. The argument `x` may be specified either as a two-element
// array representing the minimum and maximum value of the range, or as a
// function that returns the range given the array of values and the current
// index `i`. The default range is the extent (minimum and maximum) of the
// values.
histogram.range = function(x) {
if (!arguments.length) return ranger;
ranger = d3.functor(x);
return histogram;
};
// Specifies how to bin values in the histogram. The argument `x` may be
// specified as a number, in which case the range of values will be split
// uniformly into the given number of bins. Or, `x` may be an array of
// threshold values, defining the bins; the specified array must contain the
// rightmost (upper) value, thus specifying n + 1 values for n bins. Or, `x`
// may be a function which is evaluated, being passed the range, the array of
// values, and the current index `i`, returning an array of thresholds. The
// default bin function will divide the values into uniform bins using
// Sturges' formula.
histogram.bins = function(x) {
if (!arguments.length) return binner;
binner = typeof x === "number"
? function(range) { return d3_layout_histogramBinFixed(range, x); }
: d3.functor(x);
return histogram;
};
// Specifies whether the histogram's `y` value is a count (frequency) or a
// probability (density). The default value is true.
histogram.frequency = function(x) {
if (!arguments.length) return frequency;
frequency = Boolean(x);
return histogram;
};
histogram.ticks = function(x) {
if (!arguments.length) return ticksFunction;
ticksFunction = d3.functor(x);
return histogram;
};
histogram.value = function(x) {
if (!arguments.length) return value;
value = x;
frequency = !!x;
return histogram;
};
return histogram;
};
// Performs a binary search on a sorted array.
// Returns the index of the value if found, otherwise -(insertion point) - 1.
// The insertion point is the index at which value should be inserted into the
// array for the array to remain sorted.
function d3_layout_histogramSearch(array, value) {
var low = 0, high = array.length - 1;
while (low <= high) {
var mid = (low + high) >> 1, midValue = array[mid];
if (midValue < value) low = mid + 1;
else if (midValue > value) high = mid - 1;
else return mid;
}
return -low - 1;
function d3_layout_histogramBinSturges(range, values) {
return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1));
}
function d3_layout_histogramSearchIndex(array, value) {
var i = d3_layout_histogramSearch(array, value);
return (i < 0) ? (-i - 1) : i;
function d3_layout_histogramBinFixed(range, n) {
var x = -1,
b = +range[0],
m = (range[1] - b) / n,
f = [];
while (++x <= n) f[x] = m * x + b;
return f;
}
function d3_layout_histogramTicks(x) {
return d3.scale.linear().domain(x).ticks(10);
function d3_layout_histogramRange(values) {
return [d3.min(values), d3.max(values)];
}
d3.layout.hierarchy = function() {
var sort = d3_layout_hierarchySort,
@ -1074,14 +1171,14 @@ function d3_layout_packCircle(nodes) {
// Search for the closest intersection.
var isect = 0, s1 = 1, s2 = 1;
for (j = b._pack_next; j != b; j = j._pack_next, s1++) {
for (j = b._pack_next; j !== b; j = j._pack_next, s1++) {
if (d3_layout_packIntersects(j, c)) {
isect = 1;
break;
}
}
if (isect == 1) {
for (k = a._pack_prev; k != j._pack_prev; k = k._pack_prev, s2++) {
for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) {
if (d3_layout_packIntersects(k, c)) {
if (s2 < s1) {
isect = -1;

2
d3.layout.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

4
d3.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -15,8 +15,8 @@ var calendar = {
Date: calendar.format(date)
});
date.setDate(date.getDate() + 1);
if (day == 6) week++;
} while (date.getFullYear() == year);
if (day === 6) week++;
} while (date.getFullYear() === year);
return dates;
},
@ -34,16 +34,16 @@ var calendar = {
month = date.getMonth();
do {
day = date.getDay();
if (day == 6) week++;
if (day === 6) week++;
date.setDate(date.getDate() + 1);
} while (date.getMonth() == month);
} while (date.getMonth() === month);
months.push({
firstDay: firstDay,
firstWeek: firstWeek,
lastDay: day,
lastWeek: day == 6 ? week - 1 : week
lastWeek: day === 6 ? week - 1 : week
});
} while (date.getFullYear() == year);
} while (date.getFullYear() === year);
return months;
}

Просмотреть файл

@ -10,48 +10,71 @@ body {
font: 10px sans-serif;
}
rect {
fill: steelblue;
stroke: white;
}
line {
stroke: black;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<script type="text/javascript">
// Generate an Irwin-Hall distribution.
var n = 10000, // number of trials
m = 10, // number of random variables
data = [];
// Generate an Irwin-Hall distribution.
for (var i = 0; i < n; i++) {
var s = 0;
for (var j = 0; j < m; j++) {
for (var s = 0, j = 0; j < m; j++) {
s += Math.random();
}
data.push(s);
}
var w = 400,
h = 400,
x = d3.scale.linear().domain([0, m]).range([0, w]);
bins = d3.layout.histogram().ticks(x.ticks(20))(data),
max = d3.max(bins, function(d) { return d.y; }),
y = d3.scale.linear().domain([0, max]).range([0, h]);
h = 400;
var vis = d3.select("body")
.append("svg:svg")
var histogram = d3.layout.histogram()
(data);
var x = d3.scale.ordinal()
.domain(histogram.map(function(d) { return d.x; }))
.rangeRoundBands([0, w]);
var y = d3.scale.linear()
.domain([0, d3.max(histogram, function(d) { return d.y; })])
.range([0, h]);
var vis = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h);
.attr("height", h)
.append("svg:g")
.attr("transform", "translate(.5)");
var bars = vis.selectAll("g.bar")
.data(bins)
.enter().append("svg:g")
.attr("class", "bar")
.attr("transform", function(d, i) {
return "translate(" + x(d.x) + "," + (h - y(d.y)) + ")";
});
bars.append("svg:rect")
.attr("fill", "steelblue")
.attr("width", function(d) { return x(d.dx) - 1; })
vis.selectAll("rect")
.data(histogram)
.enter().append("svg:rect")
.attr("transform", function(d) { return "translate(" + x(d.x) + "," + (h - y(d.y)) + ")"; })
.attr("width", x.rangeBand())
.attr("y", function(d) { return y(d.y); })
.attr("height", 0)
.transition()
.duration(750)
.attr("y", 0)
.attr("height", function(d) { return y(d.y); });
vis.append("svg:line")
.attr("x1", 0)
.attr("x2", w)
.attr("y1", h)
.attr("y2", h);
</script>
</body>
</html>

Просмотреть файл

@ -39,9 +39,12 @@ d3.select("#interpolate")
"step-before",
"step-after",
"basis",
"basis-open",
"basis-closed",
"cardinal",
"cardinal-closed"
"cardinal-open",
"cardinal-closed",
"monotone"
])
.enter().append("option")
.attr("value", String)

65
examples/touch/touch.html Normal file
Просмотреть файл

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1,maximum-scale=1"/>
<script type="text/javascript" src="../../d3.js"></script>
<style type="text/css">
html, body {
height: 100%;
}
body {
margin: 0;
}
svg {
display: block;
overflow: hidden;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script type="text/javascript">
var color = d3.scale.category10();
var svg = d3.select("body").append("svg:svg");
d3.select("body")
.on("touchstart", touch)
.on("touchmove", touch)
.on("touchend", touch);
function touch() {
d3.event.preventDefault();
var circle = svg.selectAll("circle.touch")
.data(d3.svg.touches(svg.node()), function(d) { return d.identifier; })
.attr("cx", function(d) { return d[0]; })
.attr("cy", function(d) { return d[1]; });
circle.enter().append("svg:circle")
.attr("class", "touch")
.attr("cx", function(d) { return d[0]; })
.attr("cy", function(d) { return d[1]; })
.style("fill", function(d) { return color(d.identifier); })
.attr("r", 1e-6)
.transition()
.duration(500)
.ease("elastic")
.attr("r", 48);
circle.exit()
.attr("class", null)
.transition()
.attr("r", 1e-6)
.remove();
}
</script>
</body>
</html>

Просмотреть файл

@ -68,7 +68,7 @@ d3.behavior.zoom = function() {
}
// adjust zoom level
if (e.type == "dblclick") {
if (e.type === "dblclick") {
z = e.shiftKey ? Math.ceil(z - 1) : Math.floor(z + 1);
} else {
var delta = (e.wheelDelta / 120 || -e.detail) * .1;
@ -79,7 +79,7 @@ d3.behavior.zoom = function() {
if ((since > 9) && (Math.abs(e.wheelDelta) / since >= 50)) bug40441 = 1;
bug40441Last = now;
}
if (bug40441 == 1) delta *= .03;
if (bug40441 === 1) delta *= .03;
z += delta;
}

Просмотреть файл

@ -230,6 +230,7 @@ d3.chart.box = function() {
.style("opacity", 1e-6)
.remove();
});
d3.timer.flush();
}
box.width = function(x) {

Просмотреть файл

@ -159,6 +159,7 @@ d3.chart.bullet = function() {
.attr("opacity", 1e-6)
.remove();
});
d3.timer.flush();
}
// left, right, top, bottom

38
src/core/bisect.js Normal file
Просмотреть файл

@ -0,0 +1,38 @@
// Locate the insertion point for x in a to maintain sorted order. The
// arguments lo and hi may be used to specify a subset of the array which should
// be considered; by default the entire array is used. If x is already present
// in a, the insertion point will be before (to the left of) any existing
// entries. The return value is suitable for use as the first argument to
// `array.splice` assuming that a is already sorted.
//
// The returned insertion point i partitions the array a into two halves so that
// all v < x for v in a[lo:i] for the left side and all v >= x for v in a[i:hi]
// for the right side.
d3.bisectLeft = function(a, x, lo, hi) {
if (arguments.length < 3) lo = 0;
if (arguments.length < 4) hi = a.length;
while (lo < hi) {
var mid = (lo + hi) >> 1;
if (a[mid] < x) lo = mid + 1;
else hi = mid;
}
return lo;
};
// Similar to bisectLeft, but returns an insertion point which comes after (to
// the right of) any existing entries of x in a.
//
// The returned insertion point i partitions the array into two halves so that
// all v <= x for v in a[lo:i] for the left side and all v > x for v in a[i:hi]
// for the right side.
d3.bisect =
d3.bisectRight = function(a, x, lo, hi) {
if (arguments.length < 3) lo = 0;
if (arguments.length < 4) hi = a.length;
while (lo < hi) {
var mid = (lo + hi) >> 1;
if (x < a[mid]) hi = mid;
else lo = mid + 1;
}
return lo;
};

Просмотреть файл

@ -1 +1 @@
d3 = {version: "1.14.2"}; // semver
d3 = {version: "1.17.0"}; // semver

Просмотреть файл

@ -1,4 +1,4 @@
// TODO align, type
// TODO align
d3.format = function(specifier) {
var match = d3_format_re.exec(specifier),
fill = match[1] || " ",
@ -7,23 +7,35 @@ d3.format = function(specifier) {
width = +match[6],
comma = match[7],
precision = match[8],
type = match[9];
type = match[9],
percentage = false,
integer = false;
if (precision) precision = precision.substring(1);
if (zfill) {
fill = "0"; // TODO align = "=";
if (comma) width -= Math.floor((width - 1) / 4);
}
if (type == "d") precision = "0";
switch (type) {
case "n": comma = true; type = "g"; break;
case "%": percentage = true; type = "f"; break;
case "p": percentage = true; type = "r"; break;
case "d": integer = true; precision = "0"; break;
}
type = d3_format_types[type] || d3_format_typeDefault;
return function(value) {
var number = +value,
var number = percentage ? value * 100 : +value,
negative = (number < 0) && (number = -number) ? "\u2212" : sign;
// Return the empty string for floats formatted as ints.
if ((type == "d") && (number % 1)) return "";
if (integer && (number % 1)) return "";
// Convert the input value to the desired precision.
if (precision) value = number.toFixed(precision);
else value = "" + number;
value = type(number, precision);
// If the fill character is 0, the sign and group is applied after the fill.
if (zfill) {
@ -40,6 +52,7 @@ d3.format = function(specifier) {
var length = value.length;
if (length < width) value = new Array(width - length + 1).join(fill) + value;
}
if (percentage) value += "%";
return value;
};
@ -48,6 +61,20 @@ d3.format = function(specifier) {
// [[fill]align][sign][#][0][width][,][.precision][type]
var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/;
var d3_format_types = {
g: function(x, p) { return x.toPrecision(p); },
e: function(x, p) { return x.toExponential(p); },
f: function(x, p) { return x.toFixed(p); },
r: function(x, p) {
var n = 1 + Math.floor(1e-15 + Math.log(x) / Math.LN10);
return d3.round(x, p - n).toFixed(Math.max(0, p - n));
}
};
function d3_format_typeDefault(x) {
return x + "";
}
// Apply comma grouping for thousands.
function d3_format_group(value) {
var i = value.lastIndexOf("."),

Просмотреть файл

@ -1,3 +1,3 @@
d3.functor = function(v) {
return typeof v == "function" ? v : function() { return v; };
return typeof v === "function" ? v : function() { return v; };
};

Просмотреть файл

@ -1,22 +1,37 @@
/**
* @param {number=} s
* @param {number=} l
*/
d3.hsl = function(h, s, l) {
return arguments.length == 1
return arguments.length === 1
? d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl)
: d3_hsl(+h, +s, +l);
};
function d3_hsl(h, s, l) {
return {h: h, s: s, l: l, toString: d3_hsl_format};
return new d3_Hsl(h, s, l);
}
/** @this d3_hsl */
function d3_hsl_format() {
return "hsl(" + this.h + "," + this.s * 100 + "%," + this.l * 100 + "%)";
function d3_Hsl(h, s, l) {
this.h = h;
this.s = s;
this.l = l;
}
d3_Hsl.prototype.brighter = function(k) {
k = Math.pow(0.7, arguments.length ? k : 1);
return d3_hsl(this.h, this.s, this.l / k);
};
d3_Hsl.prototype.darker = function(k) {
k = Math.pow(0.7, arguments.length ? k : 1);
return d3_hsl(this.h, this.s, k * this.l);
};
d3_Hsl.prototype.rgb = function() {
return d3_hsl_rgb(this.h, this.s, this.l);
};
d3_Hsl.prototype.toString = function() {
return "hsl(" + this.h + "," + this.s * 100 + "%," + this.l * 100 + "%)";
};
function d3_hsl_rgb(h, s, l) {
var m1,
m2;

Просмотреть файл

@ -1,6 +1,6 @@
d3.interpolate = function(a, b) {
if (typeof b == "number") return d3.interpolateNumber(+a, b);
if (typeof b == "string") {
if (typeof b === "number") return d3.interpolateNumber(+a, b);
if (typeof b === "string") {
return (b in d3_rgb_names) || /^(#|rgb\(|hsl\()/.test(b)
? d3.interpolateRgb(String(a), b)
: d3.interpolateString(String(a), b);
@ -86,7 +86,7 @@ d3.interpolateString = function(a, b) {
}
// Special optimization for only a single match.
if (s.length == 1) {
if (s.length === 1) {
return s[0] == null ? q[0].x : function() { return b; };
}

Просмотреть файл

@ -3,7 +3,7 @@ d3.max = function(array, f) {
n = array.length,
a = array[0],
b;
if (arguments.length == 1) {
if (arguments.length === 1) {
while (++i < n) if (a < (b = array[i])) a = b;
} else {
a = f(a);

Просмотреть файл

@ -3,7 +3,7 @@ d3.min = function(array, f) {
n = array.length,
a = array[0],
b;
if (arguments.length == 1) {
if (arguments.length === 1) {
while (++i < n) if (a > (b = array[i])) a = b;
} else {
a = f(array[0]);

7
src/core/permute.js Normal file
Просмотреть файл

@ -0,0 +1,7 @@
d3.permute = function(array, indexes) {
var permutes = [],
i = -1,
n = indexes.length;
while (++i < n) permutes[i] = array[indexes[i]];
return permutes;
};

Просмотреть файл

@ -4,7 +4,7 @@
* @param {number=} step
*/
d3.range = function(start, stop, step) {
if (arguments.length == 1) { stop = start; start = 0; }
if (arguments.length === 1) { stop = start; start = 0; }
if (step == null) step = 1;
if ((stop - start) / step == Infinity) throw new Error("infinite range");
var range = [],

Просмотреть файл

@ -1,22 +1,51 @@
/**
* @param {number=} g
* @param {number=} b
*/
d3.rgb = function(r, g, b) {
return arguments.length == 1
return arguments.length === 1
? d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb)
: d3_rgb(~~r, ~~g, ~~b);
};
function d3_rgb(r, g, b) {
return {r: r, g: g, b: b, toString: d3_rgb_format};
return new d3_Rgb(r, g, b);
}
/** @this d3_rgb */
function d3_rgb_format() {
return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);
function d3_Rgb(r, g, b) {
this.r = r;
this.g = g;
this.b = b;
}
d3_Rgb.prototype.brighter = function(k) {
k = Math.pow(0.7, arguments.length ? k : 1);
var r = this.r,
g = this.g,
b = this.b,
i = 30;
if (!r && !g && !b) return d3_rgb(i, i, i);
if (r && r < i) r = i;
if (g && g < i) g = i;
if (b && b < i) b = i;
return d3_rgb(
Math.min(255, Math.floor(r / k)),
Math.min(255, Math.floor(g / k)),
Math.min(255, Math.floor(b / k)));
};
d3_Rgb.prototype.darker = function(k) {
k = Math.pow(0.7, arguments.length ? k : 1);
return d3_rgb(
Math.max(0, Math.floor(k * this.r)),
Math.max(0, Math.floor(k * this.g)),
Math.max(0, Math.floor(k * this.b)));
};
d3_Rgb.prototype.hsl = function() {
return d3_rgb_hsl(this.r, this.g, this.b);
};
d3_Rgb.prototype.toString = function() {
return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b);
};
function d3_rgb_hex(v) {
return v < 0x10 ? "0" + v.toString(16) : v.toString(16);
}
@ -55,12 +84,12 @@ function d3_rgb_parse(format, rgb, hsl) {
if (name = d3_rgb_names[format]) return rgb(name.r, name.g, name.b);
/* Hexadecimal colors: #rgb and #rrggbb. */
if (format != null && format.charAt(0) == "#") {
if (format.length == 4) {
if (format != null && format.charAt(0) === "#") {
if (format.length === 4) {
r = format.charAt(1); r += r;
g = format.charAt(2); g += g;
b = format.charAt(3); b += b;
} else if (format.length == 7) {
} else if (format.length === 7) {
r = format.substring(1, 3);
g = format.substring(3, 5);
b = format.substring(5, 7);
@ -94,7 +123,7 @@ function d3_rgb_hsl(r, g, b) {
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;
return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
}
var d3_rgb_names = {

5
src/core/round.js Normal file
Просмотреть файл

@ -0,0 +1,5 @@
d3.round = function(x, n) {
return n
? Math.round(x * Math.pow(10, n)) * Math.pow(10, -n)
: Math.round(x);
};

Просмотреть файл

@ -2,7 +2,7 @@ var d3_select = function(s, n) { return n.querySelector(s); },
d3_selectAll = function(s, n) { return d3_array(n.querySelectorAll(s)); };
// Use Sizzle, if available.
if (typeof Sizzle == "function") {
if (typeof Sizzle === "function") {
d3_select = function(s, n) { return Sizzle(s, n)[0]; };
d3_selectAll = function(s, n) { return Sizzle.uniqueSort(Sizzle(s, n)); };
}
@ -12,13 +12,13 @@ d3_root[0].parentNode = document.documentElement;
// TODO fast singleton implementation!
d3.select = function(selector) {
return typeof selector == "string"
return typeof selector === "string"
? d3_root.select(selector)
: d3_selection([[selector]]); // assume node
};
d3.selectAll = function(selector) {
return typeof selector == "string"
return typeof selector === "string"
? d3_root.selectAll(selector)
: d3_selection([d3_array(selector)]); // assume node[]
};
@ -197,7 +197,7 @@ function d3_selection(groups) {
var i = -1,
n = groups.length,
group;
if (typeof data == "function") {
if (typeof data === "function") {
while (++i < n) {
bind(group = groups[i], data.call(group, group.parentNode.__data__, i));
}
@ -294,7 +294,7 @@ function d3_selection(groups) {
}
return groups.each(value == null
? (name.local ? attrNullNS : attrNull) : (typeof value == "function"
? (name.local ? attrNullNS : attrNull) : (typeof value === "function"
? (name.local ? attrFunctionNS : attrFunction)
: (name.local ? attrConstantNS : attrConstant)));
};
@ -305,24 +305,36 @@ function d3_selection(groups) {
// If no value is specified, return the first value.
if (arguments.length < 2) {
return first(function() {
if (c = this.classList) return c.contains(name);
var c = this.className;
re.lastIndex = 0;
return re.test(this.className);
return re.test(c.baseVal != null ? c.baseVal : c);
});
}
/** @this {Element} */
function classedAdd() {
var classes = this.className;
if (c = this.classList) return c.add(name);
var c = this.className,
cb = c.baseVal != null,
cv = cb ? c.baseVal : c;
re.lastIndex = 0;
if (!re.test(classes)) {
this.className = d3_collapse(classes + " " + name);
if (!re.test(cv)) {
cv = d3_collapse(cv + " " + name);
if (cb) c.baseVal = cv;
else this.className = cv;
}
}
/** @this {Element} */
function classedRemove() {
var classes = d3_collapse(this.className.replace(re, " "));
this.className = classes.length ? classes : null;
if (c = this.classList) return c.remove(name);
var c = this.className,
cb = c.baseVal != null,
cv = cb ? c.baseVal : c;
cv = d3_collapse(cv.replace(re, " "));
if (cb) c.baseVal = cv;
else this.className = cv;
}
/** @this {Element} */
@ -332,7 +344,7 @@ function d3_selection(groups) {
: classedRemove).call(this);
}
return groups.each(typeof value == "function"
return groups.each(typeof value === "function"
? classedFunction : value
? classedAdd
: classedRemove);
@ -366,7 +378,7 @@ function d3_selection(groups) {
}
return groups.each(value == null
? styleNull : (typeof value == "function"
? styleNull : (typeof value === "function"
? styleFunction : styleConstant));
};
@ -398,7 +410,7 @@ function d3_selection(groups) {
}
return groups.each(value == null
? propertyNull : (typeof value == "function"
? propertyNull : (typeof value === "function"
? propertyFunction : propertyConstant));
};
@ -421,7 +433,7 @@ function d3_selection(groups) {
this.textContent = value.apply(this, arguments);
}
return groups.each(typeof value == "function"
return groups.each(typeof value === "function"
? textFunction : textConstant);
};
@ -444,7 +456,7 @@ function d3_selection(groups) {
this.innerHTML = value.apply(this, arguments);
}
return groups.each(typeof value == "function"
return groups.each(typeof value === "function"
? htmlFunction : htmlConstant);
};
@ -518,7 +530,7 @@ function d3_selection(groups) {
// parse the type specifier
var i = type.indexOf("."),
typo = i == -1 ? type : type.substring(0, i),
typo = i === -1 ? type : type.substring(0, i),
name = "__on" + type;
// remove the old event listener, and add the new event listener
@ -526,12 +538,13 @@ function d3_selection(groups) {
if (this[name]) this.removeEventListener(typo, this[name], capture);
if (listener) this.addEventListener(typo, this[name] = l, capture);
// wrapped event listener that preserves d, i
// wrapped event listener that preserves i
var node = this;
function l(e) {
var o = d3.event; // Events can be reentrant (e.g., focus).
d3.event = e;
try {
listener.call(this, d, i);
listener.call(this, node.__data__, i);
} finally {
d3.event = o;
}

7
src/core/sum.js Normal file
Просмотреть файл

@ -0,0 +1,7 @@
d3.sum = function(x) {
var s = 0,
n = x.length,
i = -1;
while (++i < n) s += x[i];
return s;
};

Просмотреть файл

@ -46,13 +46,12 @@ function d3_timer(callback, delay) {
function d3_timer_step() {
var elapsed,
now = Date.now(),
t0 = null,
t1 = d3_timer_queue;
while (t1) {
elapsed = now - t1.then;
if (elapsed > t1.delay) t1.flush = t1.callback(elapsed);
t1 = (t0 = t1).next;
t1 = t1.next;
}
var delay = d3_timer_flush() - now;
@ -68,6 +67,20 @@ function d3_timer_step() {
}
}
d3.timer.flush = function() {
var elapsed,
now = Date.now(),
t1 = d3_timer_queue;
while (t1) {
elapsed = now - t1.then;
if (!t1.delay) t1.flush = t1.callback(elapsed);
t1 = t1.next;
}
d3_timer_flush();
};
// Flush after callbacks, to avoid concurrent queue modification.
function d3_timer_flush() {
var t0 = null,

Просмотреть файл

@ -47,7 +47,7 @@ function d3_transition(groups) {
var clear = true,
k = -1;
groups.each(function() {
if (stage[++k] == 2) return; // ended
if (stage[++k] === 2) return; // ended
var t = (elapsed - delay[k]) / duration[k],
tx = this.__transition__,
te, // ease(t)
@ -67,7 +67,7 @@ function d3_transition(groups) {
// 1 - In progress.
// 2 - Ended.
if (stage[k]) {
if (!tx || tx.active != transitionId) {
if (!tx || tx.active !== transitionId) {
stage[k] = 2;
return;
}
@ -91,11 +91,11 @@ function d3_transition(groups) {
for (tk in ik) ik[tk].call(this, te);
// Handle ending transitions.
if (t == 1) {
if (t === 1) {
stage[k] = 2;
if (tx.active == transitionId) {
if (tx.active === transitionId) {
var owner = tx.owner;
if (owner == transitionId) {
if (owner === transitionId) {
delete this.__transition__;
if (remove) this.parentNode.removeChild(this);
}
@ -112,7 +112,7 @@ function d3_transition(groups) {
transition.delay = function(value) {
var delayMin = Infinity,
k = -1;
if (typeof value == "function") {
if (typeof value === "function") {
groups.each(function(d, i) {
var x = delay[++k] = +value.apply(this, arguments);
if (x < delayMin) delayMin = x;
@ -129,7 +129,7 @@ function d3_transition(groups) {
transition.duration = function(value) {
var k = -1;
if (typeof value == "function") {
if (typeof value === "function") {
durationMax = 0;
groups.each(function(d, i) {
var x = duration[++k] = +value.apply(this, arguments);
@ -145,7 +145,7 @@ function d3_transition(groups) {
};
transition.ease = function(value) {
ease = typeof value == "function" ? value : d3.ease.apply(d3, arguments);
ease = typeof value === "function" ? value : d3.ease.apply(d3, arguments);
return transition;
};
@ -197,7 +197,7 @@ function d3_transition(groups) {
transition.text = function(value) {
tweens.text = function(d, i) {
this.textContent = typeof value == "function"
this.textContent = typeof value === "function"
? value.call(this, d, i)
: value;
};
@ -234,7 +234,7 @@ function d3_transition(groups) {
}
function d3_transitionTween(b) {
return typeof b == "function"
return typeof b === "function"
? function(d, i, a) { return d3.interpolate(a, String(b.call(this, d, i))); }
: (b = String(b), function(d, i, a) { return d3.interpolate(a, b); });
}

Просмотреть файл

@ -0,0 +1,9 @@
function d3_uninterpolateNumber(a, b) {
b = 1 / (b - (a = +a));
return function(x) { return (x - a) * b; };
}
function d3_uninterpolateClamp(a, b) {
b = 1 / (b - (a = +a));
return function(x) { return Math.max(0, Math.min(1, (x - a) * b)); };
}

Просмотреть файл

@ -4,7 +4,7 @@ d3.xhr = function(url, mime, callback) {
else if (mime && req.overrideMimeType) req.overrideMimeType(mime);
req.open("GET", url, true);
req.onreadystatechange = function() {
if (req.readyState == 4) callback(req.status < 300 ? req : null);
if (req.readyState === 4) callback(req.status < 300 ? req : null);
};
req.send(null);
};

Просмотреть файл

@ -25,25 +25,25 @@ d3.csv.parseRows = function(text, f) {
/** @private Returns the next token. */
function token() {
if (re.lastIndex == text.length) return EOF; // special case: end of file
if (re.lastIndex === text.length) return EOF; // special case: end of file
if (eol) { eol = false; return EOL; } // special case: end of line
// special case: quotes
var j = re.lastIndex;
if (text.charCodeAt(j) == 34) {
if (text.charCodeAt(j) === 34) {
var i = j;
while (i++ < text.length) {
if (text.charCodeAt(i) == 34) {
if (text.charCodeAt(i + 1) != 34) break;
if (text.charCodeAt(i) === 34) {
if (text.charCodeAt(i + 1) !== 34) break;
i++;
}
}
re.lastIndex = i + 2;
var c = text.charCodeAt(i + 1);
if (c == 13) {
if (c === 13) {
eol = true;
if (text.charCodeAt(i + 2) == 10) re.lastIndex++;
} else if (c == 10) {
if (text.charCodeAt(i + 2) === 10) re.lastIndex++;
} else if (c === 10) {
eol = true;
}
return text.substring(j + 1, i).replace(/""/g, "\"");
@ -52,7 +52,7 @@ d3.csv.parseRows = function(text, f) {
// common case
var m = re.exec(text);
if (m) {
eol = m[0].charCodeAt(0) != 44;
eol = m[0].charCodeAt(0) !== 44;
return text.substring(j, m.index);
}
re.lastIndex = text.length;

Просмотреть файл

@ -11,7 +11,7 @@ d3.geo.path = function() {
projection = d3.geo.albersUsa();
function path(d, i) {
if (typeof pointRadius == "function") {
if (typeof pointRadius === "function") {
pointCircle = d3_path_circle(pointRadius.apply(this, arguments));
}
return d3_geo_pathType(pathTypes, d);
@ -262,7 +262,7 @@ d3.geo.path = function() {
};
path.pointRadius = function(x) {
if (typeof x == "function") pointRadius = x;
if (typeof x === "function") pointRadius = x;
else {
pointRadius = +x;
pointCircle = d3_path_circle(pointRadius);

Просмотреть файл

@ -28,12 +28,12 @@ d3.geom.contour = function(grid, start) {
if (grid(x, y )) i += 8;
// determine next direction
if (i == 6) {
dx = pdy == -1 ? -1 : 1;
if (i === 6) {
dx = pdy === -1 ? -1 : 1;
dy = 0;
} else if (i == 9) {
} else if (i === 9) {
dx = 0;
dy = pdx == 1 ? -1 : 1;
dy = pdx === 1 ? -1 : 1;
} else {
dx = d3_geom_contourDx[i];
dy = d3_geom_contourDy[i];
@ -67,7 +67,7 @@ function d3_geom_contourStart(grid) {
if (grid(x,y)) {
return [x,y];
}
if (x == 0) {
if (x === 0) {
x = y + 1;
y = 0;
} else {

Просмотреть файл

@ -27,7 +27,7 @@ d3.geom.hull = function(vertices) {
// calculate polar angles from ref point and sort
for (i=0; i<len; ++i) {
if (i == h) continue;
if (i === h) continue;
y1 = vertices[i][1] - vertices[h][1];
x1 = vertices[i][0] - vertices[h][0];
points.push({angle: Math.atan2(y1, x1), index: i});
@ -64,7 +64,7 @@ d3.geom.hull = function(vertices) {
// initialize the stack
stack.push(h);
for (i=0, j=0; i<2; ++j) {
if (points[j].index != -1) {
if (points[j].index !== -1) {
stack.push(points[j].index);
i++;
}
@ -73,7 +73,7 @@ d3.geom.hull = function(vertices) {
// do graham's scan
for (; j<plen; ++j) {
if (points[j].index == -1) continue; // skip tossed out points
if (points[j].index === -1) continue; // skip tossed out points
while (!d3_geom_hullCCW(stack[sp-2], stack[sp-1], points[j].index, vertices)) {
--sp;
}

Просмотреть файл

@ -18,14 +18,14 @@ d3.geom.voronoi = function(vertices) {
x2,
y1,
y2;
if (e.a == 1 && e.b >= 0) {
if (e.a === 1 && e.b >= 0) {
s1 = e.ep.r;
s2 = e.ep.l;
} else {
s1 = e.ep.l;
s2 = e.ep.r;
}
if (e.a == 1) {
if (e.a === 1) {
y1 = s1 ? s1.y : -1e6;
x1 = e.c - e.b * y1;
y2 = s2 ? s2.y : 1e6;
@ -200,8 +200,8 @@ function d3_voronoi_tessellate(vertices, callback) {
e = e2;
}
var rightOfSite = (xint >= e.region.r.x);
if ((rightOfSite && (el.side == "l")) ||
(!rightOfSite && (el.side == "r"))) {
if ((rightOfSite && (el.side === "l")) ||
(!rightOfSite && (el.side === "r"))) {
return null;
}
return {
@ -215,13 +215,13 @@ function d3_voronoi_tessellate(vertices, callback) {
topsite = e.region.r,
rightOfSite = (p.x > topsite.x);
if (rightOfSite && (he.side == "l")) {
if (rightOfSite && (he.side === "l")) {
return 1;
}
if (!rightOfSite && (he.side == "r")) {
if (!rightOfSite && (he.side === "r")) {
return 0;
}
if (e.a == 1) {
if (e.a === 1) {
var dyp = p.y - topsite.y,
dxp = p.x - topsite.x,
fast = 0,
@ -256,7 +256,7 @@ function d3_voronoi_tessellate(vertices, callback) {
above = (t1 * t1) > (t2 * t2 + t3 * t3);
}
return he.side == "l" ? above : !above;
return he.side === "l" ? above : !above;
},
endPoint: function(edge, side, site) {
@ -296,7 +296,7 @@ function d3_voronoi_tessellate(vertices, callback) {
ls.splice(i, 1);
},
empty: function() { return EventQueue.list.length == 0; },
empty: function() { return EventQueue.list.length === 0; },
nextEvent: function(he) {
for (var i=0, ls=EventQueue.list, l=ls.length; i<l; ++i) {

Просмотреть файл

@ -1,79 +1,102 @@
d3.layout.histogram = function() {
var frequency = true,
value = Number,
ticksFunction = d3_layout_histogramTicks;
valuer = Number,
ranger = d3_layout_histogramRange,
binner = d3_layout_histogramBinSturges;
function histogram(data, i) {
var x = data.map(value), bins = [];
// Initialize default ticks.
var ticks = ticksFunction.call(this, data, i);
var bins = [],
values = data.map(valuer, this),
range = ranger.call(this, values, i),
thresholds = binner.call(this, range, values, i),
bin,
i = -1,
n = values.length,
m = thresholds.length - 1,
k = frequency ? 1 / n : 1,
x;
// Initialize the bins.
for (var i = 0; i < ticks.length - 1; i++) {
var bin = bins[i] = [];
bin.x = ticks[i];
bin.dx = ticks[i + 1] - ticks[i];
while (++i < m) {
bin = bins[i] = [];
bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]);
bin.y = 0;
}
// Count the number of samples per bin.
for (var i = 0; i < x.length; i++) {
var j = d3_layout_histogramSearchIndex(ticks, x[i]) - 1,
bin = bins[Math.max(0, Math.min(bins.length - 1, j))];
bin.y++;
// Fill the bins, ignoring values outside the range.
i = -1; while(++i < n) {
x = values[i];
if ((x >= range[0]) && (x <= range[1])) {
bin = bins[d3.bisect(thresholds, x, 1, m) - 1];
bin.y += k;
bin.push(data[i]);
}
// Convert frequencies to probabilities.
if (!frequency) for (var i = 0; i < bins.length; i++) {
bins[i].y /= x.length;
}
return bins;
}
// Specifies how to extract a value from the associated data. The default
// value function is `Number`, which is equivalent to the identity function.
histogram.value = function(x) {
if (!arguments.length) return valuer;
valuer = x;
return histogram;
};
// Specifies the range of the histogram. Values outside the specified range
// will be ignored. The argument `x` may be specified either as a two-element
// array representing the minimum and maximum value of the range, or as a
// function that returns the range given the array of values and the current
// index `i`. The default range is the extent (minimum and maximum) of the
// values.
histogram.range = function(x) {
if (!arguments.length) return ranger;
ranger = d3.functor(x);
return histogram;
};
// Specifies how to bin values in the histogram. The argument `x` may be
// specified as a number, in which case the range of values will be split
// uniformly into the given number of bins. Or, `x` may be an array of
// threshold values, defining the bins; the specified array must contain the
// rightmost (upper) value, thus specifying n + 1 values for n bins. Or, `x`
// may be a function which is evaluated, being passed the range, the array of
// values, and the current index `i`, returning an array of thresholds. The
// default bin function will divide the values into uniform bins using
// Sturges' formula.
histogram.bins = function(x) {
if (!arguments.length) return binner;
binner = typeof x === "number"
? function(range) { return d3_layout_histogramBinFixed(range, x); }
: d3.functor(x);
return histogram;
};
// Specifies whether the histogram's `y` value is a count (frequency) or a
// probability (density). The default value is true.
histogram.frequency = function(x) {
if (!arguments.length) return frequency;
frequency = Boolean(x);
return histogram;
};
histogram.ticks = function(x) {
if (!arguments.length) return ticksFunction;
ticksFunction = d3.functor(x);
return histogram;
};
histogram.value = function(x) {
if (!arguments.length) return value;
value = x;
frequency = !!x;
return histogram;
};
return histogram;
};
// Performs a binary search on a sorted array.
// Returns the index of the value if found, otherwise -(insertion point) - 1.
// The insertion point is the index at which value should be inserted into the
// array for the array to remain sorted.
function d3_layout_histogramSearch(array, value) {
var low = 0, high = array.length - 1;
while (low <= high) {
var mid = (low + high) >> 1, midValue = array[mid];
if (midValue < value) low = mid + 1;
else if (midValue > value) high = mid - 1;
else return mid;
}
return -low - 1;
function d3_layout_histogramBinSturges(range, values) {
return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1));
}
function d3_layout_histogramSearchIndex(array, value) {
var i = d3_layout_histogramSearch(array, value);
return (i < 0) ? (-i - 1) : i;
function d3_layout_histogramBinFixed(range, n) {
var x = -1,
b = +range[0],
m = (range[1] - b) / n,
f = [];
while (++x <= n) f[x] = m * x + b;
return f;
}
function d3_layout_histogramTicks(x) {
return d3.scale.linear().domain(x).ticks(10);
function d3_layout_histogramRange(values) {
return [d3.min(values), d3.max(values)];
}

Просмотреть файл

@ -104,14 +104,14 @@ function d3_layout_packCircle(nodes) {
// Search for the closest intersection.
var isect = 0, s1 = 1, s2 = 1;
for (j = b._pack_next; j != b; j = j._pack_next, s1++) {
for (j = b._pack_next; j !== b; j = j._pack_next, s1++) {
if (d3_layout_packIntersects(j, c)) {
isect = 1;
break;
}
}
if (isect == 1) {
for (k = a._pack_prev; k != j._pack_prev; k = k._pack_prev, s2++) {
for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) {
if (d3_layout_packIntersects(k, c)) {
if (s2 < s1) {
isect = -1;

Просмотреть файл

@ -7,12 +7,12 @@ d3.layout.pie = function() {
function pie(data, i) {
// Compute the start angle.
var a = +(typeof startAngle == "function"
var a = +(typeof startAngle === "function"
? startAngle.apply(this, arguments)
: startAngle);
// Compute the angular range (end - start).
var k = (typeof endAngle == "function"
var k = (typeof endAngle === "function"
? endAngle.apply(this, arguments)
: endAngle) - startAngle;

Просмотреть файл

@ -1,47 +1,102 @@
// data is two-dimensional array of x,y; we populate y0
// TODO perhaps make the `x`, `y` and `y0` structure customizable
d3.layout.stack = function() {
var order = "default",
offset = "zero";
var values = Object,
order = d3_layout_stackOrders["default"],
offset = d3_layout_stackOffsets["zero"],
out = d3_layout_stackOut,
x = d3_layout_stackX,
y = d3_layout_stackY;
function stack(data) {
var n = data.length,
m = data[0].length,
function stack(data, index) {
// Convert series to canonical two-dimensional representation.
var series = data.map(function(d, i) {
return values.call(stack, d, i);
});
// Convert each series to canonical [[x,y]] representation.
var points = series.map(function(d, i) {
return d.map(function(v, i) {
return [x.call(stack, v, i), y.call(stack, v, i)];
});
});
// Compute the order of series, and permute them.
var orders = order.call(stack, points, index);
series = d3.permute(series, orders);
points = d3.permute(points, orders);
// Compute the baseline…
var offsets = offset.call(stack, points, index);
// And propagate it to other series.
var n = series.length,
m = series[0].length,
i,
j,
y0;
// compute the order of series
var index = d3_layout_stackOrders[order](data);
// set y0 on the baseline
d3_layout_stackOffsets[offset](data, index);
// propagate offset to other series
o;
for (j = 0; j < m; ++j) {
for (i = 1, y0 = data[index[0]][j].y0; i < n; ++i) {
data[index[i]][j].y0 = y0 += data[index[i - 1]][j].y;
out.call(stack, series[0][j], o = offsets[j], points[0][j][1]);
for (i = 1; i < n; ++i) {
out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]);
}
}
return data;
}
stack.values = function(x) {
if (!arguments.length) return values;
values = x;
return stack;
};
stack.order = function(x) {
if (!arguments.length) return order;
order = x;
order = typeof x === "function" ? x : d3_layout_stackOrders[x];
return stack;
};
stack.offset = function(x) {
if (!arguments.length) return offset;
offset = x;
offset = typeof x === "function" ? x : d3_layout_stackOffsets[x];
return stack;
};
stack.x = function(z) {
if (!arguments.length) return x;
x = z;
return stack;
};
stack.y = function(z) {
if (!arguments.length) return y;
y = z;
return stack;
};
stack.out = function(z) {
if (!arguments.length) return out;
out = z;
return stack;
};
return stack;
}
function d3_layout_stackX(d) {
return d.x;
}
function d3_layout_stackY(d) {
return d.y;
}
function d3_layout_stackOut(d, y0, y) {
d.y0 = y0;
d.y = y;
}
var d3_layout_stackOrders = {
"inside-out": function(data) {
@ -55,7 +110,7 @@ var d3_layout_stackOrders = {
bottom = 0,
tops = [],
bottoms = [];
for (i = 0; i < n; i++) {
for (i = 0; i < n; ++i) {
j = index[i];
if (top < bottom) {
top += sums[j];
@ -80,25 +135,27 @@ var d3_layout_stackOrders = {
var d3_layout_stackOffsets = {
"silhouette": function(data, index) {
"silhouette": function(data) {
var n = data.length,
m = data[0].length,
sums = [],
max = 0,
i,
j,
o;
o,
y0 = [];
for (j = 0; j < m; ++j) {
for (i = 0, o = 0; i < n; i++) o += data[i][j].y;
for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
if (o > max) max = o;
sums.push(o);
}
for (j = 0, i = index[0]; j < m; ++j) {
data[i][j].y0 = (max - sums[j]) / 2;
for (j = 0; j < m; ++j) {
y0[j] = (max - sums[j]) / 2;
}
return y0;
},
"wiggle": function(data, index) {
"wiggle": function(data) {
var n = data.length,
x = data[0],
m = x.length,
@ -106,51 +163,64 @@ var d3_layout_stackOffsets = {
i,
j,
k,
ii,
ik,
i0 = index[0],
s1,
s2,
s3,
dx,
o,
o0;
data[i0][0].y0 = o = o0 = 0;
o0,
y0 = [];
y0[0] = o = o0 = 0;
for (j = 1; j < m; ++j) {
for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j].y;
for (i = 0, s2 = 0, dx = x[j].x - x[j - 1].x; i < n; ++i) {
for (k = 0, ii = index[i], s3 = (data[ii][j].y - data[ii][j - 1].y) / (2 * dx); k < i; ++k) {
s3 += (data[ik = index[k]][j].y - data[ik][j - 1].y) / dx;
for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1];
for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) {
for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) {
s3 += (data[k][j][1] - data[k][j - 1][1]) / dx;
}
s2 += s3 * data[ii][j].y;
s2 += s3 * data[i][j][1];
}
data[i0][j].y0 = o -= s1 ? s2 / s1 * dx : 0;
y0[j] = o -= s1 ? s2 / s1 * dx : 0;
if (o < o0) o0 = o;
}
for (j = 0; j < m; ++j) data[i0][j].y0 -= o0;
for (j = 0; j < m; ++j) y0[j] -= o0;
return y0;
},
"zero": function(data, index) {
var j = 0,
"expand": function(data) {
var n = data.length,
m = data[0].length,
i0 = index[0];
for (; j < m; ++j) data[i0][j].y0 = 0;
k = 1 / n,
i,
j,
o,
y0 = [];
for (j = 0; j < m; ++j) {
for (i = 0, o = 0; i < n; i++) o += data[i][j][1];
if (o) for (i = 0; i < n; i++) data[i][j][1] /= o;
else for (i = 0; i < n; i++) data[i][j][1] = k;
}
for (j = 0; j < m; ++j) y0[j] = 0;
return y0;
},
"zero": function(data) {
var j = -1,
m = data[0].length,
y0 = [];
while (++j < m) y0[j] = 0;
return y0;
}
};
function d3_layout_stackReduceSum(d) {
return d.reduce(d3_layout_stackSum, 0);
}
function d3_layout_stackMaxIndex(array) {
var i = 1,
j = 0,
v = array[0].y,
v = array[0][1],
k,
n = array.length;
for (; i < n; ++i) {
if ((k = array[i].y) > v) {
if ((k = array[i][1]) > v) {
j = i;
v = k;
}
@ -158,6 +228,10 @@ function d3_layout_stackMaxIndex(array) {
return j;
}
function d3_layout_stackSum(p, d) {
return p + d.y;
function d3_layout_stackReduceSum(d) {
return d.reduce(d3_layout_stackSum, 0);
}
function d3_layout_stackSum(p, d) {
return p + d[1];
}

7
src/scale/bilinear.js Normal file
Просмотреть файл

@ -0,0 +1,7 @@
function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
var u = uninterpolate(domain[0], domain[1]),
i = interpolate(range[0], range[1]);
return function(x) {
return i(u(x));
};
}

Просмотреть файл

@ -1,40 +1,38 @@
d3.scale.linear = function() {
var x0 = 0,
x1 = 1,
y0 = 0,
y1 = 1,
kx = 1, // 1 / (x1 - x0)
ky = 1, // (x1 - x0) / (y1 - y0)
var domain = [0, 1],
range = [0, 1],
interpolate = d3.interpolate,
i = interpolate(y0, y1),
clamp = false;
clamp = false,
output,
input;
function rescale() {
var linear = domain.length == 2 ? d3_scale_bilinear : d3_scale_polylinear,
uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
output = linear(domain, range, uninterpolate, interpolate);
input = linear(range, domain, uninterpolate, d3.interpolate);
return scale;
}
function scale(x) {
x = (x - x0) * kx;
return i(clamp ? Math.max(0, Math.min(1, x)) : x);
return output(x);
}
// Note: requires range is coercible to number!
scale.invert = function(y) {
return (y - y0) * ky + x0;
return input(y);
};
scale.domain = function(x) {
if (!arguments.length) return [x0, x1];
x0 = +x[0];
x1 = +x[1];
kx = 1 / (x1 - x0);
ky = (x1 - x0) / (y1 - y0);
return scale;
if (!arguments.length) return domain;
domain = x.map(Number);
return rescale();
};
scale.range = function(x) {
if (!arguments.length) return [y0, y1];
y0 = x[0];
y1 = x[1];
ky = (x1 - x0) / (y1 - y0);
i = interpolate(y0, y1);
return scale;
if (!arguments.length) return range;
range = x;
return rescale();
};
scale.rangeRound = function(x) {
@ -44,19 +42,19 @@ d3.scale.linear = function() {
scale.clamp = function(x) {
if (!arguments.length) return clamp;
clamp = x;
return scale;
return rescale();
};
scale.interpolate = function(x) {
if (!arguments.length) return interpolate;
i = (interpolate = x)(y0, y1);
return scale;
interpolate = x;
return rescale();
};
// TODO Dates? Ugh.
function tickRange(m) {
var start = Math.min(x0, x1),
stop = Math.max(x0, x1),
var start = d3.min(domain),
stop = d3.max(domain),
span = stop - start,
step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)),
err = m / (span / step);
@ -84,5 +82,5 @@ d3.scale.linear = function() {
return d3.format(",." + n + "f");
};
return scale;
return rescale();
};

16
src/scale/polylinear.js Normal file
Просмотреть файл

@ -0,0 +1,16 @@
function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
var u = [],
i = [],
j = 0,
n = domain.length;
while (++j < n) {
u.push(uninterpolate(domain[j - 1], domain[j]));
i.push(interpolate(range[j - 1], range[j]));
}
return function(x) {
var j = d3.bisect(domain, x, 1, domain.length - 1) - 1;
return i[j](u[j](x));
};
}

Просмотреть файл

@ -4,26 +4,21 @@ d3.scale.quantile = function() {
thresholds = [];
function rescale() {
var i = -1,
n = thresholds.length = range.length,
k = domain.length / n;
while (++i < n) thresholds[i] = domain[~~(i * k)];
var k = 0,
n = domain.length,
q = range.length,
i;
thresholds.length = Math.max(0, q - 1);
while (++k < q) {
thresholds[k - 1] = (i = n * k / q) % 1
? domain[~~i]
: (domain[i = ~~i] + domain[i - 1]) / 2;
}
function quantile(value) {
if (isNaN(value = +value)) return NaN;
var low = 0, high = thresholds.length - 1;
while (low <= high) {
var mid = (low + high) >> 1, midValue = thresholds[mid];
if (midValue < value) low = mid + 1;
else if (midValue > value) high = mid - 1;
else return mid;
}
return high < 0 ? 0 : high;
}
function scale(x) {
return range[quantile(x)];
if (isNaN(x = +x)) return NaN;
return range[d3.bisect(thresholds, x)];
}
scale.domain = function(x) {

Просмотреть файл

@ -45,8 +45,8 @@ function d3_svg_linePoints(self, d, x, y) {
var points = [],
i = -1,
n = d.length,
fx = typeof x == "function",
fy = typeof y == "function",
fx = typeof x === "function",
fy = typeof y === "function",
value;
if (fx && fy) {
while (++i < n) points.push([
@ -79,9 +79,12 @@ var d3_svg_lineInterpolators = {
"step-before": d3_svg_lineStepBefore,
"step-after": d3_svg_lineStepAfter,
"basis": d3_svg_lineBasis,
"basis-open": d3_svg_lineBasisOpen,
"basis-closed": d3_svg_lineBasisClosed,
"cardinal": d3_svg_lineCardinal,
"cardinal-closed": d3_svg_lineCardinalClosed
"cardinal-open": d3_svg_lineCardinalOpen,
"cardinal-closed": d3_svg_lineCardinalClosed,
"monotone": d3_svg_lineMonotone
};
// Linear interpolation; generates "L" commands.
@ -117,6 +120,14 @@ function d3_svg_lineStepAfter(points) {
return path.join("");
}
// Open cardinal spline interpolation; generates "C" commands.
function d3_svg_lineCardinalOpen(points, tension) {
return points.length < 4
? d3_svg_lineLinear(points)
: points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1),
d3_svg_lineCardinalTangents(points, tension));
}
// Closed cardinal spline interpolation; generates "C" commands.
function d3_svg_lineCardinalClosed(points, tension) {
return points.length < 3
@ -199,7 +210,7 @@ function d3_svg_lineCardinalTangents(points, tension) {
return tangents;
}
// Open B-spline interpolation; generates "C" commands.
// B-spline interpolation; generates "C" commands.
function d3_svg_lineBasis(points) {
if (points.length < 3) return d3_svg_lineLinear(points);
var path = [],
@ -227,6 +238,31 @@ function d3_svg_lineBasis(points) {
return path.join("");
}
// Open B-spline interpolation; generates "C" commands.
function d3_svg_lineBasisOpen(points) {
if (points.length < 4) return d3_svg_lineLinear(points);
var path = [],
i = -1,
n = points.length,
pi,
px = [0],
py = [0];
while (++i < 3) {
pi = points[i];
px.push(pi[0]);
py.push(pi[1]);
}
path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px)
+ "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py));
--i; while (++i < n) {
pi = points[i];
px.shift(); px.push(pi[0]);
py.shift(); py.push(pi[1]);
d3_svg_lineBasisBezier(path, px, py);
}
return path.join("");
}
// Closed B-spline interpolation; generates "C" commands.
function d3_svg_lineBasisClosed(points) {
var path,
@ -276,3 +312,86 @@ function d3_svg_lineBasisBezier(path, x, y) {
",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x),
",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y));
}
// Computes the slope from points p0 to p1.
function d3_svg_lineSlope(p0, p1) {
return (p1[1] - p0[1]) / (p1[0] - p0[0]);
}
// Compute three-point differences for the given points.
// http://en.wikipedia.org/wiki/Cubic_Hermite_spline#Finite_difference
function d3_svg_lineFiniteDifferences(points) {
var i = 0,
j = points.length - 1,
m = [],
p0 = points[0],
p1 = points[1],
d = m[0] = d3_svg_lineSlope(p0, p1);
while (++i < j) {
m[i] = d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]));
}
m[i] = d;
return m;
}
// Interpolates the given points using Fritsch-Carlson Monotone cubic Hermite
// interpolation. Returns an array of tangent vectors. For details, see
// http://en.wikipedia.org/wiki/Monotone_cubic_interpolation
function d3_svg_lineMonotoneTangents(points) {
var tangents = [],
d,
a,
b,
s,
m = d3_svg_lineFiniteDifferences(points),
i = -1,
j = points.length - 1;
// The first two steps are done by computing finite-differences:
// 1. Compute the slopes of the secant lines between successive points.
// 2. Initialize the tangents at every point as the average of the secants.
// Then, for each segment…
while (++i < j) {
d = d3_svg_lineSlope(points[i], points[i + 1]);
// 3. If two successive yk = y{k + 1} are equal (i.e., d is zero), then set
// mk = m{k + 1} = 0 as the spline connecting these points must be flat to
// preserve monotonicity. Ignore step 4 and 5 for those k.
if (Math.abs(d) < 1e-6) {
m[i] = m[i + 1] = 0;
} else {
// 4. Let ak = mk / dk and bk = m{k + 1} / dk.
a = m[i] / d;
b = m[i + 1] / d;
// 5. Prevent overshoot and ensure monotonicity by restricting the
// magnitude of vector <ak, bk> to a circle of radius 3.
s = a * a + b * b;
if (s > 9) {
s = d * 3 / Math.sqrt(s);
m[i] = s * a;
m[i + 1] = s * b;
}
}
}
// Compute the normalized tangent vector from the slopes. Note that if x is
// not monotonic, it's possible that the slope will be infinite, so we protect
// against NaN by setting the coordinate to zero.
i = -1; while (++i <= j) {
s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0])
/ (6 * (1 + m[i] * m[i]));
tangents.push([s || 0, m[i] * s || 0]);
}
return tangents;
}
function d3_svg_lineMonotone(points) {
return points.length < 3
? d3_svg_lineLinear(points)
: points[0] +
d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points));
}

Просмотреть файл

@ -1,4 +1,11 @@
d3.svg.mouse = function(container) {
return d3_svg_mousePoint(container, d3.event);
};
// https://bugs.webkit.org/show_bug.cgi?id=44083
var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0;
function d3_svg_mousePoint(container, e) {
var point = (container.ownerSVGElement || container).createSVGPoint();
if ((d3_mouse_bug44083 < 0) && (window.scrollX || window.scrollY)) {
var svg = d3.select(document.body)
@ -11,15 +18,12 @@ d3.svg.mouse = function(container) {
svg.remove();
}
if (d3_mouse_bug44083) {
point.x = d3.event.pageX;
point.y = d3.event.pageY;
point.x = e.pageX;
point.y = e.pageY;
} else {
point.x = d3.event.clientX;
point.y = d3.event.clientY;
point.x = e.clientX;
point.y = e.clientY;
}
point = point.matrixTransform(container.getScreenCTM().inverse());
return [point.x, point.y];
};
// https://bugs.webkit.org/show_bug.cgi?id=44083
var d3_mouse_bug44083 = /WebKit/.test(navigator.userAgent) ? -1 : 0;

8
src/svg/touches.js Normal file
Просмотреть файл

@ -0,0 +1,8 @@
d3.svg.touches = function(container) {
var touches = d3.event.touches;
return touches ? d3_array(touches).map(function(touch) {
var point = d3_svg_mousePoint(container, touch);
point.identifier = touch.identifier;
return point;
}) : [];
};

66
tests/test-bisect.js Normal file
Просмотреть файл

@ -0,0 +1,66 @@
require("./../lib/env-js/envjs/node");
require("./../d3");
var a = [1,2,3,4],
l = d3.bisectLeft,
r = d3.bisectRight;
console.log("exact match:");
console.log(" -1 ->", l(a, -1), r(a, -1));
console.log(" 0 ->", l(a, 0), r(a, 0));
console.log(" 1 ->", l(a, 1), r(a, 1));
console.log(" 2 ->", l(a, 2), r(a, 2));
console.log(" 3 ->", l(a, 3), r(a, 3));
console.log(" 4 ->", l(a, 4), r(a, 4));
console.log(" 5 ->", l(a, 5), r(a, 5));
console.log("");
console.log("non-exact match:");
console.log(" -.1 ->", l(a, -.1), r(a, -.1));
console.log(" .1 ->", l(a, .1), r(a, .1));
console.log(" 1.1 ->", l(a, 1.1), r(a, 1.1));
console.log(" 2.1 ->", l(a, 2.1), r(a, 2.1));
console.log(" 3.1 ->", l(a, 3.1), r(a, 3.1));
console.log(" 4.1 ->", l(a, 4.1), r(a, 4.1));
console.log(" 5.1 ->", l(a, 5.1), r(a, 5.1));
console.log("");
console.log("weird values:");
console.log(" NaN ->", l(a, NaN), r(a, NaN));
console.log(" Infinity ->", l(a, Infinity), r(a, Infinity));
console.log(" -Infinity ->", l(a, -Infinity), r(a, -Infinity));
console.log("");
console.log("d3.bisect === d3.bisectRight:");
console.log(" ", d3.bisect === r);
console.log("");
console.log("lo:");
console.log(" -1 ->", l(a, -1, 2), r(a, -1, 2));
console.log(" 0 ->", l(a, 0, 2), r(a, 0, 2));
console.log(" 1 ->", l(a, 1, 2), r(a, 1, 2));
console.log(" 2 ->", l(a, 2, 2), r(a, 2, 2));
console.log(" 3 ->", l(a, 3, 2), r(a, 3, 2));
console.log(" 4 ->", l(a, 4, 2), r(a, 4, 2));
console.log(" 5 ->", l(a, 5, 2), r(a, 5, 2));
console.log("");
console.log("hi:");
console.log(" -1 ->", l(a, -1, 0, 2), r(a, -1, 0, 2));
console.log(" 0 ->", l(a, 0, 0, 2), r(a, 0, 0, 2));
console.log(" 1 ->", l(a, 1, 0, 2), r(a, 1, 0, 2));
console.log(" 2 ->", l(a, 2, 0, 2), r(a, 2, 0, 2));
console.log(" 3 ->", l(a, 3, 0, 2), r(a, 3, 0, 2));
console.log(" 4 ->", l(a, 4, 0, 2), r(a, 4, 0, 2));
console.log(" 5 ->", l(a, 5, 0, 2), r(a, 5, 0, 2));
console.log("");
console.log("lo and hi:");
console.log(" -1 ->", l(a, -1, 1, 3), r(a, -1, 1, 3));
console.log(" 0 ->", l(a, 0, 1, 3), r(a, 0, 1, 3));
console.log(" 1 ->", l(a, 1, 1, 3), r(a, 1, 1, 3));
console.log(" 2 ->", l(a, 2, 1, 3), r(a, 2, 1, 3));
console.log(" 3 ->", l(a, 3, 1, 3), r(a, 3, 1, 3));
console.log(" 4 ->", l(a, 4, 1, 3), r(a, 4, 1, 3));
console.log(" 5 ->", l(a, 5, 1, 3), r(a, 5, 1, 3));
console.log("");

53
tests/test-bisect.out Normal file
Просмотреть файл

@ -0,0 +1,53 @@
exact match:
-1 -> 0 0
0 -> 0 0
1 -> 0 1
2 -> 1 2
3 -> 2 3
4 -> 3 4
5 -> 4 4
non-exact match:
-.1 -> 0 0
.1 -> 0 0
1.1 -> 1 1
2.1 -> 2 2
3.1 -> 3 3
4.1 -> 4 4
5.1 -> 4 4
weird values:
NaN -> 0 4
Infinity -> 4 4
-Infinity -> 0 0
d3.bisect === d3.bisectRight:
true
lo:
-1 -> 2 2
0 -> 2 2
1 -> 2 2
2 -> 2 2
3 -> 2 3
4 -> 3 4
5 -> 4 4
hi:
-1 -> 0 0
0 -> 0 0
1 -> 0 1
2 -> 1 2
3 -> 2 2
4 -> 2 2
5 -> 2 2
lo and hi:
-1 -> 1 1
0 -> 1 1
1 -> 1 1
2 -> 1 2
3 -> 2 3
4 -> 3 3
5 -> 3 3

40
tests/test-classed.js Normal file
Просмотреть файл

@ -0,0 +1,40 @@
require("./../lib/env-js/envjs/node");
require("./../lib/sizzle/sizzle");
require("./../d3");
var div = d3.select("body").append("div");
div.classed("foo", true);
console.log("constant classed:");
console.log(" ", document.body.innerHTML);
console.log("");
div.classed("foo", true);
console.log("add existing class:");
console.log(" ", document.body.innerHTML);
console.log(" ", div.classed("foo"));
console.log("");
div.classed("bar", function() { return true; });
console.log("function classed:");
console.log(" ", document.body.innerHTML);
console.log(" ", div.classed("bar"));
console.log("");
div.classed("foo", false);
console.log("remove constant class:");
console.log(" ", document.body.innerHTML);
console.log(" ", div.classed("foo"));
console.log("");
div.classed("foo", false);
console.log("remove missing class:");
console.log(" ", document.body.innerHTML);
console.log(" ", div.classed("foo"));
console.log("");
div.classed("bar", function() { return false; });
console.log("remove function class:");
console.log(" ", document.body.innerHTML);
console.log(" ", div.classed("bar"));
console.log("");

23
tests/test-classed.out Normal file
Просмотреть файл

@ -0,0 +1,23 @@
constant classed:
<div class="foo"/>
add existing class:
<div class="foo"/>
true
function classed:
<div class="foo bar"/>
true
remove constant class:
<div class="bar"/>
false
remove missing class:
<div class="bar"/>
false
remove function class:
<div class=""/>
false

Просмотреть файл

@ -78,7 +78,18 @@ console.log(" ", d3.format("8,d")(12345678));
console.log(" ", d3.format("13,d")(1234567890123));
console.log("");
console.log("precision:");
console.log("grouping with general notation:");
console.log(" ", d3.format(",g")(0));
console.log(" ", d3.format(",g")(42));
console.log(" ", d3.format(",g")(42000000));
console.log(" ", d3.format(",g")(420000000));
console.log(" ", d3.format(",g")(-4));
console.log(" ", d3.format(",g")(-42));
console.log(" ", d3.format(",g")(-4200000));
console.log(" ", d3.format(",g")(-42000000));
console.log("");
console.log("precision (fixed-point notation):");
console.log(" ", d3.format(".1f")(0.49));
console.log(" ", d3.format(".2f")(0.449));
console.log(" ", d3.format(".3f")(0.4449));
@ -89,6 +100,35 @@ console.log(" ", d3.format(".3f")(100));
console.log(" ", d3.format(".5f")(100));
console.log("");
console.log("precision (significant digits):");
console.log(" ", d3.format(".1g")(0.049));
console.log(" ", d3.format(".1g")(0.49));
console.log(" ", d3.format(".2g")(0.449));
console.log(" ", d3.format(".3g")(0.4449));
console.log(" ", d3.format(".5g")(0.444449));
console.log(" ", d3.format(".1g")(100));
console.log(" ", d3.format(".2g")(100));
console.log(" ", d3.format(".3g")(100));
console.log(" ", d3.format(".5g")(100));
console.log(" ", d3.format(".5g")(100.2));
console.log(" ", d3.format(".2g")(0.002));
console.log("");
console.log("precision and rounding (significant digits):");
console.log(" ", d3.format(".1r")(0.049));
console.log(" ", d3.format(".1r")(0.49));
console.log(" ", d3.format(".2r")(0.449));
console.log(" ", d3.format(".3r")(0.4449));
console.log(" ", d3.format(".5r")(0.444449));
console.log(" ", d3.format("r")(123.45));
console.log(" ", d3.format(".1r")(123.45));
console.log(" ", d3.format(".2r")(123.45));
console.log(" ", d3.format(".3r")(123.45));
console.log(" ", d3.format(".4r")(123.45));
console.log(" ", d3.format(".5r")(123.45));
console.log(" ", d3.format(".6r")(123.45));
console.log("");
console.log("precision and grouping with space fill:");
console.log(" ", d3.format("10,.1f")(123456.49));
console.log(" ", d3.format("10,.2f")(1234567.449));
@ -105,5 +145,50 @@ console.log(" ", d3.format("f")(42));
console.log("");
console.log("int type passed float:");
console.log(" ", d3.format("d")(4.2));
console.log(d3.format("d")(4.2));
console.log("");
console.log("number:");
console.log(" ", d3.format("n")(.0042));
console.log(" ", d3.format("n")(.42));
console.log(" ", d3.format("n")(0));
console.log(" ", d3.format("n")(42));
console.log(" ", d3.format("n")(42000000));
console.log(" ", d3.format("n")(420000000));
console.log(" ", d3.format("n")(-4));
console.log(" ", d3.format("n")(-42));
console.log(" ", d3.format("n")(-4200000));
console.log(" ", d3.format("n")(-42000000));
console.log("");
console.log("percentage:");
console.log(" ", d3.format("%")(0));
console.log(" ", d3.format("%")(.042));
console.log(" ", d3.format("%")(.42));
console.log(" ", d3.format("%")(4.2));
console.log(" ", d3.format("%")(-.042));
console.log(" ", d3.format("%")(-.42));
console.log(" ", d3.format("%")(-4.2));
console.log("");
console.log("percentage with rounding and sign:");
console.log(" ", d3.format("+.2p")(.00123));
console.log(" ", d3.format("+.2p")(.0123));
console.log(" ", d3.format("+.2p")(.123));
console.log(" ", d3.format("+.2p")(1.23));
console.log(" ", d3.format("+.2p")(-.00123));
console.log(" ", d3.format("+.2p")(-.0123));
console.log(" ", d3.format("+.2p")(-.123));
console.log(" ", d3.format("+.2p")(-1.23));
console.log("");
console.log("exponent:");
console.log(" ", d3.format("e")(0));
console.log(" ", d3.format("e")(42));
console.log(" ", d3.format("e")(42000000));
console.log(" ", d3.format("e")(420000000));
console.log(" ", d3.format("e")(-4));
console.log(" ", d3.format("e")(-42));
console.log(" ", d3.format("e")(-4200000));
console.log(" ", d3.format("e")(-42000000));
console.log("");

Просмотреть файл

@ -66,7 +66,17 @@ grouping with space fill (overflow):
12,345,678
1,234,567,890,123
precision:
grouping with general notation:
0
42
42,000,000
420,000,000
4
42
4,200,000
42,000,000
precision (fixed-point notation):
0.5
0.45
0.445
@ -76,6 +86,33 @@ precision:
100.000
100.00000
precision (significant digits):
0.05
0.5
0.45
0.445
0.44445
1e+2
1.0e+2
100
100.00
100.20
0.0020
precision and rounding (significant digits):
0.05
0.5
0.45
0.445
0.44445
123
100
120
123
123.5
123.45
123.450
precision and grouping with space fill:
123,456.5
1,234,567.45
@ -92,3 +129,44 @@ float type passed int:
int type passed float:
number:
0.0042
0.42
0
42
42,000,000
420,000,000
4
42
4,200,000
42,000,000
percentage:
0%
4%
42%
420%
4%
42%
420%
percentage with rounding and sign:
+0.12%
+1.2%
+12%
+120%
0.12%
1.2%
12%
120%
exponent:
0e+0
4.2e+1
4.2e+7
4.2e+8
4e+0
4.2e+1
4.2e+6
4.2e+7

51
tests/test-hsl.js Normal file
Просмотреть файл

@ -0,0 +1,51 @@
require("./../lib/env-js/envjs/node");
require("./../d3");
console.log("constructor:");
console.log(" " + d3.hsl(60, 1, .2));
console.log(" " + d3.hsl(60.4, .994, .204));
console.log(" " + d3.hsl(60.6, .996, .216));
console.log(" " + JSON.stringify(d3.hsl(60, 1, .2)));
console.log("");
console.log("parse rgb:");
console.log(" " + d3.hsl("#660"));
console.log(" " + d3.hsl("#666600"));
console.log(" " + d3.hsl("rgb(102, 102, 0)"));
console.log(" " + JSON.stringify(d3.hsl("#660")));
console.log("");
console.log("parse hsl:");
console.log(" " + d3.hsl("hsl(60, 100%, 20%)"));
console.log(" " + d3.hsl(d3.hsl(60, 1, .2)));
console.log(" " + JSON.stringify(d3.hsl("hsl(60, 100%, 20%)")));
console.log("");
console.log("parse names:");
console.log(" " + d3.hsl("red"));
console.log(" " + d3.hsl("yellow"));
console.log(" " + d3.hsl("blue"));
console.log("");
console.log("convert to rgb:");
console.log(" " + d3.hsl("#660").rgb());
console.log(" " + d3.hsl("hsl(60, 100%, 20%)").rgb());
console.log(" " + d3.hsl(60, 1, .2).rgb());
console.log(" " + JSON.stringify(d3.hsl("#660").rgb()));
console.log("");
console.log("brighter:");
console.log(" " + d3.hsl(60, 1, .2).brighter());
console.log(" " + d3.hsl("#660").brighter(1));
console.log(" " + d3.hsl("hsl(60, 100%, 20%)").brighter(.5));
console.log(" " + d3.hsl(d3.rgb(102, 102, 0)).brighter(2));
console.log(" " + JSON.stringify(d3.hsl("hsl(60, 100%, 20%)").brighter()));
console.log("");
console.log("darker:");
console.log(" " + d3.hsl(60, 1, .2).darker());
console.log(" " + d3.hsl("#660").darker(1));
console.log(" " + d3.hsl("hsl(60, 100%, 20%)").darker(.5));
console.log(" " + d3.hsl(d3.rgb(102, 102, 0)).darker(2));
console.log(" " + JSON.stringify(d3.hsl("hsl(60, 100%, 20%)").darker()));
console.log("");

42
tests/test-hsl.out Normal file
Просмотреть файл

@ -0,0 +1,42 @@
constructor:
hsl(60,100%,20%)
hsl(60.4,99.4%,20.4%)
hsl(60.6,99.6%,21.6%)
{"h":60,"s":1,"l":0.2}
parse rgb:
hsl(60,100%,20%)
hsl(60,100%,20%)
hsl(60,100%,20%)
{"h":60,"s":1,"l":0.2}
parse hsl:
hsl(60,100%,20%)
hsl(60,100%,20%)
{"h":60,"s":1,"l":0.2}
parse names:
hsl(0,100%,50%)
hsl(60,100%,50%)
hsl(240,100%,50%)
convert to rgb:
#666600
#666600
#666600
{"r":102,"g":102,"b":0}
brighter:
hsl(60,100%,28.571428571428577%)
hsl(60,100%,28.571428571428577%)
hsl(60,100%,23.904572186687872%)
hsl(60,100%,40.81632653061225%)
{"h":60,"s":1,"l":0.28571428571428575}
darker:
hsl(60,100%,13.999999999999998%)
hsl(60,100%,13.999999999999998%)
hsl(60,100%,16.733200530681515%)
hsl(60,100%,9.799999999999999%)
{"h":60,"s":1,"l":0.13999999999999999}

17
tests/test-keys.js Normal file
Просмотреть файл

@ -0,0 +1,17 @@
require("./../lib/env-js/envjs/node");
require("./../d3");
function Abc() {
this.a = 1;
this.b = 2;
}
Abc.prototype.c = 1;
console.log("keys:");
console.log(" " + d3.keys({a: 1, b: 2}).sort());
console.log("");
console.log("inherited keys:");
console.log(" " + d3.keys(new Abc()).sort());
console.log("");

6
tests/test-keys.out Normal file
Просмотреть файл

@ -0,0 +1,6 @@
keys:
a,b
inherited keys:
a,b,c

38
tests/test-permute.js Normal file
Просмотреть файл

@ -0,0 +1,38 @@
require("./../lib/env-js/envjs/node");
require("./../d3");
var array = [0,1,2];
console.log("permute reverses:");
console.log(" 2,1,0:", d3.permute(array, [2,1,0]) + "");
console.log("");
console.log("permute does not modify input array:");
console.log(" 0,1,2:", array + "");
console.log("");
console.log("permute does nothing:");
console.log(" 0,1,2:", d3.permute(array, [0,1,2]) + "");
console.log("");
console.log("permute duplicates:");
console.log(" 0,0,0:", d3.permute(array, [0,0,0]) + "");
console.log("");
console.log("permute returns fewer elements:");
console.log(" 2,1:", d3.permute(array, [2,1]) + "");
console.log(" 1:", d3.permute(array, [1]) + "");
console.log(" 0:", d3.permute(array, [0]) + "");
console.log(" :", d3.permute(array, []) + "");
console.log("");
console.log("permute returns undefined elements:");
console.log(" 10:", d3.permute(array, [10]) + "");
console.log(" -1:", d3.permute(array, [-1]) + "");
console.log(" 0,-1:", d3.permute(array, [0,-1]) + "");
console.log("");
console.log("permute returns more elements:");
console.log(" 0,0,1,2:", d3.permute(array, [0,0,1,2]) + "");
console.log(" 0,1,1,1:", d3.permute(array, [0,1,1,1]) + "");
console.log("");

27
tests/test-permute.out Normal file
Просмотреть файл

@ -0,0 +1,27 @@
permute reverses:
2,1,0: 2,1,0
permute does not modify input array:
0,1,2: 0,1,2
permute does nothing:
0,1,2: 0,1,2
permute duplicates:
0,0,0: 0,0,0
permute returns fewer elements:
2,1: 2,1
1: 1
0: 0
:
permute returns undefined elements:
10:
-1:
0,-1: 0,
permute returns more elements:
0,0,1,2: 0,0,1,2
0,1,1,1: 0,1,1,1

51
tests/test-rgb.js Normal file
Просмотреть файл

@ -0,0 +1,51 @@
require("./../lib/env-js/envjs/node");
require("./../d3");
console.log("constructor:");
console.log(" " + d3.rgb(102, 102, 0));
console.log(" " + d3.rgb(102.4, 102.4, 0.4));
console.log(" " + d3.rgb(102.6, 102.6, 0.6));
console.log(" " + JSON.stringify(d3.rgb(102, 102, 0)));
console.log("");
console.log("parse rgb:");
console.log(" " + d3.rgb("#660"));
console.log(" " + d3.rgb("#666600"));
console.log(" " + d3.rgb("rgb(102, 102, 0)"));
console.log(" " + JSON.stringify(d3.rgb("#660")));
console.log("");
console.log("parse hsl:");
console.log(" " + d3.rgb("hsl(60, 100%, 20%)"));
console.log(" " + d3.rgb(d3.hsl(60, 1, .2)));
console.log(" " + JSON.stringify(d3.rgb("hsl(60, 100%, 20%)")));
console.log("");
console.log("parse names:");
console.log(" " + d3.rgb("aliceblue"));
console.log(" " + d3.rgb("moccasin"));
console.log(" " + d3.rgb("yellow"));
console.log("");
console.log("convert to hsl:");
console.log(" " + d3.rgb("#660").hsl());
console.log(" " + d3.rgb("#666600").hsl());
console.log(" " + d3.rgb(102, 102, 0).hsl());
console.log(" " + JSON.stringify(d3.rgb("#660").hsl()));
console.log("");
console.log("brighter:");
console.log(" " + d3.rgb(102, 102, 0).brighter());
console.log(" " + d3.rgb("#660").brighter(1));
console.log(" " + d3.rgb("hsl(60, 100%, 20%)").brighter(.5));
console.log(" " + d3.rgb(d3.hsl(60, 1, .2)).brighter(2));
console.log(" " + JSON.stringify(d3.rgb("#660").brighter()));
console.log("");
console.log("darker:");
console.log(" " + d3.rgb(102, 102, 0).darker());
console.log(" " + d3.rgb("#660").darker(1));
console.log(" " + d3.rgb("hsl(60, 100%, 20%)").darker(.5));
console.log(" " + d3.rgb(d3.hsl(60, 1, .2)).darker(2));
console.log(" " + JSON.stringify(d3.rgb("#660").darker()));
console.log("");

42
tests/test-rgb.out Normal file
Просмотреть файл

@ -0,0 +1,42 @@
constructor:
#666600
#666600
#666600
{"r":102,"g":102,"b":0}
parse rgb:
#666600
#666600
#666600
{"r":102,"g":102,"b":0}
parse hsl:
#666600
#666600
{"r":102,"g":102,"b":0}
parse names:
#f0f8ff
#ffe4b5
#ffff00
convert to hsl:
hsl(60,100%,20%)
hsl(60,100%,20%)
hsl(60,100%,20%)
{"h":60,"s":1,"l":0.2}
brighter:
#919100
#919100
#797900
#d0d000
{"r":145,"g":145,"b":0}
darker:
#474700
#474700
#555500
#313100
{"r":71,"g":71,"b":0}

75
tests/test-round.js Normal file
Просмотреть файл

@ -0,0 +1,75 @@
require("./../lib/env-js/envjs/node");
require("./../d3");
console.log("degenerate:");
console.log(" 0 ->", d3.round(0));
console.log(" NaN ->", d3.round(NaN));
console.log(" Infinity ->", d3.round(Infinity));
console.log(" -Infinity ->", d3.round(-Infinity));
console.log("");
console.log("default:");
console.log(" 10.51 ->", d3.round(10.51));
console.log(" 10.50 ->", d3.round(10.50));
console.log(" 10.49 ->", d3.round(10.49));
console.log(" 0.51 ->", d3.round(0.51));
console.log(" 0.50 ->", d3.round(0.50));
console.log(" 0.49 ->", d3.round(0.49));
console.log(" -0.51 ->", d3.round(-0.51));
console.log(" -0.50 ->", d3.round(-0.50));
console.log(" -0.49 ->", d3.round(-0.49));
console.log(" -10.51 ->", d3.round(-10.51));
console.log(" -10.50 ->", d3.round(-10.50));
console.log(" -10.49 ->", d3.round(-10.49));
console.log("");
console.log("precision 1:");
console.log(" 10.51 ->", d3.round(10.51, 1));
console.log(" 10.50 ->", d3.round(10.50, 1));
console.log(" 10.49 ->", d3.round(10.49, 1));
console.log(" 0.51 ->", d3.round(0.51, 1));
console.log(" 0.50 ->", d3.round(0.50, 1));
console.log(" 0.49 ->", d3.round(0.49, 1));
console.log(" -0.51 ->", d3.round(-0.51, 1));
console.log(" -0.50 ->", d3.round(-0.50, 1));
console.log(" -0.49 ->", d3.round(-0.49, 1));
console.log(" -10.51 ->", d3.round(-10.51, 1));
console.log(" -10.50 ->", d3.round(-10.50, 1));
console.log(" -10.49 ->", d3.round(-10.49, 1));
console.log("");
console.log("precision 2:");
console.log(" 10.51 ->", d3.round(10.51, 2));
console.log(" 10.50 ->", d3.round(10.50, 2));
console.log(" 10.49 ->", d3.round(10.49, 2));
console.log(" 0.51 ->", d3.round(0.51, 2));
console.log(" 0.50 ->", d3.round(0.50, 2));
console.log(" 0.49 ->", d3.round(0.49, 2));
console.log(" -0.51 ->", d3.round(-0.51, 2));
console.log(" -0.50 ->", d3.round(-0.50, 2));
console.log(" -0.49 ->", d3.round(-0.49, 2));
console.log(" -10.51 ->", d3.round(-10.51, 2));
console.log(" -10.50 ->", d3.round(-10.50, 2));
console.log(" -10.49 ->", d3.round(-10.49, 2));
console.log("");
console.log("precision -1:");
console.log(" 123.45 ->", d3.round(123.45, -1));
console.log(" 345.67 ->", d3.round(345.67, -1));
console.log(" -123.45 ->", d3.round(-123.45, -1));
console.log(" -345.67 ->", d3.round(-345.67, -1));
console.log("");
console.log("precision -2:");
console.log(" 123.45 ->", d3.round(123.45, -2));
console.log(" 456.78 ->", d3.round(456.78, -2));
console.log(" -123.45 ->", d3.round(-123.45, -2));
console.log(" -456.78 ->", d3.round(-456.78, -2));
console.log("");
console.log("precision -3:");
console.log(" 123.45 ->", d3.round(123.45, -3));
console.log(" 567.89 ->", d3.round(567.89, -3));
console.log(" -123.45 ->", d3.round(-123.45, -3));
console.log(" -567.89 ->", d3.round(-567.89, -3));
console.log("");

66
tests/test-round.out Normal file
Просмотреть файл

@ -0,0 +1,66 @@
degenerate:
0 -> 0
NaN -> NaN
Infinity -> Infinity
-Infinity -> -Infinity
default:
10.51 -> 11
10.50 -> 11
10.49 -> 10
0.51 -> 1
0.50 -> 1
0.49 -> 0
-0.51 -> -1
-0.50 -> 0
-0.49 -> 0
-10.51 -> -11
-10.50 -> -10
-10.49 -> -10
precision 1:
10.51 -> 10.5
10.50 -> 10.5
10.49 -> 10.5
0.51 -> 0.5
0.50 -> 0.5
0.49 -> 0.5
-0.51 -> -0.5
-0.50 -> -0.5
-0.49 -> -0.5
-10.51 -> -10.5
-10.50 -> -10.5
-10.49 -> -10.5
precision 2:
10.51 -> 10.51
10.50 -> 10.5
10.49 -> 10.49
0.51 -> 0.51
0.50 -> 0.5
0.49 -> 0.49
-0.51 -> -0.51
-0.50 -> -0.5
-0.49 -> -0.49
-10.51 -> -10.51
-10.50 -> -10.5
-10.49 -> -10.49
precision -1:
123.45 -> 120
345.67 -> 350
-123.45 -> -120
-345.67 -> -350
precision -2:
123.45 -> 100
456.78 -> 500
-123.45 -> -100
-456.78 -> -500
precision -3:
123.45 -> 0
567.89 -> 1000
-123.45 -> 0
-567.89 -> -1000

Просмотреть файл

@ -0,0 +1,30 @@
require("./../lib/env-js/envjs/node");
require("./../d3");
var f = d3.format(" .3f");
var x = d3.scale.linear().domain([-1, 0, 1]).range(["red", "white", "green"]);
console.log("domain(-1, 0, 1).range(red, white, green):");
console.log(" -1.0 -> " + x(-1));
console.log(" -0.8 -> " + x(-.8));
console.log(" -0.6 -> " + x(-.6));
console.log(" -0.4 -> " + x(-.4));
console.log(" -0.2 -> " + x(-.2));
console.log(" 0.0 -> " + x(0));
console.log(" 0.2 -> " + x(.2));
console.log(" 0.4 -> " + x(.4));
console.log(" 0.6 -> " + x(.6));
console.log(" 0.8 -> " + x(.8));
console.log(" 1.0 -> " + x(1));
console.log("");
var x = d3.scale.linear().domain([-1, 0, 1]).range([-100, 0, 10]);
console.log("domain(-1, 0, 1).range(-100, 0, 10):");
console.log(" -1.5 -> " + f(x(-1.5)));
console.log(" -1.0 -> " + f(x(-1)));
console.log(" -0.5 -> " + f(x(-.5)));
console.log(" 0.0 -> " + f(x(0)));
console.log(" 0.5 -> " + f(x(.5)));
console.log(" 1.0 -> " + f(x(1)));
console.log(" 1.5 -> " + f(x(1.5)));
console.log("");

Просмотреть файл

@ -0,0 +1,22 @@
domain(-1, 0, 1).range(red, white, green):
-1.0 -> rgb(255,0,0)
-0.8 -> rgb(255,51,51)
-0.6 -> rgb(255,102,102)
-0.4 -> rgb(255,153,153)
-0.2 -> rgb(255,204,204)
0.0 -> rgb(255,255,255)
0.2 -> rgb(204,230,204)
0.4 -> rgb(153,204,153)
0.6 -> rgb(102,179,102)
0.8 -> rgb(51,153,51)
1.0 -> rgb(0,128,0)
domain(-1, 0, 1).range(-100, 0, 10):
-1.5 -> 150.000
-1.0 -> 100.000
-0.5 -> 50.000
0.0 -> 0.000
0.5 -> 5.000
1.0 -> 10.000
1.5 -> 15.000

Просмотреть файл

@ -0,0 +1,142 @@
require("./../lib/env-js/envjs/node");
require("./../d3");
var x = d3.scale.quantile()
.domain([3, 6, 7, 8, 8, 10, 13, 15, 16, 20])
.range([0, 1, 2, 3]);
console.log("domain(3, 6, 7, 8, 8, 10, 13, 15, 16, 20).range(0, 1, 2, 3):");
console.log(" quantiles -> " + x.quantiles());
console.log(" 3 -> " + x(3));
console.log(" 6 -> " + x(6));
console.log(" 6.9 -> " + x(6.9));
console.log(" 7 -> " + x(7));
console.log(" 7.1 -> " + x(7.1));
console.log(" 8 -> " + x(8));
console.log(" 8.9 -> " + x(8.9));
console.log(" 9 -> " + x(9));
console.log(" 9.1 -> " + x(9.1));
console.log(" 10 -> " + x(10));
console.log(" 13 -> " + x(13));
console.log(" 14.9 -> " + x(14.9));
console.log(" 15 -> " + x(15));
console.log(" 15.1 -> " + x(15.1));
console.log(" 16 -> " + x(16));
console.log(" 20 -> " + x(20));
console.log("");
var x = d3.scale.quantile()
.domain([3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20])
.range([0, 1, 2, 3]);
console.log("domain(3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20).range(0, 1, 2, 3):");
console.log(" quantiles -> " + x.quantiles());
console.log(" 3 -> " + x(3));
console.log(" 6 -> " + x(6));
console.log(" 6.9 -> " + x(6.9));
console.log(" 7 -> " + x(7));
console.log(" 7.1 -> " + x(7.1));
console.log(" 8 -> " + x(8));
console.log(" 8.9 -> " + x(8.9));
console.log(" 9 -> " + x(9));
console.log(" 9.1 -> " + x(9.1));
console.log(" 10 -> " + x(10));
console.log(" 13 -> " + x(13));
console.log(" 14.9 -> " + x(14.9));
console.log(" 15 -> " + x(15));
console.log(" 15.1 -> " + x(15.1));
console.log(" 16 -> " + x(16));
console.log(" 20 -> " + x(20));
console.log("");
var x = d3.scale.quantile()
.domain([0, 1])
.range([0, 1]);
console.log("domain(0, 1).range(0, 1):");
console.log(" quantiles -> " + x.quantiles());
console.log(" -.5 -> " + x(-.5));
console.log(" 0 -> " + x(0));
console.log(" .49 -> " + x(.49));
console.log(" .51 -> " + x(.51));
console.log(" 1 -> " + x(1));
console.log(" 1.5 -> " + x(1.5));
console.log("");
var x = d3.scale.quantile()
.domain([1, 2, 3, 4])
.range(["a", "b"]);
console.log("domain(1, 2, 3, 4).range(a, b):");
console.log(" quantiles -> " + x.quantiles());
console.log(" 0 -> " + x(0));
console.log(" 1 -> " + x(1));
console.log(" 2 -> " + x(2));
console.log(" 2.49 -> " + x(2.49));
console.log(" 2.51 -> " + x(2.51));
console.log(" 3 -> " + x(3));
console.log(" 4 -> " + x(4));
console.log(" 5 -> " + x(5));
console.log("");
var x = d3.scale.quantile()
.domain([1, 2, 3, 4])
.range(["a", "b", "c"]);
console.log("domain(1, 2, 3, 4).range(a, b, c):");
console.log(" quantiles -> " + x.quantiles());
console.log(" 0 -> " + x(0));
console.log(" 1 -> " + x(1));
console.log(" 1.9 -> " + x(1.9));
console.log(" 2 -> " + x(2));
console.log(" 2.1 -> " + x(2.1));
console.log(" 2.9 -> " + x(2.9));
console.log(" 3 -> " + x(3));
console.log(" 3.1 -> " + x(3.1));
console.log(" 4 -> " + x(4));
console.log(" 5 -> " + x(5));
console.log("");
var x = d3.scale.quantile()
.domain([1, 1, 2, 2, 3, 3, 4, 4])
.range(["a", "b", "c", "d"]);
console.log("domain(1, 1, 2, 2, 3, 3, 4, 4).range(a, b, c, d):");
console.log(" quantiles -> " + x.quantiles());
console.log(" 0 -> " + x(0));
console.log(" 1 -> " + x(1));
console.log(" 1.49 -> " + x(1.49));
console.log(" 1.51 -> " + x(1.51));
console.log(" 2 -> " + x(2));
console.log(" 2.49 -> " + x(2.49));
console.log(" 2.51 -> " + x(2.51));
console.log(" 3 -> " + x(3));
console.log(" 3.49 -> " + x(3.49));
console.log(" 3.51 -> " + x(3.51));
console.log(" 4 -> " + x(4));
console.log(" 5 -> " + x(5));
console.log("");
var x = d3.scale.quantile()
.domain([1, 2, 3, 4, 5, 6, 7, 8])
.range(["a", "b", "c", "d"]);
console.log("domain(1, 2, 3, 4, 5, 6, 7, 8).range(a, b, c, d):");
console.log(" quantiles -> " + x.quantiles());
console.log(" 0 -> " + x(0));
console.log(" 1 -> " + x(1));
console.log(" 2 -> " + x(2));
console.log(" 2.49 -> " + x(2.49));
console.log(" 2.51 -> " + x(2.51));
console.log(" 3 -> " + x(3));
console.log(" 4 -> " + x(4));
console.log(" 4.49 -> " + x(4.49));
console.log(" 4.51 -> " + x(4.51));
console.log(" 5 -> " + x(5));
console.log(" 6 -> " + x(6));
console.log(" 6.49 -> " + x(6.49));
console.log(" 6.51 -> " + x(6.51));
console.log(" 7 -> " + x(7));
console.log(" 8 -> " + x(8));
console.log(" 9 -> " + x(9));
console.log("");

Просмотреть файл

@ -0,0 +1,105 @@
domain(3, 6, 7, 8, 8, 10, 13, 15, 16, 20).range(0, 1, 2, 3):
quantiles -> 7,9,15
3 -> 0
6 -> 0
6.9 -> 0
7 -> 1
7.1 -> 1
8 -> 1
8.9 -> 1
9 -> 2
9.1 -> 2
10 -> 2
13 -> 2
14.9 -> 2
15 -> 3
15.1 -> 3
16 -> 3
20 -> 3
domain(3, 6, 7, 8, 8, 9, 10, 13, 15, 16, 20).range(0, 1, 2, 3):
quantiles -> 7,9,15
3 -> 0
6 -> 0
6.9 -> 0
7 -> 1
7.1 -> 1
8 -> 1
8.9 -> 1
9 -> 2
9.1 -> 2
10 -> 2
13 -> 2
14.9 -> 2
15 -> 3
15.1 -> 3
16 -> 3
20 -> 3
domain(0, 1).range(0, 1):
quantiles -> 0.5
-.5 -> 0
0 -> 0
.49 -> 0
.51 -> 1
1 -> 1
1.5 -> 1
domain(1, 2, 3, 4).range(a, b):
quantiles -> 2.5
0 -> a
1 -> a
2 -> a
2.49 -> a
2.51 -> b
3 -> b
4 -> b
5 -> b
domain(1, 2, 3, 4).range(a, b, c):
quantiles -> 2,3
0 -> a
1 -> a
1.9 -> a
2 -> b
2.1 -> b
2.9 -> b
3 -> c
3.1 -> c
4 -> c
5 -> c
domain(1, 1, 2, 2, 3, 3, 4, 4).range(a, b, c, d):
quantiles -> 1.5,2.5,3.5
0 -> a
1 -> a
1.49 -> a
1.51 -> b
2 -> b
2.49 -> b
2.51 -> c
3 -> c
3.49 -> c
3.51 -> d
4 -> d
5 -> d
domain(1, 2, 3, 4, 5, 6, 7, 8).range(a, b, c, d):
quantiles -> 2.5,4.5,6.5
0 -> a
1 -> a
2 -> a
2.49 -> a
2.51 -> b
3 -> b
4 -> b
4.49 -> b
4.51 -> c
5 -> c
6 -> c
6.49 -> c
6.51 -> d
7 -> d
8 -> d
9 -> d

Просмотреть файл

@ -93,3 +93,12 @@ console.log(" [[0, 0]]:", area([[0, 0]]));
console.log(" [[0, 0], [5, 5]]:", area([[0, 0], [5, 5]]));
console.log(" [[0, 0], [5, 5], [10, 0]]:", area([[0, 0], [5, 5], [10, 0]]));
console.log("");
var area = d3.svg.area()
.interpolate("monotone");
console.log("interpolate(monotone):");
console.log(" [[0, 0]]:", area([[0, 0]]));
console.log(" [[0, 0], [5, 5]]:", area([[0, 0], [5, 5]]));
console.log(" [[0, 0], [5, 5], [10, 0]]:", area([[0, 0], [5, 5], [10, 0]]));
console.log("");

Просмотреть файл

@ -48,3 +48,8 @@ interpolate(cardinal-closed):
[[0, 0], [5, 5]]: M0,0L5,5L5,0L0,0Z
[[0, 0], [5, 5], [10, 0]]: M0,0C-0.7500000000000001,0.7500000000000001,3.5,5,5,5S10.75,0.7500000000000001,10,0S0.7500000000000001,-0.7500000000000001,0,0L10,0C10.75,0,6.5,0,5,0S-0.7500000000000001,0,0,0S9.25,0,10,0Z
interpolate(monotone):
[[0, 0]]: M0,0L0,0Z
[[0, 0], [5, 5]]: M0,0L5,5L5,0L0,0Z
[[0, 0], [5, 5], [10, 0]]: M0,0C0.4166666666666667,0.4166666666666667,3.333333333333333,5,5,5S9.583333333333334,0.4166666666666667,10,0L10,0C9.166666666666666,0,6.666666666666667,0,5,0S0.8333333333333334,0,0,0Z

Просмотреть файл

@ -82,3 +82,12 @@ console.log(" [[0, 0]]:", line([[0, 0]]));
console.log(" [[0, 0], [5, 5]]:", line([[0, 0], [5, 5]]));
console.log(" [[0, 0], [5, 5], [10, 0]]:", line([[0, 0], [5, 5], [10, 0]]));
console.log("");
var line = d3.svg.line()
.interpolate("monotone");
console.log("interpolate(monotone):");
console.log(" [[0, 0]]:", line([[0, 0]]));
console.log(" [[0, 0], [5, 5]]:", line([[0, 0], [5, 5]]));
console.log(" [[0, 0], [5, 5], [10, 0]]:", line([[0, 0], [5, 5], [10, 0]]));
console.log("");

Просмотреть файл

@ -43,3 +43,8 @@ interpolate(cardinal-closed):
[[0, 0], [5, 5]]: M0,0L5,5
[[0, 0], [5, 5], [10, 0]]: M0,0C-0.7500000000000001,0.7500000000000001,3.5,5,5,5S10.75,0.7500000000000001,10,0S0.7500000000000001,-0.7500000000000001,0,0
interpolate(monotone):
[[0, 0]]: M0,0
[[0, 0], [5, 5]]: M0,0L5,5
[[0, 0], [5, 5], [10, 0]]: M0,0C0.4166666666666667,0.4166666666666667,3.333333333333333,5,5,5S9.583333333333334,0.4166666666666667,10,0