This repository has been archived by the owner on Jul 3, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
from d3/d3-array#151
- Loading branch information
Showing
16 changed files
with
1,978 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"extends": "eslint:recommended", | ||
"parserOptions": { | ||
"sourceType": "module", | ||
"ecmaVersion": 8 | ||
}, | ||
"env": { | ||
"es6": true, | ||
"node": true, | ||
"browser": true | ||
}, | ||
"rules": { | ||
"no-cond-assign": 0, | ||
"no-constant-condition": 0 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"problemMatcher": [ | ||
{ | ||
"owner": "eslint-compact", | ||
"pattern": [ | ||
{ | ||
"regexp": "^(.+):\\sline\\s(\\d+),\\scol\\s(\\d+),\\s(Error|Warning|Info)\\s-\\s(.+)\\s\\((.+)\\)$", | ||
"file": 1, | ||
"line": 2, | ||
"column": 3, | ||
"severity": 4, | ||
"message": 5, | ||
"code": 6 | ||
} | ||
] | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions | ||
|
||
name: Node.js CI | ||
|
||
on: | ||
push: | ||
branches: [ master ] | ||
pull_request: | ||
branches: [ master ] | ||
|
||
jobs: | ||
build: | ||
|
||
runs-on: ubuntu-latest | ||
|
||
strategy: | ||
matrix: | ||
node-version: [12.x] | ||
|
||
steps: | ||
- uses: actions/checkout@v2 | ||
- name: Use Node.js ${{ matrix.node-version }} | ||
uses: actions/setup-node@v1 | ||
with: | ||
node-version: ${{ matrix.node-version }} | ||
- run: yarn --frozen-lockfile | ||
- run: | | ||
echo ::add-matcher::.github/eslint.json | ||
yarn run eslint src --format=compact | ||
- run: yarn test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
*.sublime-workspace | ||
.DS_Store | ||
dist/ | ||
node_modules | ||
npm-debug.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
Copyright 2020 Fil | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without modification, | ||
are permitted provided that the following conditions are met: | ||
|
||
* Redistributions of source code must retain the above copyright notice, this | ||
list of conditions and the following disclaimer. | ||
|
||
* Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
* Neither the name of the author nor the names of contributors may be used to | ||
endorse or promote products derived from this software without specific prior | ||
written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# array-blur | ||
|
||
<a name="blur" href="#blur">#</a> <b>blur</b>() · [Source](https://github.com/fil/array-blur/blob/master/src/blur.js) | ||
|
||
Creates a blur transformer, which can blur (or smooth) an *array* of values by three iterations of a moving average transform. | ||
|
||
<a name="blur_radius" href="#blur_radius">#</a> *blur*.<b>radius</b>([*radius*]) | ||
|
||
If *radius* is specified, sets the radius of the transformation: on each iteration, the value of a point is transformed into the mean value of itself and the *radius* points of data surrounding it on the left and on the right (taking into account the edges). If *radius* is not specified, return the current radius (if horizontal and vertical radii have been set separately, returns their average value). If *radius* is not an integer value, the blurring is applied partially. Defaults to 5. | ||
|
||
<a name="blur_value" href="#blur_value">#</a> *blur*.<b>value</b>([*value*]) | ||
|
||
If *value* is specified, sets the *value* accessor, which will read the *array*. If not specified, return the current number. Defaults to the special *null* accessor, which copies the values directly (faster than an identity function). | ||
|
||
Example: | ||
```js | ||
const blurred = blur().value(d => d.temperature)(data); | ||
``` | ||
|
||
<a name="blur_width" href="#blur_width">#</a> *blur*.<b>width</b>([*width*]) | ||
|
||
If *width* is specified, sets the width of the transformation, otherwise returns the current width. When 0 < width < length, *blur* considers that the *array* describes values in two dimensions—as a rectangle of a certain width (height inferred as length divided by width). In that case each iteration involves an horizontal (x) blurring, followed by a vertical (y) blurring. Defaults to undefined (horizontal dimension). | ||
|
||
<a name="blur_radiusX" href="#blur_radiusX">#</a> *blur*.<b>radiusX</b>([*radius*]) | ||
|
||
If *radius* is specified, sets the horizontal radius of the transformation, otherwise returns it. (Use 0 for vertical blurring.) | ||
|
||
<a name="blur_radiusY" href="#blur_radiusY">#</a> *blur*.<b>radiusY</b>([*radius*]) | ||
|
||
If *radius* is specified, sets the vertical radius of the transformation, otherwise returns it. (Use 0 for horizontal blurring.) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"folders": [ | ||
{ | ||
"path": ".", | ||
"file_exclude_patterns": ["*.sublime-workspace"], | ||
"folder_exclude_patterns": ["dist"] | ||
} | ||
], | ||
"build_systems": [ | ||
{ | ||
"name": "yarn test", | ||
"cmd": ["yarn", "test"], | ||
"file_regex": "\\((...*?):([0-9]*):([0-9]*)\\)", | ||
"working_dir": "$project_path" | ||
} | ||
] | ||
} |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import {terser} from "rollup-plugin-terser"; | ||
import * as meta from "./package.json"; | ||
|
||
const config = { | ||
input: "src/index.js", | ||
external: Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)), | ||
output: { | ||
file: `dist/${meta.name}.js`, | ||
name: "d3", | ||
format: "umd", | ||
indent: false, | ||
extend: true, | ||
banner: `// ${meta.homepage} v${meta.version} Copyright ${(new Date).getFullYear()} ${meta.author.name}`, | ||
globals: Object.assign({}, ...Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)).map(key => ({[key]: "d3"}))) | ||
}, | ||
plugins: [] | ||
}; | ||
|
||
export default [ | ||
config, | ||
{ | ||
...config, | ||
output: { | ||
...config.output, | ||
file: `dist/${meta.name}.min.js` | ||
}, | ||
plugins: [ | ||
...config.plugins, | ||
terser({ | ||
output: { | ||
preamble: config.output.banner | ||
} | ||
}) | ||
] | ||
} | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import {floor, max, min} from "./math.js"; | ||
|
||
function blurTransfer(V, r, n, vertical) { | ||
if (!r) return; // radius 0 is a noop | ||
|
||
const iterations = 3, r0 = Math.floor(r); | ||
// for a non-integer radius, interpolate between floor(r) and ceil(r) | ||
if (r === r0) { | ||
for (let i = 0; i < iterations; i++) { | ||
blurTransferInt(V, r, n, vertical); | ||
} | ||
} else { | ||
const frac = r - r0, frac_1 = 1 - frac; | ||
const data = V[0].slice(); | ||
for (let i = 0; i < iterations; i++) { | ||
blurTransferInt(V, r0 + 1, n, vertical); | ||
} | ||
const data_ceil = V[0]; | ||
V[0] = data; | ||
if (r0 > 0) { | ||
for (let i = 0; i < iterations; i++) { | ||
blurTransferInt(V, r0, n, vertical); | ||
} | ||
} | ||
for (let i = 0; i < data.length; i++) { | ||
V[0][i] = V[0][i] * frac_1 + data_ceil[i] * frac; | ||
} | ||
} | ||
} | ||
|
||
function blurTransferInt(V, r, n, vertical) { | ||
const [source, target] = V, | ||
m = floor(source.length / n), | ||
w = 2 * r + 1, | ||
w1 = 1 / w, | ||
ki = vertical ? m : 1, | ||
kj = vertical ? 1 : n, | ||
W = w * ki, | ||
R = r * ki; | ||
|
||
for (let j = 0; j < m; ++j) { | ||
const k0 = kj * j, | ||
kn = k0 + ki * (n - 1); | ||
for (let i = 0, sr = w * source[k0]; i < n + r; ++i) { | ||
const k = ki * i + kj * j; | ||
sr += source[min(k, kn)] - source[max(k - W, k0)]; | ||
target[max(k - R, k0)] = sr * w1; | ||
} | ||
} | ||
V.reverse(); // target becomes V[0] and will be used as source in the next iteration | ||
} | ||
|
||
export default function blur() { | ||
let rx = 5, | ||
ry = rx, | ||
value, | ||
width; | ||
|
||
function blur(data) { | ||
const n = width || data.length, | ||
m = Math.round(data.length / n), | ||
V = [ | ||
value ? Float32Array.from(data, value) : Float32Array.from(data), | ||
new Float32Array(data.length) | ||
]; | ||
|
||
blurTransfer(V, rx, n, false); | ||
blurTransfer(V, ry, m, true); | ||
|
||
V[0].width = n; | ||
V[0].height = m; | ||
return V[0]; | ||
} | ||
|
||
blur.radius = _ => _ === undefined | ||
? (rx + ry) / 2 | ||
: (rx = ry = +_, blur); | ||
blur.radiusX = _ => _ === undefined | ||
? rx : (rx = +_, blur); | ||
blur.radiusY = _ => _ === undefined | ||
? ry : (ry = +_, blur); | ||
blur.width = _ => | ||
_ === undefined ? width : (width = Math.round(+_), blur); | ||
blur.value = _ => | ||
typeof _ === "function" ? (value = _, blur) : value; | ||
|
||
return blur; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export {default as blur} from "./blur.js"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export const floor = Math.floor; | ||
|
||
export const max = Math.max; | ||
|
||
export const min = Math.min; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
const tape = require("tape"), | ||
arrays = require("../"); | ||
|
||
require("./inDelta"); | ||
|
||
tape("blur() returns a default blur generator", function(test) { | ||
const h = arrays.blur(); | ||
test.equal(h.radius(), 5); | ||
test.equal(h.radiusX(), 5); | ||
test.equal(h.radiusY(), 5); | ||
test.equal(h.width(), undefined); | ||
test.equal(h.value(), undefined); | ||
test.end(); | ||
}); | ||
|
||
|
||
tape("blur() blurs in 1D", function(test) { | ||
const h = arrays.blur(); | ||
test.deepEqual( | ||
h.radius(1).width(0)([0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0]), | ||
Object.assign([0, 0, 0, 1, 3, 6, 7, 6, 3, 1, 0, 0, 0, 0], { width: 14, height: 1 }) | ||
); | ||
test.end(); | ||
}); | ||
|
||
tape("blur() blurs in 2D", function(test) { | ||
const h = arrays.blur(); | ||
test.deepEqual( | ||
h.width(4).radiusX(1).radiusY(1)([0, 0, 0, 0, 729, 0, 0, 0, 0, 0, 0, 0]), | ||
Object.assign([117, 81, 36, 9, 117, 81, 36, 9, 117, 81, 36, 9], { width: 4, height: 3 }) | ||
); | ||
test.end(); | ||
}); | ||
|
||
tape("blur().radiusY(0) blurs horizontally", function(test) { | ||
const h = arrays.blur(); | ||
test.deepEqual( | ||
h.width(4).radiusX(1).radiusY(0)([27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), | ||
Object.assign([13, 9, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0], { width: 4, height: 3 }) | ||
); | ||
test.end(); | ||
}); | ||
|
||
tape("blur().radiusX(0) blurs vertically", function(test) { | ||
const h = arrays.blur(); | ||
test.deepEqual( | ||
h.width(4).radiusX(0).radiusY(1)([0, 0, 0, 27, 3, -9, 0, 0, 0, 0, 0, 0]), | ||
Object.assign([1, -3, 0, 13, 1, -3, 0, 9, 1, -3, 0, 5], { width: 4, height: 3 }) | ||
); | ||
test.end(); | ||
}); | ||
|
||
tape("blur().radius(0.5) does a fraction of blur", function(test) { | ||
const h = arrays.blur().width(5), V = [0,0,0,0,0, 0,0,5184,0,0, 0,0,0,0,0]; | ||
test.deepEqual( | ||
h.radius(0.5)(V), | ||
Object.assign([64, 96, 544, 96, 64, 256, 384, 2176, 384, 256, 64, 96, 544, 96, 64], { width: 5, height: 3 }) | ||
); | ||
test.end(); | ||
}); | ||
|
||
tape("blur().radius(1.2) does a fraction of blur", function(test) { | ||
const h = arrays.blur(), V = [0,0,0,0,0, 0,0,1,0,0, 0,0,0,0,0]; | ||
const V1 = h.radius(1)(V); | ||
const V2 = h.radius(2)(V); | ||
for (let i = 0; i < V1.length; i++) V1[i] = 0.8 * V1[i] + 0.2 * V2[i]; | ||
test.inDelta(Array.from(h.radius(1.2)(V)), Array.from(V1)); | ||
test.end(); | ||
}); | ||
|
||
|
||
tape("blur().radius() returns the (average) radius", function(test) { | ||
const h = arrays.blur(); | ||
test.equal(h.width(2).radiusX(1).radiusY(1).radius(), 1); | ||
test.equal(h.width(2).radius(2).radius(), 2); | ||
test.equal(h.width(2).radiusX(1).radiusY(5).radius(), 3); | ||
test.end(); | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
var tape = require("tape"); | ||
|
||
tape.Test.prototype.inDelta = function(actual, expected, delta) { | ||
delta = delta || 1e-6; | ||
this._assert(inDelta(actual, expected, delta), { | ||
message: "should be in delta " + delta, | ||
operator: "inDelta", | ||
actual: actual, | ||
expected: expected | ||
}); | ||
}; | ||
|
||
function inDelta(actual, expected, delta) { | ||
return (Array.isArray(expected) ? inDeltaArray : inDeltaNumber)(actual, expected, delta); | ||
} | ||
|
||
function inDeltaArray(actual, expected, delta) { | ||
var n = expected.length, i = -1; | ||
if (actual.length !== n) return false; | ||
while (++i < n) if (!inDelta(actual[i], expected[i], delta)) return false; | ||
return true; | ||
} | ||
|
||
function inDeltaNumber(actual, expected, delta) { | ||
return actual >= expected - delta && actual <= expected + delta; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash | ||
|
||
tape ${@:-'test/**/*-test.js'} && eslint src |
Oops, something went wrong.