Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adopt type=module #48

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,7 @@
"sourceType": "module",
"ecmaVersion": 8
},
"env": {
"es6": true
},
"rules": {
"no-cond-assign": 0,
"no-constant-condition": 0,
"no-floating-decimal": 2
"no-constant-condition": 0
}
}
30 changes: 30 additions & 0 deletions .github/workflows/node.js.yml
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: [ 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
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright 2017 Mike Bostock
Copyright 2017-2021 Mike Bostock

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
Expand Down
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,31 @@ Clipping and geometric operations for spherical polygons.

## Installing

If you use NPM, `npm install d3-geo-polygon`. Otherwise, download the [latest release](https://github.com/d3/d3-geo-polygon/releases/latest). You can also load directly from [unpkg](https://unpkg.com/d3-geo-polygon/). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3` global is exported:
If you use npm, `npm install d3-geo-polygon`. You can also download the [latest release on GitHub](https://github.com/d3/d3-geo-polygon/releases/latest). For vanilla HTML in modern browsers, import d3-geo-polygon from Skypack:

```html
<script src="https://unpkg.com/d3-geo@1"></script>
<script src="https://unpkg.com/d3-geo-polygon@1"></script>
<script type="module">
import {geoDodecahedral} from "https://cdn.skypack.dev/d3-geo-polygon@2";

const projection = geoDodecahedral();
</script>
```

For legacy environments, you can load d3-geo-polygon’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-geo@3"></script>
<script src="https://cdn.jsdelivr.net/npm/d3-geo-polygon@2"></script>
<script>

// new projection
var projection = d3.geoDodecahedral();
const projection = d3.geoDodecahedral();

// polyhedral projections don’t need SVG or canvas clipping anymore
var projection = d3.geoPolyhedralCollignon();
const projection = d3.geoPolyhedralCollignon();

// arbitrary polygon clipping on any projection
var projection = d3.geoEquirectangular()
const projection = d3.geoEquirectangular()
.preclip(d3.geoClipPolygon({
type: "Polygon",
coordinates: [[[-10, -10], [-10, 10], [10, 10], [10, -10], [-10, -10]]]
Expand Down
45 changes: 25 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@
"name": "d3-geo-polygon",
"version": "1.12.1",
"description": "Clipping and geometric operations for spherical polygons.",
"homepage": "https://github.com/d3/d3-geo-polygon",
"repository": {
"type": "git",
"url": "https://github.com/d3/d3-geo-polygon.git"
},
"keywords": [
"d3",
"d3-module",
"cartography",
"projection",
"polygon"
],
"homepage": "https://github.com/d3/d3-geo-polygon",
"license": "ISC",
"author": {
"name": "Mike Bostock",
Expand All @@ -25,35 +29,36 @@
"url": "https://visionscarto.net"
}
],
"main": "dist/d3-geo-polygon.js",
"unpkg": "dist/d3-geo-polygon.min.js",
"jsdelivr": "dist/d3-geo-polygon.min.js",
"type": "module",
"module": "src/index.js",
"repository": {
"type": "git",
"url": "https://github.com/d3/d3-geo-polygon.git"
},
"scripts": {
"pretest": "rollup -c",
"test": "tape 'test/**/*-test.js' && eslint src",
"prepublishOnly": "rm -rf dist && yarn test && mkdir -p test/output && test/compare-images",
"postpublish": "git push && git push --tags && zip -j dist/d3-geo-polygon.zip -- LICENSE README.md dist/d3-geo-polygon.js dist/d3-geo-polygon.min.js"
"main": "src/index.js",
"jsdelivr": "dist/d3-geo-polygon.min.js",
"unpkg": "dist/d3-geo-polygon.min.js",
"exports": {
"umd": "./dist/d3-geo-polygon.min.js",
"default": "./src/index.js"
},
"sideEffects": false,
"dependencies": {
"d3-array": "1 - 2",
"d3-geo": "1.12.0 - 2"
},
"sideEffects": false,
"devDependencies": {
"canvas": "1 - 2",
"eslint": "5",
"rollup": "0.64",
"rollup-plugin-terser": "1",
"tape": "4",
"canvas": "2",
"d3-format": "2",
"eslint": "7",
"mocha": "8",
"rollup": "2",
"rollup-plugin-terser": "7",
"topojson-client": "3",
"world-atlas": "1"
},
"scripts": {
"test": "mocha 'test/**/*-test.js' && eslint src test",
"prepublishOnly": "rm -rf dist && yarn test && rollup -c && mkdir -p test/output && test/compare-images",
"postpublish": "git push && git push --tags"
},
"engines": {
"node": ">=6.0.0"
"node": ">=12"
}
}
2 changes: 1 addition & 1 deletion src/imago.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
sin,
sqrt,
tan
} from "./math";
} from "./math.js";
import { geoProjectionMutator as projectionMutator } from "d3-geo";
import { default as clipPolygon } from "./clip/polygon.js";
import { solve } from "./newton.js";
Expand Down
30 changes: 15 additions & 15 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
export {default as geoClipPolygon} from "./clip/polygon";
export {default as geoIntersectArc} from "./intersect";
export {default as geoPolyhedral} from "./polyhedral/index";
export {default as geoPolyhedralButterfly} from "./polyhedral/butterfly";
export {default as geoPolyhedralCollignon} from "./polyhedral/collignon";
export {default as geoPolyhedralWaterman} from "./polyhedral/waterman";
export {default as geoPolyhedralVoronoi} from "./polyhedral/voronoi";
export {default as geoDodecahedral} from "./polyhedral/dodecahedral";
export {default as geoClipPolygon} from "./clip/polygon.js";
export {default as geoIntersectArc} from "./intersect.js";
export {default as geoPolyhedral} from "./polyhedral/index.js";
export {default as geoPolyhedralButterfly} from "./polyhedral/butterfly.js";
export {default as geoPolyhedralCollignon} from "./polyhedral/collignon.js";
export {default as geoPolyhedralWaterman} from "./polyhedral/waterman.js";
export {default as geoPolyhedralVoronoi} from "./polyhedral/voronoi.js";
export {default as geoDodecahedral} from "./polyhedral/dodecahedral.js";
export {default as geoCox, coxRaw as geoCoxRaw} from "./cox.js";
export {default as geoTetrahedralLee, leeRaw as geoLeeRaw} from "./tetrahedralLee.js";
export {default as geoGrayFullerRaw} from "./grayfuller";
export {default as geoAirocean} from "./airocean";
export {default as geoIcosahedral} from "./icosahedral";
export {default as geoImago, imagoBlock as geoImagoBlock, imagoRaw as geoImagoRaw} from "./imago";
export {default as geoCubic} from "./cubic";
export {default as geoCahillKeyes, cahillKeyesRaw as geoCahillKeyesRaw} from "./cahillKeyes";
export {default as geoComplexLog, complexLogRaw as geoComplexLogRaw} from "./complexLog";
export {default as geoGrayFullerRaw} from "./grayfuller.js";
export {default as geoAirocean} from "./airocean.js";
export {default as geoIcosahedral} from "./icosahedral.js";
export {default as geoImago, imagoBlock as geoImagoBlock, imagoRaw as geoImagoRaw} from "./imago.js";
export {default as geoCubic} from "./cubic.js";
export {default as geoCahillKeyes, cahillKeyesRaw as geoCahillKeyesRaw} from "./cahillKeyes.js";
export {default as geoComplexLog, complexLogRaw as geoComplexLogRaw} from "./complexLog.js";
7 changes: 4 additions & 3 deletions src/polyhedral/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ export default function(tree, face) {
function forward(lambda, phi) {
var node = face(lambda, phi),
point = node.project([lambda * degrees, phi * degrees]),
t;
if (t = node.transform) {
t = node.transform;
if (t) {
return [
t[0] * point[0] + t[1] * point[1] + t[2],
-(t[3] * point[0] + t[4] * point[1] + t[5])
Expand Down Expand Up @@ -78,7 +78,8 @@ export default function(tree, face) {
var p,
children = node.children;
for (var i = 0, n = children && children.length; i < n; ++i) {
if (p = faceInvert(children[i], coordinates)) return p;
p = faceInvert(children[i], coordinates);
if (p) return p;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/tetrahedralLee.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
complexNorm,
complexPow,
complexSub
} from "./complex";
} from "./complex.js";
import {solve2d} from "./newton.js";

export function leeRaw(lambda, phi) {
Expand Down
13 changes: 13 additions & 0 deletions test/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module",
"ecmaVersion": 8
},
"rules": {
"no-constant-condition": 0
},
"env": {
"mocha": true
}
}
70 changes: 70 additions & 0 deletions test/asserts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import assert from "assert";

export function assertPathEqual(actual, expected) {
assert.strictEqual(normalizePath(actual + ""), normalizePath(expected + ""));
}

const reNumber = /[-+]?(?:\d+\.\d+|\d+\.|\.\d+|\d+)(?:[eE][-]?\d+)?/g;

function normalizePath(path) {
return path.replace(reNumber, formatNumber);
}

function formatNumber(s) {
return Math.abs((s = +s) - Math.round(s)) < 1e-6 ? Math.round(s) : s.toFixed(6);
}

export function assertInDelta(actual, expected, delta) {
delta = delta || 1e-6;
assert(inDelta(actual, expected, delta),
`${actual} should be within ${delta} of ${expected}`);
}

function inDelta(actual, expected, delta) {
return (Array.isArray(expected) ? inDeltaArray
: typeof expected === "object" ? inDeltaObject
: inDeltaNumber)(actual, expected, delta);
}

function inDeltaArray(actual, expected, delta) {
let 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 inDeltaObject(actual, expected, delta) {
for (let i in expected) if (!inDelta(actual[i], expected[i], delta)) return false;
for (let i in actual) if (!(i in expected)) return false;
return true;
}

function inDeltaNumber(actual, expected, delta) {
return actual >= expected - delta && actual <= expected + delta;
}


export function assertProjectionEqual(projection, location, point, delta) {
assert(planarEqual(projection(location), point, delta || 1e-6)
&& sphericalEqual(projection.invert(point), location, delta || 1e-3),
`${[projection.invert(point), projection(location)]} should be projected equivalents; expected: ${[location, point]}`);
}

function planarEqual(actual, expected, delta) {
return Array.isArray(actual)
&& actual.length === 2
&& inDelta(actual[0], expected[0], delta)
&& inDelta(actual[1], expected[1], delta);
}

function sphericalEqual(actual, expected, delta) {
return Array.isArray(actual)
&& actual.length === 2
&& longitudeEqual(actual[0], expected[0], delta)
&& inDelta(actual[1], expected[1], delta);
}

function longitudeEqual(actual, expected, delta) {
actual = Math.abs(actual - expected) % 360;
return actual <= delta || actual >= 360 - delta;
}
28 changes: 13 additions & 15 deletions test/clip/polygon-test.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,26 @@
var tape = require("tape"),
d3 = require("../../"),
d3_geo = require("d3-geo");
import assert from "assert";
import * as d3 from "../../src/index.js";
import {geoEquirectangular, geoPath} from "d3-geo";

tape("clipPolygon clips line", function(test) {
var clipPolygon = d3.geoClipPolygon({ type: "Polygon", coordinates: [[[-10, -10], [-10, 10], [10, 10], [10, -10], [-10, -10]]] });
var projection = d3_geo.geoEquirectangular().clipAngle(10).preclip(clipPolygon);
var path = d3_geo.geoPath()
it("clipPolygon clips line", () => {
const clipPolygon = d3.geoClipPolygon({ type: "Polygon", coordinates: [[[-10, -10], [-10, 10], [10, 10], [10, -10], [-10, -10]]] });
const projection = geoEquirectangular().clipAngle(10).preclip(clipPolygon);
const path = geoPath()
.projection(projection);
test.equal(path({type:"LineString", coordinates:[[-20,0], [20,0]]}), path({type:"LineString", coordinates:[[-10.5,0], [10.5,0]]}));
test.end();
assert.strictEqual(path({type:"LineString", coordinates:[[-20,0], [20,0]]}), path({type:"LineString", coordinates:[[-10.5,0], [10.5,0]]}));
});


tape("clipPolygon interpolates when the intersections are on the same segment", function(test) {
var clipPolygon = d3.geoClipPolygon({
it("clipPolygon interpolates when the intersections are on the same segment", () => {
const clipPolygon = d3.geoClipPolygon({
type: "Polygon",
coordinates: [[[-10, -11], [10, 10], [11, -10], [-10, -11]]]
}),
projection = d3_geo.geoEquirectangular().preclip(clipPolygon).precision(0.1),
path = d3_geo.geoPath().projection(projection);
test.equal(path({
projection = geoEquirectangular().preclip(clipPolygon).precision(0.1),
path = geoPath().projection(projection);
assert.strictEqual(path({
type: "Polygon",
coordinates: [[[0, -11], [1, -11], [1, -10], [0, -10], [0, -11]]]
}).replace(/[.]\d+/g, ""),
"M482,278L482,276L480,276L480,278L466,279L453,279L506,223L509,276L495,277Z");
test.end();
});
2 changes: 1 addition & 1 deletion test/compare-images
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ for i in \
tetrahedralLee \
tetrahedralLeeSouth \
; do
test/render-world $i > test/output/$i.png \
node test/render-world.mjs $i > test/output/$i.png \
&& [ "$(gm compare -metric rmse img/$i.png test/output/$i.png 2>&1)" = "Image Difference (RootMeanSquaredError):
Normalized Absolute
============ ==========
Expand Down
Loading