Adopt type=module (#192)
* Adopt type=module follow changes in d3-format: * type=module * add exports * remove zip * license: ISC * update dependencies * es6 rather than no-undef * remove Sublime project * add eslint.json * related d3/d3#3502; extract copyrights from LICENSE * update dependencies * stricter eslint * cleaner imports * Update README Co-authored-by: Mike Bostock <mbostock@gmail.com>
This commit is contained in:
parent
8c4d113979
commit
8aed9d462f
|
|
@ -5,9 +5,7 @@
|
|||
"ecmaVersion": 8
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true,
|
||||
"browser": true
|
||||
"es6": true
|
||||
},
|
||||
"rules": {
|
||||
"no-cond-assign": 0
|
||||
|
|
|
|||
18
.github/eslint.json
vendored
Normal file
18
.github/eslint.json
vendored
Normal file
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
30
.github/workflows/node.js.yml
vendored
Normal file
30
.github/workflows/node.js.yml
vendored
Normal file
|
|
@ -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: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [14.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 test --format=compact
|
||||
- run: yarn test
|
||||
36
LICENSE
36
LICENSE
|
|
@ -1,27 +1,13 @@
|
|||
Copyright 2010-2016 Mike Bostock
|
||||
All rights reserved.
|
||||
Copyright 2010-2021 Mike Bostock
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose
|
||||
with or without fee is hereby granted, provided that the above copyright notice
|
||||
and this permission notice appear in all copies.
|
||||
|
||||
* 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.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
|
||||
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
||||
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
|
|
|
|||
24
README.md
24
README.md
|
|
@ -18,16 +18,28 @@ To use this module, create a [simulation](#simulation) for an array of [nodes](#
|
|||
|
||||
## Installing
|
||||
|
||||
If you use NPM, `npm install d3-force`. Otherwise, download the [latest release](https://github.com/d3/d3-force/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-force.v2.min.js) or as part of [D3](https://github.com/d3/d3). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3_force` global is exported:
|
||||
If you use npm, `npm install d3-force`. You can also download the [latest release on GitHub](https://github.com/d3/d3-force/releases/latest). For vanilla HTML in modern browsers, import d3-force from Skypack:
|
||||
|
||||
```html
|
||||
<script src="https://d3js.org/d3-dispatch.v2.min.js"></script>
|
||||
<script src="https://d3js.org/d3-quadtree.v2.min.js"></script>
|
||||
<script src="https://d3js.org/d3-timer.v2.min.js"></script>
|
||||
<script src="https://d3js.org/d3-force.v2.min.js"></script>
|
||||
<script type="module">
|
||||
|
||||
import {forceSimulation} from "https://cdn.skypack.dev/d3-force@3";
|
||||
|
||||
const simulation = forceSimulation(nodes);
|
||||
|
||||
</script>
|
||||
```
|
||||
|
||||
For legacy environments, you can load d3-force’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
|
||||
|
||||
```html
|
||||
<script src="https://cdn.jsdelivr.net/npm/d3-dispatch@3"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/d3-quadtree@3"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/d3-timer@3"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/d3-force@3"></script>
|
||||
<script>
|
||||
|
||||
var simulation = d3.forceSimulation(nodes);
|
||||
const simulation = d3.forceSimulation(nodes);
|
||||
|
||||
</script>
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
}
|
||||
57
package.json
57
package.json
|
|
@ -2,6 +2,11 @@
|
|||
"name": "d3-force",
|
||||
"version": "2.1.1",
|
||||
"description": "Force-directed graph layout using velocity Verlet integration.",
|
||||
"homepage": "https://d3js.org/d3-force/",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/d3/d3-force.git"
|
||||
},
|
||||
"keywords": [
|
||||
"d3",
|
||||
"d3-module",
|
||||
|
|
@ -12,40 +17,42 @@
|
|||
"verlet",
|
||||
"infovis"
|
||||
],
|
||||
"homepage": "https://d3js.org/d3-force/",
|
||||
"license": "BSD-3-Clause",
|
||||
"license": "ISC",
|
||||
"author": {
|
||||
"name": "Mike Bostock",
|
||||
"url": "http://bost.ocks.org/mike"
|
||||
},
|
||||
"main": "dist/d3-force.js",
|
||||
"unpkg": "dist/d3-force.min.js",
|
||||
"jsdelivr": "dist/d3-force.min.js",
|
||||
"module": "src/index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/d3/d3-force.git"
|
||||
},
|
||||
"scripts": {
|
||||
"pretest": "rollup -c",
|
||||
"test": "tape 'test/**/*-test.js' && eslint src",
|
||||
"prepublishOnly": "rm -rf dist && yarn test",
|
||||
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd - && zip -j dist/${npm_package_name}.zip -- LICENSE README.md dist/${npm_package_name}.js dist/${npm_package_name}.min.js"
|
||||
"url": "https://bost.ocks.org/mike"
|
||||
},
|
||||
"type": "module",
|
||||
"files": [
|
||||
"src/**/*.js",
|
||||
"dist/**/*.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"d3-dispatch": "1 - 2",
|
||||
"d3-quadtree": "1 - 2",
|
||||
"d3-timer": "1 - 2"
|
||||
"module": "src/index.js",
|
||||
"main": "src/index.js",
|
||||
"jsdelivr": "dist/d3-force.min.js",
|
||||
"unpkg": "dist/d3-force.min.js",
|
||||
"exports": {
|
||||
"umd": "./dist/d3-force.min.js",
|
||||
"default": "./src/index.js"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"dependencies": {
|
||||
"d3-dispatch": "1 - 3",
|
||||
"d3-quadtree": "1 - 3",
|
||||
"d3-timer": "1 - 3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "6",
|
||||
"rollup": "1",
|
||||
"rollup-plugin-terser": "5",
|
||||
"tape": "4"
|
||||
"eslint": "7",
|
||||
"mocha": "8",
|
||||
"rollup": "2",
|
||||
"rollup-plugin-terser": "7"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha 'test/**/*-test.js' && eslint src test",
|
||||
"prepublishOnly": "rm -rf dist && yarn test && rollup -c",
|
||||
"postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
import {readFileSync} from "fs";
|
||||
import {terser} from "rollup-plugin-terser";
|
||||
import * as meta from "./package.json";
|
||||
|
||||
// Extract copyrights from the LICENSE.
|
||||
const copyright = readFileSync("./LICENSE", "utf-8")
|
||||
.split(/\n/g)
|
||||
.filter(line => /^Copyright\s+/.test(line))
|
||||
.map(line => line.replace(/^Copyright\s+/, ""))
|
||||
.join(", ");
|
||||
|
||||
const config = {
|
||||
input: "src/index.js",
|
||||
external: Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)),
|
||||
|
|
@ -10,7 +18,7 @@ const config = {
|
|||
format: "umd",
|
||||
indent: false,
|
||||
extend: true,
|
||||
banner: `// ${meta.homepage} v${meta.version} Copyright ${(new Date).getFullYear()} ${meta.author.name}`,
|
||||
banner: `// ${meta.homepage} v${meta.version} Copyright ${copyright}`,
|
||||
globals: Object.assign({}, ...Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)).map(key => ({[key]: "d3"})))
|
||||
},
|
||||
plugins: []
|
||||
|
|
|
|||
11
test/.eslintrc.json
Normal file
11
test/.eslintrc.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"ecmaVersion": 8
|
||||
},
|
||||
"env": {
|
||||
"es6": true,
|
||||
"mocha": true
|
||||
}
|
||||
}
|
||||
15
test/asserts.js
Normal file
15
test/asserts.js
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import assert from "assert";
|
||||
|
||||
export function assertNodeEqual(actual, expected, delta = 1e-6) {
|
||||
assert(nodeEqual(actual, expected, delta), `${actual} and ${expected} should be similar`);
|
||||
}
|
||||
|
||||
function nodeEqual(actual, expected, delta) {
|
||||
return actual.index == expected.index
|
||||
&& Math.abs(actual.x - expected.x) < delta
|
||||
&& Math.abs(actual.vx - expected.vx) < delta
|
||||
&& Math.abs(actual.y - expected.y) < delta
|
||||
&& Math.abs(actual.vy - expected.vy) < delta
|
||||
&& !(Math.abs(actual.fx - expected.fx) > delta)
|
||||
&& !(Math.abs(actual.fy - expected.fy) > delta);
|
||||
}
|
||||
|
|
@ -1,27 +1,22 @@
|
|||
var tape = require("tape"),
|
||||
force = require("../");
|
||||
import {forceCenter, forceSimulation} from "../src/index.js";
|
||||
import {assertNodeEqual} from "./asserts.js";
|
||||
|
||||
require("./nodeEqual.js");
|
||||
|
||||
tape("forceCenter repositions nodes", function(test) {
|
||||
const center = force.forceCenter(0, 0);
|
||||
const f = force.forceSimulation().force("center", center).stop();
|
||||
const a = { x: 100, y: 0 }, b = { x: 200, y: 0 }, c = { x: 300, y: 0 };
|
||||
it("forceCenter repositions nodes", () => {
|
||||
const center = forceCenter(0, 0);
|
||||
const f = forceSimulation().force("center", center).stop();
|
||||
const a = {x: 100, y: 0}, b = {x: 200, y: 0}, c = {x: 300, y: 0};
|
||||
f.nodes([a, b, c]);
|
||||
f.tick();
|
||||
test.nodeEqual(a, { index: 0, x: -100, y: 0, vy: 0, vx: 0 });
|
||||
test.nodeEqual(b, { index: 1, x: 0, y: 0, vy: 0, vx: 0 });
|
||||
test.nodeEqual(c, { index: 2, x: 100, y: 0, vy: 0, vx: 0 });
|
||||
test.end();
|
||||
assertNodeEqual(a, {index: 0, x: -100, y: 0, vy: 0, vx: 0});
|
||||
assertNodeEqual(b, {index: 1, x: 0, y: 0, vy: 0, vx: 0});
|
||||
assertNodeEqual(c, {index: 2, x: 100, y: 0, vy: 0, vx: 0});
|
||||
});
|
||||
|
||||
|
||||
tape("forceCenter respects fixed positions", function(test) {
|
||||
const center = force.forceCenter();
|
||||
const f = force.forceSimulation().force("center", center).stop();
|
||||
const a = { fx: 0, fy:0 }, b = {}, c = {};
|
||||
it("forceCenter respects fixed positions", () => {
|
||||
const center = forceCenter();
|
||||
const f = forceSimulation().force("center", center).stop();
|
||||
const a = {fx: 0, fy: 0}, b = {}, c = {};
|
||||
f.nodes([a, b, c]);
|
||||
f.tick();
|
||||
test.nodeEqual(a, { fx: 0, fy: 0, index: 0, x: 0, y: 0, vy: 0, vx: 0 });
|
||||
test.end();
|
||||
assertNodeEqual(a, {fx: 0, fy: 0, index: 0, x: 0, y: 0, vy: 0, vx: 0});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,57 +1,50 @@
|
|||
var tape = require("tape"),
|
||||
force = require("../");
|
||||
import assert from "assert";
|
||||
import {forceCollide, forceSimulation} from "../src/index.js";
|
||||
import {assertNodeEqual} from "./asserts.js";
|
||||
|
||||
require("./nodeEqual.js");
|
||||
|
||||
tape("forceCollide collides nodes", function(test) {
|
||||
const collide = force.forceCollide(1);
|
||||
const f = force.forceSimulation().force("collide", collide).stop();
|
||||
it("forceCollide collides nodes", () => {
|
||||
const collide = forceCollide(1);
|
||||
const f = forceSimulation().force("collide", collide).stop();
|
||||
const a = {}, b = {}, c = {};
|
||||
f.nodes([a, b, c]);
|
||||
f.tick(10);
|
||||
test.nodeEqual(a, { index: 0, x: 7.0710678118654755, y: 0, vy: 0, vx: 0 });
|
||||
test.nodeEqual(b, { index: 1, x: -9.03088751750192, y: 8.27303273571596, vy: 0, vx: 0 });
|
||||
test.nodeEqual(c, { index: 2, x: 1.3823220809823638, y: -15.750847141167634, vy: 0, vx: 0 });
|
||||
assertNodeEqual(a, {index: 0, x: 7.0710678118654755, y: 0, vy: 0, vx: 0});
|
||||
assertNodeEqual(b, {index: 1, x: -9.03088751750192, y: 8.27303273571596, vy: 0, vx: 0});
|
||||
assertNodeEqual(c, {index: 2, x: 1.3823220809823638, y: -15.750847141167634, vy: 0, vx: 0});
|
||||
collide.radius(100);
|
||||
f.tick(10);
|
||||
test.nodeEqual(a, { index: 0, x: 174.08616723117228, y: 66.51743051995625, vy: 0.26976816231064354, vx: 0.677346615710878 });
|
||||
test.nodeEqual(b, { index: 1, x: -139.73606544743998, y: 95.69860503079263, vy: 0.3545632444404687, vx: -0.5300880593105067 });
|
||||
test.nodeEqual(c, { index: 2, x: -34.9275994083864, y: -169.69384995620052, vy: -0.6243314067511122, vx: -0.1472585564003713 });
|
||||
test.end();
|
||||
assertNodeEqual(a, {index: 0, x: 174.08616723117228, y: 66.51743051995625, vy: 0.26976816231064354, vx: 0.677346615710878});
|
||||
assertNodeEqual(b, {index: 1, x: -139.73606544743998, y: 95.69860503079263, vy: 0.3545632444404687, vx: -0.5300880593105067});
|
||||
assertNodeEqual(c, {index: 2, x: -34.9275994083864, y: -169.69384995620052, vy: -0.6243314067511122, vx: -0.1472585564003713});
|
||||
});
|
||||
|
||||
|
||||
tape("forceCollide respects fixed positions", function(test) {
|
||||
const collide = force.forceCollide(1);
|
||||
const f = force.forceSimulation().force("collide", collide).stop();
|
||||
const a = { fx: 0, fy:0 }, b = {}, c = {};
|
||||
it("forceCollide respects fixed positions", () => {
|
||||
const collide = forceCollide(1);
|
||||
const f = forceSimulation().force("collide", collide).stop();
|
||||
const a = {fx: 0, fy: 0}, b = {}, c = {};
|
||||
f.nodes([a, b, c]);
|
||||
f.tick(10);
|
||||
test.nodeEqual(a, { fx: 0, fy: 0, index: 0, x: 0, y: 0, vy: 0, vx: 0 });
|
||||
assertNodeEqual(a, {fx: 0, fy: 0, index: 0, x: 0, y: 0, vy: 0, vx: 0});
|
||||
collide.radius(100);
|
||||
f.tick(10);
|
||||
test.nodeEqual(a, { fx: 0, fy: 0, index: 0, x: 0, y: 0, vy: 0, vx: 0 });
|
||||
test.end();
|
||||
assertNodeEqual(a, {fx: 0, fy: 0, index: 0, x: 0, y: 0, vy: 0, vx: 0});
|
||||
});
|
||||
|
||||
tape("forceCollide jiggles equal positions", function(test) {
|
||||
const collide = force.forceCollide(1);
|
||||
const f = force.forceSimulation().force("collide", collide).stop();
|
||||
const a = { x: 0, y:0 }, b = { x:0, y: 0 };
|
||||
it("forceCollide jiggles equal positions", () => {
|
||||
const collide = forceCollide(1);
|
||||
const f = forceSimulation().force("collide", collide).stop();
|
||||
const a = {x: 0, y: 0}, b = {x: 0, y: 0};
|
||||
f.nodes([a, b]);
|
||||
f.tick();
|
||||
test.assert(a.x !== b.x);
|
||||
test.assert(a.y !== b.y);
|
||||
test.equal(a.vx, -b.vx);
|
||||
test.equal(a.vy, -b.vy);
|
||||
test.end();
|
||||
assert(a.x !== b.x);
|
||||
assert(a.y !== b.y);
|
||||
assert.strictEqual(a.vx, -b.vx);
|
||||
assert.strictEqual(a.vy, -b.vy);
|
||||
});
|
||||
|
||||
tape("forceCollide jiggles in a reproducible way", function(test) {
|
||||
const nodes = Array.from({length:10}, () => ({x:0,y:0}));
|
||||
force.forceSimulation()
|
||||
.nodes(nodes)
|
||||
.force("collide", force.forceCollide()).stop().tick(50);
|
||||
test.nodeEqual(nodes[0], {x: -5.371433857229194, y: -2.6644608278592576, index: 0, vy: 0, vx: 0});
|
||||
test.end();
|
||||
it("forceCollide jiggles in a reproducible way", () => {
|
||||
const nodes = Array.from({length:10}, () => ({x: 0, y: 0}));
|
||||
forceSimulation().nodes(nodes).force("collide", forceCollide()).stop().tick(50);
|
||||
assertNodeEqual(nodes[0], {x: -5.371433857229194, y: -2.6644608278592576, index: 0, vy: 0, vx: 0});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,24 +1,19 @@
|
|||
var tape = require("tape"),
|
||||
force = require("../");
|
||||
import assert from "assert";
|
||||
import {forceSimulation} from "../src/index.js";
|
||||
|
||||
require("./nodeEqual.js");
|
||||
|
||||
tape("simulation.find finds a node", function(test) {
|
||||
const f = force.forceSimulation().stop();
|
||||
const a = { x: 5, y: 0 }, b = { x: 10, y: 16 }, c = { x: -10, y: -4};
|
||||
it("simulation.find finds a node", () => {
|
||||
const f = forceSimulation().stop();
|
||||
const a = {x: 5, y: 0}, b = {x: 10, y: 16}, c = {x: -10, y: -4};
|
||||
f.nodes([a, b, c]);
|
||||
test.equal(f.find(0, 0), a);
|
||||
test.equal(f.find(0, 20), b);
|
||||
test.end();
|
||||
assert.strictEqual(f.find(0, 0), a);
|
||||
assert.strictEqual(f.find(0, 20), b);
|
||||
});
|
||||
|
||||
tape("simulation.find(x, y, radius) finds a node within radius", function(test) {
|
||||
const f = force.forceSimulation().stop();
|
||||
const a = { x: 5, y: 0 }, b = { x: 10, y: 16 }, c = { x: -10, y: -4};
|
||||
it("simulation.find(x, y, radius) finds a node within radius", () => {
|
||||
const f = forceSimulation().stop();
|
||||
const a = {x: 5, y: 0}, b = {x: 10, y: 16}, c = {x: -10, y: -4};
|
||||
f.nodes([a, b, c]);
|
||||
test.equal(f.find(0, 0), a);
|
||||
test.equal(f.find(0, 0, 1), undefined);
|
||||
test.equal(f.find(0, 20), b);
|
||||
test.end();
|
||||
assert.strictEqual(f.find(0, 0), a);
|
||||
assert.strictEqual(f.find(0, 0, 1), undefined);
|
||||
assert.strictEqual(f.find(0, 20), b);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
var tape = require("tape");
|
||||
|
||||
tape.Test.prototype.nodeEqual = nodeEqual;
|
||||
|
||||
function nodeEqual(actual, expected, delta) {
|
||||
delta = delta || 1e-6;
|
||||
this._assert(nodeEqual(actual, expected, delta), {
|
||||
message: "should be similar",
|
||||
operator: "nodeEqual",
|
||||
actual: actual,
|
||||
expected: expected
|
||||
});
|
||||
|
||||
function nodeEqual(actual, expected, delta) {
|
||||
return actual.index == expected.index
|
||||
&& Math.abs(actual.x - expected.x) < delta
|
||||
&& Math.abs(actual.vx - expected.vx) < delta
|
||||
&& Math.abs(actual.y - expected.y) < delta
|
||||
&& Math.abs(actual.vy - expected.vy) < delta
|
||||
&& !(Math.abs(actual.fx - expected.fx) > delta)
|
||||
&& !(Math.abs(actual.fy - expected.fy) > delta);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,18 @@
|
|||
var tape = require("tape"),
|
||||
force = require("../");
|
||||
import assert from "assert";
|
||||
import {forceSimulation} from "../src/index.js";
|
||||
import {assertNodeEqual} from "./asserts.js";
|
||||
|
||||
require("./nodeEqual.js");
|
||||
|
||||
tape("forceSimulation() returns a simulation", function(test) {
|
||||
const f = force.forceSimulation().stop();
|
||||
test.deepEqual(Object.keys(f).sort(), [ 'alpha', 'alphaDecay', 'alphaMin', 'alphaTarget', 'find', 'force', 'nodes', 'on', 'randomSource', 'restart', 'stop', 'tick', 'velocityDecay' ]);
|
||||
test.end();
|
||||
it("forceSimulation() returns a simulation", () => {
|
||||
const f = forceSimulation().stop();
|
||||
assert.deepStrictEqual(Object.keys(f).sort(), [ 'alpha', 'alphaDecay', 'alphaMin', 'alphaTarget', 'find', 'force', 'nodes', 'on', 'randomSource', 'restart', 'stop', 'tick', 'velocityDecay' ]);
|
||||
});
|
||||
|
||||
tape("simulation.nodes(nodes) initializes a simulation with indices & phyllotaxis positions, 0 speed", function(test) {
|
||||
const f = force.forceSimulation().stop();
|
||||
it("simulation.nodes(nodes) initializes a simulation with indices & phyllotaxis positions, 0 speed", () => {
|
||||
const f = forceSimulation().stop();
|
||||
const a = {}, b = {}, c = {};
|
||||
f.nodes([a, b, c]);
|
||||
test.nodeEqual(a, { index: 0, x: 7.0710678118654755, y: 0, vy: 0, vx: 0 });
|
||||
test.nodeEqual(b, { index: 1, x: -9.03088751750192, y: 8.27303273571596, vy: 0, vx: 0 });
|
||||
test.nodeEqual(c, { index: 2, x: 1.3823220809823638, y: -15.750847141167634, vy: 0, vx: 0 });
|
||||
test.end();
|
||||
assertNodeEqual(a, {index: 0, x: 7.0710678118654755, y: 0, vy: 0, vx: 0});
|
||||
assertNodeEqual(b, {index: 1, x: -9.03088751750192, y: 8.27303273571596, vy: 0, vx: 0});
|
||||
assertNodeEqual(c, {index: 2, x: 1.3823220809823638, y: -15.750847141167634, vy: 0, vx: 0});
|
||||
});
|
||||
|
||||
|
|
|
|||
101
test/x-test.js
101
test/x-test.js
|
|
@ -1,84 +1,77 @@
|
|||
var tape = require("tape"),
|
||||
force = require("../");
|
||||
import assert from "assert";
|
||||
import {forceSimulation, forceX, forceY} from "../src/index.js";
|
||||
import {assertNodeEqual} from "./asserts.js";
|
||||
|
||||
require("./nodeEqual.js");
|
||||
|
||||
tape("forceX centers nodes", function(test) {
|
||||
const x = force.forceX(200);
|
||||
const f = force.forceSimulation().force("x", x).stop();
|
||||
it("forceX centers nodes", () => {
|
||||
const x = forceX(200);
|
||||
const f = forceSimulation().force("x", x).stop();
|
||||
const a = { x: 100, y: 0 }, b = { x: 200, y: 0 }, c = { x: 300, y: 0 };
|
||||
f.nodes([a, b, c]);
|
||||
f.tick(30);
|
||||
test.assert(a.x > 190);
|
||||
test.assert(a.vx > 0);
|
||||
test.equal(b.x, 200);
|
||||
test.equal(b.vx, 0);
|
||||
test.assert(c.x < 210);
|
||||
test.assert(c.vx < 0);
|
||||
test.end();
|
||||
assert(a.x > 190);
|
||||
assert(a.vx > 0);
|
||||
assert.strictEqual(b.x, 200);
|
||||
assert.strictEqual(b.vx, 0);
|
||||
assert(c.x < 210);
|
||||
assert(c.vx < 0);
|
||||
});
|
||||
|
||||
tape("forceY centers nodes", function(test) {
|
||||
const y = force.forceY(200);
|
||||
const f = force.forceSimulation().force("y", y).stop();
|
||||
it("forceY centers nodes", () => {
|
||||
const y = forceY(200);
|
||||
const f = forceSimulation().force("y", y).stop();
|
||||
const a = { y: 100, x: 0 }, b = { y: 200, x: 0 }, c = { y: 300, x: 0 };
|
||||
f.nodes([a, b, c]);
|
||||
f.tick(30);
|
||||
test.assert(a.y > 190);
|
||||
test.assert(a.vy > 0);
|
||||
test.equal(b.y, 200);
|
||||
test.equal(b.vy, 0);
|
||||
test.assert(c.y < 210);
|
||||
test.assert(c.vy < 0);
|
||||
test.end();
|
||||
assert(a.y > 190);
|
||||
assert(a.vy > 0);
|
||||
assert.strictEqual(b.y, 200);
|
||||
assert.strictEqual(b.vy, 0);
|
||||
assert(c.y < 210);
|
||||
assert(c.vy < 0);
|
||||
});
|
||||
|
||||
tape("forceX respects fixed positions", function(test) {
|
||||
const x = force.forceX(200);
|
||||
const f = force.forceSimulation().force("x", x).stop();
|
||||
it("forceX respects fixed positions", () => {
|
||||
const x = forceX(200);
|
||||
const f = forceSimulation().force("x", x).stop();
|
||||
const a = { fx: 0, fy:0 }, b = {}, c = {};
|
||||
f.nodes([a, b, c]);
|
||||
f.tick();
|
||||
test.nodeEqual(a, { fx: 0, fy: 0, index: 0, x: 0, y: 0, vy: 0, vx: 0 });
|
||||
test.end();
|
||||
assertNodeEqual(a, { fx: 0, fy: 0, index: 0, x: 0, y: 0, vy: 0, vx: 0 });
|
||||
});
|
||||
|
||||
tape("forceY respects fixed positions", function(test) {
|
||||
const y = force.forceX(200);
|
||||
const f = force.forceSimulation().force("y", y).stop();
|
||||
it("forceY respects fixed positions", () => {
|
||||
const y = forceX(200);
|
||||
const f = forceSimulation().force("y", y).stop();
|
||||
const a = { fx: 0, fy:0 }, b = {}, c = {};
|
||||
f.nodes([a, b, c]);
|
||||
f.tick();
|
||||
test.nodeEqual(a, { fx: 0, fy: 0, index: 0, x: 0, y: 0, vy: 0, vx: 0 });
|
||||
test.end();
|
||||
assertNodeEqual(a, { fx: 0, fy: 0, index: 0, x: 0, y: 0, vy: 0, vx: 0 });
|
||||
});
|
||||
|
||||
tape("forceX.x() accessor", function(test) {
|
||||
const x = force.forceX().x(d => d.x0);
|
||||
const f = force.forceSimulation().force("x", x).stop();
|
||||
it("forceX.x() accessor", () => {
|
||||
const x = forceX().x(d => d.x0);
|
||||
const f = forceSimulation().force("x", x).stop();
|
||||
const a = { x: 100, y: 0, x0: 300 }, b = { x: 200, y: 0, x0: 200 }, c = { x: 300, y: 0, x0: 100 };
|
||||
f.nodes([a, b, c]);
|
||||
f.tick(30);
|
||||
test.assert(a.x > 290);
|
||||
test.assert(a.vx > 0);
|
||||
test.equal(b.x, 200);
|
||||
test.equal(b.vx, 0);
|
||||
test.assert(c.x < 110);
|
||||
test.assert(c.vx < 0);
|
||||
test.end();
|
||||
assert(a.x > 290);
|
||||
assert(a.vx > 0);
|
||||
assert.strictEqual(b.x, 200);
|
||||
assert.strictEqual(b.vx, 0);
|
||||
assert(c.x < 110);
|
||||
assert(c.vx < 0);
|
||||
});
|
||||
|
||||
tape("forceY.y() accessor", function(test) {
|
||||
const y = force.forceY().y(d => d.y0);
|
||||
const f = force.forceSimulation().force("y", y).stop();
|
||||
it("forceY.y() accessor", () => {
|
||||
const y = forceY().y(d => d.y0);
|
||||
const f = forceSimulation().force("y", y).stop();
|
||||
const a = { y: 100, x: 0, y0: 300 }, b = { y: 200, x: 0, y0: 200 }, c = { y: 300, x: 0, y0: 100 };
|
||||
f.nodes([a, b, c]);
|
||||
f.tick(30);
|
||||
test.assert(a.y > 290);
|
||||
test.assert(a.vy > 0);
|
||||
test.equal(b.y, 200);
|
||||
test.equal(b.vy, 0);
|
||||
test.assert(c.y < 110);
|
||||
test.assert(c.vy < 0);
|
||||
test.end();
|
||||
assert(a.y > 290);
|
||||
assert(a.vy > 0);
|
||||
assert.strictEqual(b.y, 200);
|
||||
assert.strictEqual(b.vy, 0);
|
||||
assert(c.y < 110);
|
||||
assert(c.vy < 0);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user