This is similar to pv.search, but more closely modeled after Python's bisect
methods to provide the desired flexibility in searching slices of arrays. This
includes good tests for bisect, and better tests for polylinear and quantile
scales (both of which now use bisect).
This commit is contained in:
Mike Bostock 2011-05-21 12:56:06 -07:00
Родитель a5d46990c6
Коммит 6ba3097766
16 изменённых файлов: 595 добавлений и 149 удалений

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

@ -48,6 +48,7 @@ d3.core.js: \
src/core/call.js \
src/core/range.js \
src/core/requote.js \
src/core/bisect.js \
src/core/xhr.js \
src/core/text.js \
src/core/json.js \
@ -176,6 +177,8 @@ tests: \
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-svg-arc.test \
tests/test-svg-area.test \
tests/test-svg-line.test \

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

@ -236,6 +236,44 @@ d3.requote = function(s) {
};
var d3_requote_re = /[\\\^\$\*\+\?\[\]\(\)\.\{\}]/g;
// 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.xhr = function(url, mime, callback) {
var req = new XMLHttpRequest();
if (arguments.length < 3) callback = mime;
@ -2147,19 +2185,8 @@ function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
i.push(interpolate(range[j - 1], range[j]));
}
function search(x) {
var low = 1, high = domain.length - 2;
while (low <= high) {
var mid = (low + high) >> 1, midValue = domain[mid];
if (midValue < x) low = mid + 1;
else if (midValue > x) high = mid - 1;
else return mid;
}
return low - 1;
}
return function(x) {
var j = search(x);
var j = d3.bisect(domain, x, 1, domain.length - 1) - 1;
return i[j](u[j](x));
};
}
@ -2417,26 +2444,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)];
}
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;
var k = 0,
n = domain.length,
q = range.length,
i;
thresholds.length = Math.max(0, q - 1);
while (++k < q) {
i = n * k / q;
if (i % 1) thresholds[k - 1] = domain[~~i];
else thresholds[k - 1] = (domain[i = ~~i] + domain[i - 1]) / 2;
}
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) {

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

@ -878,37 +878,35 @@ d3.layout.histogram = function() {
ticksFunction = d3_layout_histogramTicks;
function histogram(data, i) {
var x = data.map(value), bins = [];
// Initialize default ticks.
var ticks = ticksFunction.call(this, data, i);
var x = data.map(value),
bins = [],
bin,
ticks = ticksFunction.call(this, data, i),
i = -1,
n = x.length,
m = ticks.length - 1,
k = frequency ? 1 / n : 1;
// 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 = ticks[i + 1] - (bin.x = ticks[i]);
bin.y = 0;
}
// Count the number of samples per bin.
for (var i = 0; i < x.length; i++) {
var bin = bins[d3_layout_histogramSearch(ticks, x[i])];
bin.y++;
i = -1; while(++i < n) {
bin = bins[d3.bisect(ticks, x[i], 0, 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;
}
histogram.frequency = function(x) {
if (!arguments.length) return frequency;
frequency = Boolean(x);
frequency = !!x;
return histogram;
};
@ -927,18 +925,6 @@ d3.layout.histogram = function() {
return histogram;
};
// Performs a binary search on a sorted array.
function d3_layout_histogramSearch(array, value) {
var low = 1, high = array.length - 2;
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_histogramTicks(x) {
return d3.scale.linear().domain(x).ticks(10);
}

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

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

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

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

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

@ -10,18 +10,28 @@ 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
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);
@ -29,29 +39,44 @@ for (var i = 0; i < n; i++) {
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]);
ticks = d3.range(0, m, .25);
var vis = d3.select("body")
.append("svg:svg")
var histogram = d3.layout.histogram()
.frequency(true)
.ticks(ticks);
var x = d3.scale.ordinal()
.domain(ticks)
.rangeRoundBands([0, w]);
var y = d3.scale.linear()
.domain([0, .12])
.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(data))
.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>

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;
};

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

@ -4,37 +4,35 @@ d3.layout.histogram = function() {
ticksFunction = d3_layout_histogramTicks;
function histogram(data, i) {
var x = data.map(value), bins = [];
// Initialize default ticks.
var ticks = ticksFunction.call(this, data, i);
var x = data.map(value),
bins = [],
bin,
ticks = ticksFunction.call(this, data, i),
i = -1,
n = x.length,
m = ticks.length - 1,
k = frequency ? 1 / n : 1;
// 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 = ticks[i + 1] - (bin.x = ticks[i]);
bin.y = 0;
}
// Count the number of samples per bin.
for (var i = 0; i < x.length; i++) {
var bin = bins[d3_layout_histogramSearch(ticks, x[i])];
bin.y++;
i = -1; while(++i < n) {
bin = bins[d3.bisect(ticks, x[i], 0, 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;
}
histogram.frequency = function(x) {
if (!arguments.length) return frequency;
frequency = Boolean(x);
frequency = !!x;
return histogram;
};
@ -53,18 +51,6 @@ d3.layout.histogram = function() {
return histogram;
};
// Performs a binary search on a sorted array.
function d3_layout_histogramSearch(array, value) {
var low = 1, high = array.length - 2;
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_histogramTicks(x) {
return d3.scale.linear().domain(x).ticks(10);
}

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

@ -9,19 +9,8 @@ function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
i.push(interpolate(range[j - 1], range[j]));
}
function search(x) {
var low = 1, high = domain.length - 2;
while (low <= high) {
var mid = (low + high) >> 1, midValue = domain[mid];
if (midValue < x) low = mid + 1;
else if (midValue > x) high = mid - 1;
else return mid;
}
return low - 1;
}
return function(x) {
var j = search(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)];
}
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;
var k = 0,
n = domain.length,
q = range.length,
i;
thresholds.length = Math.max(0, q - 1);
while (++k < q) {
i = n * k / q;
if (i % 1) thresholds[k - 1] = domain[~~i];
else thresholds[k - 1] = (domain[i = ~~i] + domain[i - 1]) / 2;
}
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) {

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

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

@ -1,10 +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(" -0.5 -> ", x(-0.5));
console.log(" 0.0 -> ", x(0.0));
console.log(" 0.5 -> ", x(0.5));
console.log(" 1.0 -> ", x(1.0));
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("");

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

@ -1,6 +1,22 @@
domain([-1, 0, 1]).range(["red", "white", "green"]):
-0.5 -> rgb(255,128,128)
0.0 -> rgb(255,255,255)
0.5 -> rgb(128,192,128)
1.0 -> rgb(0,128,0)
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