Add d3.bisect.
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:
Родитель
a5d46990c6
Коммит
6ba3097766
3
Makefile
3
Makefile
|
@ -48,6 +48,7 @@ d3.core.js: \
|
||||||
src/core/call.js \
|
src/core/call.js \
|
||||||
src/core/range.js \
|
src/core/range.js \
|
||||||
src/core/requote.js \
|
src/core/requote.js \
|
||||||
|
src/core/bisect.js \
|
||||||
src/core/xhr.js \
|
src/core/xhr.js \
|
||||||
src/core/text.js \
|
src/core/text.js \
|
||||||
src/core/json.js \
|
src/core/json.js \
|
||||||
|
@ -176,6 +177,8 @@ tests: \
|
||||||
tests/test-scale-log.test \
|
tests/test-scale-log.test \
|
||||||
tests/test-scale-sqrt.test \
|
tests/test-scale-sqrt.test \
|
||||||
tests/test-scale-pow.test \
|
tests/test-scale-pow.test \
|
||||||
|
tests/test-scale-quantile.test \
|
||||||
|
tests/test-bisect.test \
|
||||||
tests/test-svg-arc.test \
|
tests/test-svg-arc.test \
|
||||||
tests/test-svg-area.test \
|
tests/test-svg-area.test \
|
||||||
tests/test-svg-line.test \
|
tests/test-svg-line.test \
|
||||||
|
|
|
@ -236,6 +236,44 @@ d3.requote = function(s) {
|
||||||
};
|
};
|
||||||
|
|
||||||
var d3_requote_re = /[\\\^\$\*\+\?\[\]\(\)\.\{\}]/g;
|
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) {
|
d3.xhr = function(url, mime, callback) {
|
||||||
var req = new XMLHttpRequest();
|
var req = new XMLHttpRequest();
|
||||||
if (arguments.length < 3) callback = mime;
|
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]));
|
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) {
|
return function(x) {
|
||||||
var j = search(x);
|
var j = d3.bisect(domain, x, 1, domain.length - 1) - 1;
|
||||||
return i[j](u[j](x));
|
return i[j](u[j](x));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2417,26 +2444,21 @@ d3.scale.quantile = function() {
|
||||||
thresholds = [];
|
thresholds = [];
|
||||||
|
|
||||||
function rescale() {
|
function rescale() {
|
||||||
var i = -1,
|
var k = 0,
|
||||||
n = thresholds.length = range.length,
|
n = domain.length,
|
||||||
k = domain.length / n;
|
q = range.length,
|
||||||
while (++i < n) thresholds[i] = domain[~~(i * k)];
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
function scale(x) {
|
||||||
return range[quantile(x)];
|
if (isNaN(x = +x)) return NaN;
|
||||||
|
return range[d3.bisect(thresholds, x)];
|
||||||
}
|
}
|
||||||
|
|
||||||
scale.domain = function(x) {
|
scale.domain = function(x) {
|
||||||
|
|
44
d3.layout.js
44
d3.layout.js
|
@ -878,37 +878,35 @@ d3.layout.histogram = function() {
|
||||||
ticksFunction = d3_layout_histogramTicks;
|
ticksFunction = d3_layout_histogramTicks;
|
||||||
|
|
||||||
function histogram(data, i) {
|
function histogram(data, i) {
|
||||||
var x = data.map(value), bins = [];
|
var x = data.map(value),
|
||||||
|
bins = [],
|
||||||
// Initialize default ticks.
|
bin,
|
||||||
var ticks = ticksFunction.call(this, data, i);
|
ticks = ticksFunction.call(this, data, i),
|
||||||
|
i = -1,
|
||||||
|
n = x.length,
|
||||||
|
m = ticks.length - 1,
|
||||||
|
k = frequency ? 1 / n : 1;
|
||||||
|
|
||||||
// Initialize the bins.
|
// Initialize the bins.
|
||||||
for (var i = 0; i < ticks.length - 1; i++) {
|
while (++i < m) {
|
||||||
var bin = bins[i] = [];
|
bin = bins[i] = [];
|
||||||
bin.x = ticks[i];
|
bin.dx = ticks[i + 1] - (bin.x = ticks[i]);
|
||||||
bin.dx = ticks[i + 1] - ticks[i];
|
|
||||||
bin.y = 0;
|
bin.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count the number of samples per bin.
|
// Count the number of samples per bin.
|
||||||
for (var i = 0; i < x.length; i++) {
|
i = -1; while(++i < n) {
|
||||||
var bin = bins[d3_layout_histogramSearch(ticks, x[i])];
|
bin = bins[d3.bisect(ticks, x[i], 0, m - 1)];
|
||||||
bin.y++;
|
bin.y += k;
|
||||||
bin.push(data[i]);
|
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;
|
return bins;
|
||||||
}
|
}
|
||||||
|
|
||||||
histogram.frequency = function(x) {
|
histogram.frequency = function(x) {
|
||||||
if (!arguments.length) return frequency;
|
if (!arguments.length) return frequency;
|
||||||
frequency = Boolean(x);
|
frequency = !!x;
|
||||||
return histogram;
|
return histogram;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -927,18 +925,6 @@ d3.layout.histogram = function() {
|
||||||
return histogram;
|
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) {
|
function d3_layout_histogramTicks(x) {
|
||||||
return d3.scale.linear().domain(x).ticks(10);
|
return d3.scale.linear().domain(x).ticks(10);
|
||||||
}
|
}
|
||||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -10,18 +10,28 @@ body {
|
||||||
font: 10px sans-serif;
|
font: 10px sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rect {
|
||||||
|
fill: steelblue;
|
||||||
|
stroke: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
line {
|
||||||
|
stroke: black;
|
||||||
|
shape-rendering: crispEdges;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
// Generate an Irwin-Hall distribution.
|
|
||||||
var n = 10000, // number of trials
|
var n = 10000, // number of trials
|
||||||
m = 10, // number of random variables
|
m = 10, // number of random variables
|
||||||
data = [];
|
data = [];
|
||||||
|
|
||||||
|
// Generate an Irwin-Hall distribution.
|
||||||
for (var i = 0; i < n; i++) {
|
for (var i = 0; i < n; i++) {
|
||||||
var s = 0;
|
for (var s = 0, j = 0; j < m; j++) {
|
||||||
for (var j = 0; j < m; j++) {
|
|
||||||
s += Math.random();
|
s += Math.random();
|
||||||
}
|
}
|
||||||
data.push(s);
|
data.push(s);
|
||||||
|
@ -29,29 +39,44 @@ for (var i = 0; i < n; i++) {
|
||||||
|
|
||||||
var w = 400,
|
var w = 400,
|
||||||
h = 400,
|
h = 400,
|
||||||
x = d3.scale.linear().domain([0, m]).range([0, w]);
|
ticks = d3.range(0, m, .25);
|
||||||
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]);
|
|
||||||
|
|
||||||
var vis = d3.select("body")
|
var histogram = d3.layout.histogram()
|
||||||
.append("svg:svg")
|
.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("width", w)
|
||||||
.attr("height", h);
|
.attr("height", h)
|
||||||
|
.append("svg:g")
|
||||||
|
.attr("transform", "translate(.5)");
|
||||||
|
|
||||||
var bars = vis.selectAll("g.bar")
|
vis.selectAll("rect")
|
||||||
.data(bins)
|
.data(histogram(data))
|
||||||
.enter().append("svg:g")
|
.enter().append("svg:rect")
|
||||||
.attr("class", "bar")
|
.attr("transform", function(d) { return "translate(" + x(d.x) + "," + (h - y(d.y)) + ")"; })
|
||||||
.attr("transform", function(d, i) {
|
.attr("width", x.rangeBand())
|
||||||
return "translate(" + x(d.x) + "," + (h - y(d.y)) + ")";
|
.attr("y", function(d) { return y(d.y); })
|
||||||
});
|
.attr("height", 0)
|
||||||
|
.transition()
|
||||||
bars.append("svg:rect")
|
.duration(750)
|
||||||
.attr("fill", "steelblue")
|
.attr("y", 0)
|
||||||
.attr("width", function(d) { return x(d.dx) - 1; })
|
|
||||||
.attr("height", function(d) { return y(d.y); });
|
.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>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -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;
|
ticksFunction = d3_layout_histogramTicks;
|
||||||
|
|
||||||
function histogram(data, i) {
|
function histogram(data, i) {
|
||||||
var x = data.map(value), bins = [];
|
var x = data.map(value),
|
||||||
|
bins = [],
|
||||||
// Initialize default ticks.
|
bin,
|
||||||
var ticks = ticksFunction.call(this, data, i);
|
ticks = ticksFunction.call(this, data, i),
|
||||||
|
i = -1,
|
||||||
|
n = x.length,
|
||||||
|
m = ticks.length - 1,
|
||||||
|
k = frequency ? 1 / n : 1;
|
||||||
|
|
||||||
// Initialize the bins.
|
// Initialize the bins.
|
||||||
for (var i = 0; i < ticks.length - 1; i++) {
|
while (++i < m) {
|
||||||
var bin = bins[i] = [];
|
bin = bins[i] = [];
|
||||||
bin.x = ticks[i];
|
bin.dx = ticks[i + 1] - (bin.x = ticks[i]);
|
||||||
bin.dx = ticks[i + 1] - ticks[i];
|
|
||||||
bin.y = 0;
|
bin.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count the number of samples per bin.
|
// Count the number of samples per bin.
|
||||||
for (var i = 0; i < x.length; i++) {
|
i = -1; while(++i < n) {
|
||||||
var bin = bins[d3_layout_histogramSearch(ticks, x[i])];
|
bin = bins[d3.bisect(ticks, x[i], 0, m - 1)];
|
||||||
bin.y++;
|
bin.y += k;
|
||||||
bin.push(data[i]);
|
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;
|
return bins;
|
||||||
}
|
}
|
||||||
|
|
||||||
histogram.frequency = function(x) {
|
histogram.frequency = function(x) {
|
||||||
if (!arguments.length) return frequency;
|
if (!arguments.length) return frequency;
|
||||||
frequency = Boolean(x);
|
frequency = !!x;
|
||||||
return histogram;
|
return histogram;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,18 +51,6 @@ d3.layout.histogram = function() {
|
||||||
return histogram;
|
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) {
|
function d3_layout_histogramTicks(x) {
|
||||||
return d3.scale.linear().domain(x).ticks(10);
|
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]));
|
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) {
|
return function(x) {
|
||||||
var j = search(x);
|
var j = d3.bisect(domain, x, 1, domain.length - 1) - 1;
|
||||||
return i[j](u[j](x));
|
return i[j](u[j](x));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,26 +4,21 @@ d3.scale.quantile = function() {
|
||||||
thresholds = [];
|
thresholds = [];
|
||||||
|
|
||||||
function rescale() {
|
function rescale() {
|
||||||
var i = -1,
|
var k = 0,
|
||||||
n = thresholds.length = range.length,
|
n = domain.length,
|
||||||
k = domain.length / n;
|
q = range.length,
|
||||||
while (++i < n) thresholds[i] = domain[~~(i * k)];
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
function scale(x) {
|
||||||
return range[quantile(x)];
|
if (isNaN(x = +x)) return NaN;
|
||||||
|
return range[d3.bisect(thresholds, x)];
|
||||||
}
|
}
|
||||||
|
|
||||||
scale.domain = function(x) {
|
scale.domain = function(x) {
|
||||||
|
|
|
@ -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("");
|
|
@ -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("./../lib/env-js/envjs/node");
|
||||||
require("./../d3");
|
require("./../d3");
|
||||||
|
|
||||||
|
var f = d3.format(" .3f");
|
||||||
|
|
||||||
var x = d3.scale.linear().domain([-1, 0, 1]).range(["red", "white", "green"]);
|
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("domain(-1, 0, 1).range(red, white, green):");
|
||||||
console.log(" -0.5 -> ", x(-0.5));
|
console.log(" -1.0 -> " + x(-1));
|
||||||
console.log(" 0.0 -> ", x(0.0));
|
console.log(" -0.8 -> " + x(-.8));
|
||||||
console.log(" 0.5 -> ", x(0.5));
|
console.log(" -0.6 -> " + x(-.6));
|
||||||
console.log(" 1.0 -> ", x(1.0));
|
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("");
|
console.log("");
|
||||||
|
|
|
@ -1,6 +1,22 @@
|
||||||
domain([-1, 0, 1]).range(["red", "white", "green"]):
|
domain(-1, 0, 1).range(red, white, green):
|
||||||
-0.5 -> rgb(255,128,128)
|
-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.0 -> rgb(255,255,255)
|
||||||
0.5 -> rgb(128,192,128)
|
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)
|
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
|
||||||
|
|
Загрузка…
Ссылка в новой задаче