diff --git a/package.json b/package.json index 1ed6c95..f9aac0e 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ }, "sideEffects": false, "dependencies": { - "d3-array": "2 - 3" + "d3-array": "^3.2.0" }, "devDependencies": { "d3-axis": "3", diff --git a/src/blur.js b/src/blur.js deleted file mode 100644 index 0edfb3e..0000000 --- a/src/blur.js +++ /dev/null @@ -1,43 +0,0 @@ -// TODO Optimize edge cases. -// TODO Optimize index calculation. -// TODO Optimize arguments. -export function blurX(source, target, r) { - var n = source.width, - m = source.height, - w = (r << 1) + 1; - for (var j = 0; j < m; ++j) { - for (var i = 0, sr = 0; i < n + r; ++i) { - if (i < n) { - sr += source.data[i + j * n]; - } - if (i >= r) { - if (i >= w) { - sr -= source.data[i - w + j * n]; - } - target.data[i - r + j * n] = sr / Math.min(i + 1, n - 1 + w - i, w); - } - } - } -} - -// TODO Optimize edge cases. -// TODO Optimize index calculation. -// TODO Optimize arguments. -export function blurY(source, target, r) { - var n = source.width, - m = source.height, - w = (r << 1) + 1; - for (var i = 0; i < n; ++i) { - for (var j = 0, sr = 0; j < m + r; ++j) { - if (j < m) { - sr += source.data[i + j * n]; - } - if (j >= r) { - if (j >= w) { - sr -= source.data[i + (j - w) * n]; - } - target.data[i + (j - r) * n] = sr / Math.min(j + 1, m - 1 + w - j, w); - } - } - } -} diff --git a/src/density.js b/src/density.js index 87f791b..ab99573 100644 --- a/src/density.js +++ b/src/density.js @@ -1,6 +1,5 @@ -import {max, ticks} from "d3-array"; +import {blur2, max, ticks} from "d3-array"; import {slice} from "./array.js"; -import {blurX, blurY} from "./blur.js"; import constant from "./constant.js"; import Contours from "./contours.js"; @@ -30,12 +29,12 @@ export default function() { threshold = constant(20); function grid(data) { - var values0 = new Float32Array(n * m), - values1 = new Float32Array(n * m), - pow2k = Math.pow(2, -k); + var values = new Float32Array(n * m), + pow2k = Math.pow(2, -k), + i = -1; - data.forEach(function(d, i, data) { - var xi = (x(d, i, data) + o) * pow2k, + for (const d of data) { + var xi = (x(d, ++i, data) + o) * pow2k, yi = (y(d, i, data) + o) * pow2k, wi = +weight(d, i, data); if (xi >= 0 && xi < n && yi >= 0 && yi < m) { @@ -43,22 +42,15 @@ export default function() { y0 = Math.floor(yi), xt = xi - x0 - 0.5, yt = yi - y0 - 0.5; - values0[x0 + y0 * n] += (1 - xt) * (1 - yt) * wi; - values0[x0 + 1 + y0 * n] += xt * (1 - yt) * wi; - values0[x0 + 1 + (y0 + 1) * n] += xt * yt * wi; - values0[x0 + (y0 + 1) * n] += (1 - xt) * yt * wi; + values[x0 + y0 * n] += (1 - xt) * (1 - yt) * wi; + values[x0 + 1 + y0 * n] += xt * (1 - yt) * wi; + values[x0 + 1 + (y0 + 1) * n] += xt * yt * wi; + values[x0 + (y0 + 1) * n] += (1 - xt) * yt * wi; } - }); - - // TODO Optimize. - blurX({width: n, height: m, data: values0}, {width: n, height: m, data: values1}, r >> k); - blurY({width: n, height: m, data: values1}, {width: n, height: m, data: values0}, r >> k); - blurX({width: n, height: m, data: values0}, {width: n, height: m, data: values1}, r >> k); - blurY({width: n, height: m, data: values1}, {width: n, height: m, data: values0}, r >> k); - blurX({width: n, height: m, data: values0}, {width: n, height: m, data: values1}, r >> k); - blurY({width: n, height: m, data: values1}, {width: n, height: m, data: values0}, r >> k); + } - return values0; + blur2({data: values, width: n, height: m}, r * pow2k); + return values; } function density(data) { @@ -150,7 +142,7 @@ export default function() { density.bandwidth = function(_) { if (!arguments.length) return Math.sqrt(r * (r + 1)); if (!((_ = +_) >= 0)) throw new Error("invalid bandwidth"); - return r = Math.round((Math.sqrt(4 * _ * _ + 1) - 1) / 2), resize(); + return r = (Math.sqrt(4 * _ * _ + 1) - 1) / 2, resize(); }; return density; diff --git a/test/density-test.js b/test/density-test.js index dc67847..775eacf 100644 --- a/test/density-test.js +++ b/test/density-test.js @@ -78,7 +78,7 @@ it("contourDensity(data) returns nice default thresholds", async () => { .bandwidth(30) (faithful); - assert.deepStrictEqual(contour.map(c => c.value), ticks(0.0002, 0.006, 30)); + assert.deepStrictEqual(contour.map(c => c.value), ticks(0.0002, 0.0059, 30)); }); it("contourDensity.contours(data) preserves the specified threshold exactly", async () => { diff --git a/test/output/faithfulContour.svg b/test/output/faithfulContour.svg index 77cd8ac..a4f757d 100644 --- a/test/output/faithfulContour.svg +++ b/test/output/faithfulContour.svg @@ -344,35 +344,34 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/output/faithfulContours.svg b/test/output/faithfulContours.svg index 3c771c8..ebfc061 100644 --- a/test/output/faithfulContours.svg +++ b/test/output/faithfulContours.svg @@ -344,35 +344,34 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index dbe3b6e..abac867 100644 --- a/yarn.lock +++ b/yarn.lock @@ -382,10 +382,10 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3": - version "3.1.6" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.1.6.tgz#0342c835925826f49b4d16eb7027aec334ffc97d" - integrity sha512-DCbBBNuKOeiR9h04ySRBMW52TFVc91O9wJziuyXw6Ztmy8D3oZbmCkOO3UHKC7ceNJsN2Mavo9+vwV8EAEUXzA== +"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.0.tgz#15bf96cd9b7333e02eb8de8053d78962eafcff14" + integrity sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g== dependencies: internmap "1 - 2"