diff --git a/package-lock.json b/package-lock.json index f60e354d56c..f40c0371415 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,6 +36,57 @@ "acorn": "5.3.0" } }, + "@mapbox/geojson-area": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@mapbox/geojson-area/-/geojson-area-0.2.2.tgz", + "integrity": "sha1-GNeBSqNr8j+7zDefjiaiKSfevxA=", + "requires": { + "wgs84": "0.0.0" + } + }, + "@mapbox/gl-matrix": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@mapbox/gl-matrix/-/gl-matrix-0.0.1.tgz", + "integrity": "sha1-5RJqq01kw2uBx6l9CuDd3eV3PSs=" + }, + "@mapbox/mapbox-gl-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-supported/-/mapbox-gl-supported-1.3.0.tgz", + "integrity": "sha512-ACfuqIMxAzIoKRp3e7J2VjTJFBbrOoXqt4b7vy1x5uz5Od5Drroe2Ei/+R416eKpTXE1L0zHq5D2m3Q+SyM9WQ==" + }, + "@mapbox/point-geometry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", + "integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI=" + }, + "@mapbox/shelf-pack": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/shelf-pack/-/shelf-pack-3.1.0.tgz", + "integrity": "sha1-Ht6pwL9nFbIXFxumBkbCAa9SD2o=" + }, + "@mapbox/tiny-sdf": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/tiny-sdf/-/tiny-sdf-1.1.0.tgz", + "integrity": "sha512-dnhyk8X2BkDRWImgHILYAGgo+kuciNYX30CUKj/Qd5eNjh54OWM/mdOS/PWsPeN+3abtN+QDGYM4G220ynVJKA==" + }, + "@mapbox/unitbezier": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz", + "integrity": "sha1-FWUb1VOme4WB+zmIEMmK2Go0Uk4=" + }, + "@mapbox/vector-tile": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.0.tgz", + "integrity": "sha1-xJX5clJb78zvzYOPRf+jfvO3D+g=", + "requires": { + "@mapbox/point-geometry": "0.1.0" + } + }, + "@mapbox/whoots-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.0.0.tgz", + "integrity": "sha1-wd5CkwgUJNo6wwwjr6hQrxAZu1Q=" + }, "@plotly/d3-sankey": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@plotly/d3-sankey/-/d3-sankey-0.5.0.tgz", @@ -127,6 +178,21 @@ } } }, + "acorn-object-spread": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/acorn-object-spread/-/acorn-object-spread-1.0.0.tgz", + "integrity": "sha1-SOrQ9KjrFplaF6Dbn/xqyq2kumg=", + "requires": { + "acorn": "3.3.0" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + } + } + }, "acorn5-object-spread": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/acorn5-object-spread/-/acorn5-object-spread-4.0.0.tgz", @@ -186,6 +252,7 @@ "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, "requires": { "co": "4.6.0", "fast-deep-equal": "1.0.0", @@ -275,8 +342,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { "version": "3.2.0", @@ -289,7 +355,8 @@ "any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", + "dev": true }, "anymatch": { "version": "1.3.2", @@ -359,7 +426,6 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, "requires": { "sprintf-js": "1.0.3" }, @@ -367,8 +433,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" } } }, @@ -492,7 +557,8 @@ "asn1": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true }, "asn1.js": { "version": "4.9.2", @@ -517,7 +583,8 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true }, "ast-module-types": { "version": "2.3.2", @@ -576,7 +643,8 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true }, "atob-lite": { "version": "1.0.0", @@ -586,12 +654,14 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true }, "aws4": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", + "dev": true }, "axios": { "version": "0.15.3", @@ -669,8 +739,7 @@ "babylon": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" }, "backo2": { "version": "1.0.2", @@ -697,11 +766,6 @@ "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", "dev": true }, - "base64-js": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.2.tgz", - "integrity": "sha1-Ak8Pcq+iW3X5wO5zzU9V7Bvtl4Q=" - }, "base64id": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", @@ -712,6 +776,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, "optional": true, "requires": { "tweetnacl": "0.14.5" @@ -855,19 +920,11 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "dev": true, "requires": { "hoek": "4.2.0" } }, - "bops": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/bops/-/bops-0.0.6.tgz", - "integrity": "sha1-CC0dVfoB5g29wuvC26N/ZZVUzzo=", - "requires": { - "base64-js": "0.0.2", - "to-utf8": "0.0.1" - } - }, "boundary-cells": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/boundary-cells/-/boundary-cells-2.0.1.tgz", @@ -1236,6 +1293,11 @@ "inherits": "2.0.3" } }, + "browserify-package-json": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-package-json/-/browserify-package-json-1.0.1.tgz", + "integrity": "sha1-mN3oqlxWH9bT/km7qhArdLOW/eo=" + }, "browserify-rsa": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", @@ -1451,7 +1513,8 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true }, "cdt2d": { "version": "1.0.0", @@ -1633,7 +1696,8 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true }, "code-point-at": { "version": "1.1.0", @@ -1753,6 +1817,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "dev": true, "requires": { "delayed-stream": "1.0.0" } @@ -1988,6 +2053,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "dev": true, "requires": { "boom": "5.2.0" }, @@ -1996,6 +2062,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "dev": true, "requires": { "hoek": "4.2.0" } @@ -2147,6 +2214,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, "requires": { "assert-plus": "1.0.0" } @@ -2272,7 +2340,8 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true }, "delegates": { "version": "1.0.0", @@ -2696,6 +2765,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, "optional": true, "requires": { "jsbn": "0.1.1" @@ -3188,7 +3258,16 @@ "extend": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "dev": true + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "0.1.1" + } }, "external-editor": { "version": "2.1.0", @@ -3229,7 +3308,8 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true }, "falafel": { "version": "2.1.0", @@ -3245,7 +3325,8 @@ "fast-deep-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", + "dev": true }, "fast-isnumeric": { "version": "1.1.1", @@ -3255,18 +3336,14 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, - "feature-filter": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/feature-filter/-/feature-filter-2.2.0.tgz", - "integrity": "sha1-PMNWAV6WjDYq+99/8bt0Td9/wuA=" - }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -3437,6 +3514,15 @@ "is-typedarray": "1.0.0" } }, + "flow-remove-types": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-1.2.3.tgz", + "integrity": "sha512-ypq/U3V+t9atYiOuSJd40tekCra03EHKoRsiK/wXGrsZimuum0kdwVY7Yv0HTaoXgHW1WiayomYd+Q3kkvPl9Q==", + "requires": { + "babylon": "6.18.0", + "vlq": "0.2.3" + } + }, "follow-redirects": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", @@ -3487,12 +3573,14 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true }, "form-data": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "dev": true, "requires": { "asynckit": "0.4.0", "combined-stream": "1.0.5", @@ -3565,33 +3653,6 @@ "jsonfile": "2.4.0" } }, - "fs-promise": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-0.5.0.tgz", - "integrity": "sha1-Q0fWv2JGVacGGkMZITw5MnatPvM=", - "dev": true, - "requires": { - "any-promise": "1.3.0", - "fs-extra": "0.26.7", - "mz": "2.7.0", - "thenify-all": "1.6.0" - }, - "dependencies": { - "fs-extra": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", - "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "2.4.0", - "klaw": "1.3.1", - "path-is-absolute": "1.0.1", - "rimraf": "2.6.2" - } - } - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4611,43 +4672,20 @@ "is-property": "1.0.2" } }, - "geojson-area": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/geojson-area/-/geojson-area-0.1.0.tgz", - "integrity": "sha1-1I2AcILPrfSnjfE0m+UPOL8YlK4=", - "requires": { - "wgs84": "0.0.0" - } - }, "geojson-rewind": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/geojson-rewind/-/geojson-rewind-0.1.0.tgz", - "integrity": "sha1-VwIqBUsZZmDXVTVP5dJmhNkM0Bk=", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/geojson-rewind/-/geojson-rewind-0.3.0.tgz", + "integrity": "sha512-5dsjiZGk6p///Ju9kh7uGW+I74CZriHsxqBNPbIN4bbInfKmHwwM+f8fZ42fmpV5emeUYLTTC+GWs3EC1TMjNQ==", "requires": { - "concat-stream": "1.2.1", - "geojson-area": "0.1.0", - "minimist": "0.0.5" - }, - "dependencies": { - "concat-stream": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.2.1.tgz", - "integrity": "sha1-81EAtsRjeL+6i2uA+fDQzN8T3GA=", - "requires": { - "bops": "0.0.6" - } - }, - "minimist": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.5.tgz", - "integrity": "sha1-16oye87PUY+RBqxrjwA/o7zqhWY=" - } + "@mapbox/geojson-area": "0.2.2", + "concat-stream": "1.6.0", + "minimist": "1.2.0" } }, "geojson-vt": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-2.4.0.tgz", - "integrity": "sha1-PBz0RJPzXrTSxwyV2mVQ3mYHLAU=" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/geojson-vt/-/geojson-vt-3.0.0.tgz", + "integrity": "sha512-FL7VV56gYBDBh0F7EWyZV5G9/L2EHEHh9SyhEpJz4c8YDPerM6dnP9VbRcsbyg1wH+1oyoHRA9dlJkGs/IXULA==" }, "get-amd-module-type": { "version": "2.0.5", @@ -4730,6 +4768,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, "requires": { "assert-plus": "1.0.0" } @@ -4955,11 +4994,6 @@ "resolved": "https://registry.npmjs.org/gl-mat4/-/gl-mat4-1.1.4.tgz", "integrity": "sha1-HolbVYkuVqiWhnq9g30483oXgIY=" }, - "gl-matrix": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-2.4.0.tgz", - "integrity": "sha1-IImxMwGinuyCLZ2Z3/wfeO6aPFA=" - }, "gl-matrix-invert": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gl-matrix-invert/-/gl-matrix-invert-1.0.0.tgz", @@ -5571,6 +5605,24 @@ "temp": "0.4.0" } }, + "gray-matter": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-3.1.1.tgz", + "integrity": "sha512-nZ1qjLmayEv0/wt3sHig7I0s3/sJO0dkAaKYQ5YAOApUtYEOonXSFdWvL1khvnZMTvov4UufkqlFsilPnejEXA==", + "requires": { + "extend-shallow": "2.0.1", + "js-yaml": "3.10.0", + "kind-of": "5.1.0", + "strip-bom-string": "1.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" + } + } + }, "grid-index": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.0.0.tgz", @@ -5620,12 +5672,14 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true }, "har-validator": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "dev": true, "requires": { "ajv": "5.5.2", "har-schema": "2.0.0" @@ -5643,7 +5697,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, "requires": { "ansi-regex": "2.1.1" } @@ -5738,6 +5791,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "dev": true, "requires": { "boom": "4.3.1", "cryptiles": "3.1.2", @@ -5776,7 +5830,8 @@ "hoek": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==", + "dev": true }, "hosted-git-info": { "version": "2.5.0", @@ -5844,6 +5899,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, "requires": { "assert-plus": "1.0.0", "jsprim": "1.4.1", @@ -6236,8 +6292,7 @@ "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" }, "is-extglob": { "version": "1.0.0", @@ -6446,7 +6501,8 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true }, "istanbul": { "version": "0.4.5", @@ -6575,7 +6631,6 @@ "version": "3.10.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", - "dev": true, "requires": { "argparse": "1.0.9", "esprima": "4.0.0" @@ -6584,8 +6639,7 @@ "esprima": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" } } }, @@ -6593,6 +6647,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, "optional": true }, "jsdom": { @@ -6672,12 +6727,14 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true }, "json-schema-traverse": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "dev": true }, "json-stable-stringify": { "version": "0.0.1", @@ -6697,12 +6754,14 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true }, "jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, "requires": { "graceful-fs": "4.1.11" } @@ -6738,6 +6797,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -7093,14 +7153,6 @@ "is-buffer": "1.1.6" } }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "requires": { - "graceful-fs": "4.1.11" - } - }, "labeled-stream-splicer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", @@ -7216,26 +7268,6 @@ "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", "dev": true }, - "lodash._baseisequal": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/lodash._baseisequal/-/lodash._baseisequal-3.0.7.tgz", - "integrity": "sha1-2AJfdjOdKTQnZ9zIh85cuVpbUfE=", - "requires": { - "lodash.isarray": "3.0.4", - "lodash.istypedarray": "3.0.6", - "lodash.keys": "3.1.2" - } - }, - "lodash._bindcallback": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz", - "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=" - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" - }, "lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", @@ -7248,40 +7280,6 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" - }, - "lodash.isequal": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-3.0.4.tgz", - "integrity": "sha1-HDXrO27wzR/1F0Pj6jz3/f/ay2Q=", - "requires": { - "lodash._baseisequal": "3.0.7", - "lodash._bindcallback": "3.0.1" - } - }, - "lodash.istypedarray": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz", - "integrity": "sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I=" - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, "lodash.memoize": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", @@ -7778,71 +7776,115 @@ "dev": true }, "mapbox-gl": { - "version": "0.22.1", - "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-0.22.1.tgz", - "integrity": "sha1-kqllVH1MLyTCLLxIfu2khpTLYno=", - "requires": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/mapbox-gl/-/mapbox-gl-0.44.0.tgz", + "integrity": "sha512-vMeZaLXjG1B1BKOD9HB11sb9UIUvbzXWJu0NR38j9Uyp1h5xUXqh1Rqe+EhxQp3jzlHIv/LVhFKCJjQQKA2LoA==", + "requires": { + "@mapbox/gl-matrix": "0.0.1", + "@mapbox/mapbox-gl-supported": "1.3.0", + "@mapbox/point-geometry": "0.1.0", + "@mapbox/shelf-pack": "3.1.0", + "@mapbox/tiny-sdf": "1.1.0", + "@mapbox/unitbezier": "0.0.0", + "@mapbox/vector-tile": "1.3.0", + "@mapbox/whoots-js": "3.0.0", + "brfs": "1.4.4", + "bubleify": "0.7.0", "csscolorparser": "1.0.3", "earcut": "2.1.3", - "feature-filter": "2.2.0", - "geojson-rewind": "0.1.0", - "geojson-vt": "2.4.0", - "gl-matrix": "2.4.0", + "geojson-rewind": "0.3.0", + "geojson-vt": "3.0.0", + "gray-matter": "3.1.1", "grid-index": "1.0.0", - "mapbox-gl-function": "1.3.0", - "mapbox-gl-shaders": "github:mapbox/mapbox-gl-shaders#de2ab007455aa2587c552694c68583f94c9f2747", - "mapbox-gl-style-spec": "github:mapbox/mapbox-gl-style-spec#83b1a3e5837d785af582efd5ed1a212f2df6a4ae", - "mapbox-gl-supported": "1.2.0", - "pbf": "1.3.7", - "pngjs": "2.3.1", - "point-geometry": "0.0.0", + "jsonlint-lines-primitives": "1.6.0", + "minimist": "0.0.8", + "package-json-versionify": "1.0.4", + "pbf": "3.1.0", "quickselect": "1.0.1", - "request": "2.83.0", - "resolve-url": "0.2.1", - "shelf-pack": "1.1.0", + "rw": "1.3.3", + "shuffle-seed": "1.1.6", + "sort-object": "0.3.2", "supercluster": "2.3.0", + "through2": "2.0.3", + "tinyqueue": "1.2.3", "unassertify": "2.1.0", - "unitbezier": "0.0.0", - "vector-tile": "1.3.0", - "vt-pbf": "2.1.4", - "webworkify": "1.5.0", - "whoots-js": "2.1.0" - } - }, - "mapbox-gl-function": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/mapbox-gl-function/-/mapbox-gl-function-1.3.0.tgz", - "integrity": "sha1-zuPZV1DBidReg6tBoKV/wqilCbw=" - }, - "mapbox-gl-shaders": { - "version": "github:mapbox/mapbox-gl-shaders#de2ab007455aa2587c552694c68583f94c9f2747", - "requires": { - "brfs": "1.4.4" - } - }, - "mapbox-gl-style-spec": { - "version": "github:mapbox/mapbox-gl-style-spec#83b1a3e5837d785af582efd5ed1a212f2df6a4ae", - "requires": { - "csscolorparser": "1.0.3", - "jsonlint-lines-primitives": "1.6.0", - "lodash.isequal": "3.0.4", - "minimist": "0.0.8", - "rw": "0.1.4", - "sort-object": "0.3.2" + "unflowify": "1.0.1", + "vt-pbf": "3.1.0", + "webworkify": "1.5.0" }, "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "buble": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/buble/-/buble-0.15.2.tgz", + "integrity": "sha1-VH/EdIP45egXbYKqXrzLGDsC1hM=", + "requires": { + "acorn": "3.3.0", + "acorn-jsx": "3.0.1", + "acorn-object-spread": "1.0.0", + "chalk": "1.1.3", + "magic-string": "0.14.0", + "minimist": "1.2.0", + "os-homedir": "1.0.2" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "bubleify": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/bubleify/-/bubleify-0.7.0.tgz", + "integrity": "sha1-0I6mQv/Qhf+HEciEP1cHLw1euPY=", + "requires": { + "buble": "0.15.2", + "object-assign": "4.1.1" + } + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" + } + }, + "magic-string": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.14.0.tgz", + "integrity": "sha1-VyJK7xcByu7Sc7F6OalW5ysXJGI=", + "requires": { + "vlq": "0.2.3" + } + }, "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" } } }, - "mapbox-gl-supported": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mapbox-gl-supported/-/mapbox-gl-supported-1.2.0.tgz", - "integrity": "sha1-y9NN+JQgbK3amjPI2aRgnya7GYk=" - }, "marching-simplex-table": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/marching-simplex-table/-/marching-simplex-table-1.0.0.tgz", @@ -8019,12 +8061,14 @@ "mime-db": { "version": "1.30.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", - "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=", + "dev": true }, "mime-types": { "version": "2.1.17", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "dev": true, "requires": { "mime-db": "1.30.0" } @@ -8813,6 +8857,11 @@ "has-color": "0.1.7", "strip-ansi": "0.1.1" } + }, + "strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=" } } }, @@ -8903,7 +8952,8 @@ "oauth-sign": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true }, "object-assign": { "version": "4.1.1", @@ -9147,6 +9197,14 @@ } } }, + "package-json-versionify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/package-json-versionify/-/package-json-versionify-1.0.4.tgz", + "integrity": "sha1-WGBYepRIc6a35tJujlH/siMVvxc=", + "requires": { + "browserify-package-json": "1.0.1" + } + }, "pad-left": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pad-left/-/pad-left-1.0.2.tgz", @@ -9318,9 +9376,9 @@ } }, "pbf": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-1.3.7.tgz", - "integrity": "sha1-Hj0Ee6PL6Ahq6FSiVQOrRTfUM10=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.1.0.tgz", + "integrity": "sha512-/hYJmIsTmh7fMkHAWWXJ5b8IKLWdjdlAFb3IHkRBn1XUhIYBChVGfVwmHEAV3UfXTxsP/AKfYTXTS/dCPxJd5w==", "requires": { "ieee754": "1.1.8", "resolve-protobuf-schema": "2.0.0" @@ -9342,7 +9400,8 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true }, "permutation-parity": { "version": "1.0.0", @@ -9431,16 +9490,6 @@ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", "dev": true }, - "pngjs": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-2.3.1.tgz", - "integrity": "sha1-EdHhK5y2TWPjDBQ6Mw9MH1Z9qF8=" - }, - "point-geometry": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/point-geometry/-/point-geometry-0.0.0.tgz", - "integrity": "sha1-b8vK16gDtkGCR91uScKFPFhNr/c=" - }, "point-in-big-polygon": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/point-in-big-polygon/-/point-in-big-polygon-2.0.0.tgz", @@ -9614,7 +9663,8 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true }, "q": { "version": "1.4.1", @@ -9632,7 +9682,8 @@ "qs": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true }, "quat-slerp": { "version": "1.0.1", @@ -9804,40 +9855,192 @@ "fs-promise": "0.5.0" }, "dependencies": { + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", + "dev": true + }, "balanced-match": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", + "integrity": "sha1-cZfX6qm4fmSDkOph/GbIRCdCDfk=", + "dev": true, + "requires": { + "balanced-match": "0.4.2", + "concat-map": "0.0.1" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "fs-extra": { "version": "0.26.7", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", + "dev": true, "requires": { "graceful-fs": "4.1.11", "jsonfile": "2.4.0", "klaw": "1.3.1", "path-is-absolute": "1.0.1", - "rimraf": "2.6.2" + "rimraf": "2.6.1" + } + }, + "fs-promise": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-0.5.0.tgz", + "integrity": "sha1-Q0fWv2JGVacGGkMZITw5MnatPvM=", + "dev": true, + "requires": { + "any-promise": "1.3.0", + "fs-extra": "0.26.7", + "mz": "2.6.0", + "thenify-all": "1.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "dev": true, + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.3", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, + "requires": { + "graceful-fs": "4.1.11" } }, "minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "dev": true, "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "1.1.6" } }, "mz": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.6.0.tgz", "integrity": "sha1-yLhSHZWN8KTydoAl22nHGe5O8c4=", + "dev": true, "requires": { "any-promise": "1.3.0", "object-assign": "4.1.1", "thenify-all": "1.6.0" } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1.0.2" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "rimraf": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", + "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "dev": true, + "requires": { + "glob": "7.1.1" + } + }, + "thenify": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.2.1.tgz", + "integrity": "sha1-JR/RyAr/blz1fLF5qx/LckJpvRE=", + "dev": true, + "requires": { + "any-promise": "1.3.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "dev": true, + "requires": { + "thenify": "3.2.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true } } }, @@ -10196,6 +10399,7 @@ "version": "2.83.0", "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "dev": true, "requires": { "aws-sign2": "0.7.0", "aws4": "1.6.0", @@ -10365,11 +10569,6 @@ "protocol-buffers-schema": "2.2.0" } }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", @@ -10405,6 +10604,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, "requires": { "glob": "7.1.2" } @@ -10526,9 +10726,9 @@ "dev": true }, "rw": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/rw/-/rw-0.1.4.tgz", - "integrity": "sha1-SQPL2AJIrg7eaFv1j9I2p6mymj4=" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" }, "rx-lite": { "version": "4.0.8", @@ -10664,6 +10864,11 @@ } } }, + "seedrandom": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz", + "integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=" + }, "semver": { "version": "4.3.6", "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", @@ -10728,11 +10933,6 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, - "shelf-pack": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shelf-pack/-/shelf-pack-1.1.0.tgz", - "integrity": "sha1-tGea/dAK1o39m70rWj6BkpOnTYI=" - }, "shell-quote": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", @@ -10745,6 +10945,14 @@ "jsonify": "0.0.0" } }, + "shuffle-seed": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/shuffle-seed/-/shuffle-seed-1.1.6.tgz", + "integrity": "sha1-UzwSaDurO0+j6HUfxOViFGdEJgs=", + "requires": { + "seedrandom": "2.4.3" + } + }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -10880,6 +11088,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "dev": true, "requires": { "hoek": "4.2.0" } @@ -11039,6 +11248,7 @@ "version": "1.13.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "dev": true, "requires": { "asn1": "0.2.3", "assert-plus": "1.0.0", @@ -11469,12 +11679,21 @@ "stringstream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", + "dev": true }, "strip-ansi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=" }, "strip-indent": { "version": "1.0.1", @@ -11736,6 +11955,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", + "dev": true, "requires": { "any-promise": "1.3.0" } @@ -11744,6 +11964,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "dev": true, "requires": { "thenify": "3.3.0" } @@ -11824,6 +12045,11 @@ "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=" }, + "tinyqueue": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-1.2.3.tgz", + "integrity": "sha512-Qz9RgWuO9l8lT+Y9xvbzhPT2efIUIFd69N7eF7tJ9lnQl0iLj1M7peK7IoUGZL9DJHw9XftqLreccfxcQgYLxA==" + }, "tmp": { "version": "0.0.31", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", @@ -11858,11 +12084,6 @@ "parse-unit": "1.0.1" } }, - "to-utf8": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/to-utf8/-/to-utf8-0.0.1.tgz", - "integrity": "sha1-0Xrqcv8vujm55DYBvns/9y4ImFI=" - }, "topojson-client": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-2.1.0.tgz", @@ -11875,6 +12096,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "dev": true, "requires": { "punycode": "1.4.1" } @@ -11967,6 +12189,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, "requires": { "safe-buffer": "5.1.1" } @@ -11985,6 +12208,7 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, "optional": true }, "two-product": { @@ -12172,6 +12396,15 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" }, + "unflowify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unflowify/-/unflowify-1.0.1.tgz", + "integrity": "sha1-ouoNJcCv/MRpVeZHNXX3xaH0ppY=", + "requires": { + "flow-remove-types": "1.2.3", + "through": "2.3.8" + } + }, "union-find": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/union-find/-/union-find-1.0.2.tgz", @@ -12182,11 +12415,6 @@ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" }, - "unitbezier": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/unitbezier/-/unitbezier-0.0.0.tgz", - "integrity": "sha1-M79/XXKExTUL/Fx/dw+6dUnFSl4=" - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -12263,7 +12491,8 @@ "uuid": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", + "dev": true }, "uws": { "version": "0.14.5", @@ -12282,14 +12511,6 @@ "spdx-expression-parse": "1.0.4" } }, - "vector-tile": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/vector-tile/-/vector-tile-1.3.0.tgz", - "integrity": "sha1-BtUWqDsGPwTILvU5zxuxrr62lrQ=", - "requires": { - "point-geometry": "0.0.0" - } - }, "vectorize-text": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/vectorize-text/-/vectorize-text-3.0.2.tgz", @@ -12308,6 +12529,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, "requires": { "assert-plus": "1.0.0", "core-util-is": "1.0.2", @@ -12335,13 +12557,13 @@ "dev": true }, "vt-pbf": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-2.1.4.tgz", - "integrity": "sha1-td98P5cGFW4LmIGpncsFY1dAtSI=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.0.tgz", + "integrity": "sha512-UUCGPkpT1P/bm3R3/HX0SCnRSto44xXx0WuLFVG6C7KspdfQfU+84etoO6cITAGCdq8V5DjuWfDhvk/pyTyt3Q==", "requires": { - "pbf": "1.3.7", - "point-geometry": "0.0.0", - "vector-tile": "1.3.0" + "@mapbox/point-geometry": "0.1.0", + "@mapbox/vector-tile": "1.3.0", + "pbf": "3.1.0" } }, "w3c-hr-time": { @@ -12450,11 +12672,6 @@ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", "dev": true }, - "whoots-js": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/whoots-js/-/whoots-js-2.1.0.tgz", - "integrity": "sha1-vLIBw04OrzNfzOWuLPh0V5qZxIc=" - }, "wide-align": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", diff --git a/package.json b/package.json index 4c80b933762..2294abb7380 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "has-hover": "^1.0.1", "has-passive-events": "^1.0.0", "kdgrass": "^1.0.1", - "mapbox-gl": "^0.22.0", + "mapbox-gl": "^0.44.0", "matrix-camera-controller": "^2.1.3", "mouse-change": "^1.4.0", "mouse-event-offset": "^3.0.2", diff --git a/src/components/drawing/index.js b/src/components/drawing/index.js index 98a64b9e334..9904121f5b0 100644 --- a/src/components/drawing/index.js +++ b/src/components/drawing/index.js @@ -439,8 +439,8 @@ drawing.pointStyle = function(s, trace, gd) { }); }; -drawing.selectedPointStyle = function(s, trace) { - if(!s.size() || !trace.selectedpoints) return; +drawing.makeSelectedPointStyleFns = function(trace) { + var out = {}; var selectedAttrs = trace.selected || {}; var unselectedAttrs = trace.unselected || {}; @@ -455,40 +455,31 @@ drawing.selectedPointStyle = function(s, trace) { var smoIsDefined = smo !== undefined; var usmoIsDefined = usmo !== undefined; - s.each(function(d) { - var pt = d3.select(this); + out.opacityFn = function(d) { var dmo = d.mo; var dmoIsDefined = dmo !== undefined; - var mo2; if(dmoIsDefined || smoIsDefined || usmoIsDefined) { if(d.selected) { - if(smoIsDefined) mo2 = smo; + if(smoIsDefined) return smo; } else { - if(usmoIsDefined) mo2 = usmo; - else mo2 = DESELECTDIM * (dmoIsDefined ? dmo : mo); + if(usmoIsDefined) return usmo; + return DESELECTDIM * (dmoIsDefined ? dmo : mo); } } - - if(mo2 !== undefined) pt.style('opacity', mo2); - }); + }; var smc = selectedMarker.color; var usmc = unselectedMarker.color; if(smc || usmc) { - s.each(function(d) { - var pt = d3.select(this); - var mc2; - + out.colorFn = function(d) { if(d.selected) { - if(smc) mc2 = smc; + if(smc) return smc; } else { - if(usmc) mc2 = usmc; + if(usmc) return usmc; } - - if(mc2) Color.fill(pt, mc2); - }); + }; } var sms = selectedMarker.size; @@ -496,18 +487,45 @@ drawing.selectedPointStyle = function(s, trace) { var smsIsDefined = sms !== undefined; var usmsIsDefined = usms !== undefined; - if(Registry.traceIs(trace, 'symbols') && (smsIsDefined || usmsIsDefined)) { - s.each(function(d) { - var pt = d3.select(this); + if(smsIsDefined || usmsIsDefined) { + out.sizeFn = function(d) { var mrc = d.mrc; - var mx = d.mx || marker.symbol || 0; - var mrc2; - if(d.selected) { - mrc2 = (smsIsDefined) ? sms / 2 : mrc; + return smsIsDefined ? sms / 2 : mrc; } else { - mrc2 = (usmsIsDefined) ? usms / 2 : mrc; + return usmsIsDefined ? usms / 2 : mrc; } + }; + } + + return out; +}; + +drawing.selectedPointStyle = function(s, trace) { + if(!s.size() || !trace.selectedpoints) return; + + var fns = drawing.makeSelectedPointStyleFns(trace); + var marker = trace.marker || {}; + + s.each(function(d) { + var pt = d3.select(this); + var mo2 = fns.opacityFn(d); + if(mo2 !== undefined) pt.style('opacity', mo2); + }); + + if(fns.colorFn) { + s.each(function(d) { + var pt = d3.select(this); + var mc2 = fns.colorFn(d); + if(mc2) Color.fill(pt, mc2); + }); + } + + if(Registry.traceIs(trace, 'symbols') && fns.sizeFn) { + s.each(function(d) { + var pt = d3.select(this); + var mx = d.mx || marker.symbol || 0; + var mrc2 = fns.sizeFn(d); pt.attr('d', makePointPath(drawing.symbolNumber(mx), mrc2)); diff --git a/src/plots/cartesian/dragbox.js b/src/plots/cartesian/dragbox.js index 3a7bcbea755..3ded8e18b47 100644 --- a/src/plots/cartesian/dragbox.js +++ b/src/plots/cartesian/dragbox.js @@ -358,6 +358,10 @@ function makeDragBox(gd, plotinfo, x, y, w, h, ns, ew) { return; } + if(redrawTimer === null) { + clearSelect(zoomlayer); + } + // If a transition is in progress, then disable any behavior: if(gd._transitioningWithDuration) { e.preventDefault(); diff --git a/src/plots/mapbox/constants.js b/src/plots/mapbox/constants.js index cde8a55fc86..e724315f471 100644 --- a/src/plots/mapbox/constants.js +++ b/src/plots/mapbox/constants.js @@ -9,13 +9,21 @@ 'use strict'; +var requiredVersion = '0.44.0'; module.exports = { + requiredVersion: requiredVersion, + styleUrlPrefix: 'mapbox://styles/mapbox/', styleUrlSuffix: 'v9', controlContainerClassName: 'mapboxgl-control-container', + wrongVersionErrorMsg: [ + 'Your custom plotly.js bundle is not using the correct mapbox-gl version', + 'Please install mapbox-gl@' + requiredVersion + '.' + ].join('\n'), + noAccessTokenErrorMsg: [ 'Missing Mapbox access token.', 'Mapbox trace type require a Mapbox access token to be registered.', @@ -24,5 +32,11 @@ module.exports = { 'More info here: https://www.mapbox.com/help/define-access-token/' ].join('\n'), - mapOnErrorMsg: 'Mapbox error.' + mapOnErrorMsg: 'Mapbox error.', + + // a subset of node_modules/mapbox-gl/dist/mapbox-gl.css + styleRules: { + map: 'overflow:hidden;position:relative;', + 'missing-css': 'display:none', + } }; diff --git a/src/plots/mapbox/index.js b/src/plots/mapbox/index.js index 0e7b12d57d8..dc19d1c5dca 100644 --- a/src/plots/mapbox/index.js +++ b/src/plots/mapbox/index.js @@ -6,7 +6,6 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var mapboxgl = require('mapbox-gl'); @@ -20,6 +19,9 @@ var constants = require('./constants'); var MAPBOX = 'mapbox'; +for(var k in constants.styleRules) { + Lib.addStyleRule('.mapboxgl-' + k, constants.styleRules[k]); +} exports.name = MAPBOX; @@ -53,6 +55,10 @@ exports.plot = function plotMapbox(gd) { var calcData = gd.calcdata; var mapboxIds = fullLayout._subplots[MAPBOX]; + if(mapboxgl.version !== constants.requiredVersion) { + throw new Error(constants.wrongVersionErrorMsg); + } + var accessToken = findAccessToken(gd, mapboxIds); mapboxgl.accessToken = accessToken; diff --git a/src/plots/mapbox/layers.js b/src/plots/mapbox/layers.js index f6ed71a412e..cd535b75141 100644 --- a/src/plots/mapbox/layers.js +++ b/src/plots/mapbox/layers.js @@ -6,13 +6,11 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var Lib = require('../../lib'); var convertTextOpts = require('./convert_text_opts'); - function MapboxLayer(mapbox, index) { this.mapbox = mapbox; this.map = mapbox.map; @@ -36,32 +34,26 @@ var proto = MapboxLayer.prototype; proto.update = function update(opts) { if(!this.visible) { - // IMPORTANT: must create source before layer to not cause errors this.updateSource(opts); this.updateLayer(opts); - } - else if(this.needsNewSource(opts)) { - + } else if(this.needsNewSource(opts)) { // IMPORTANT: must delete layer before source to not cause errors this.updateLayer(opts); this.updateSource(opts); - } - else if(this.needsNewLayer(opts)) { + } else if(this.needsNewLayer(opts)) { this.updateLayer(opts); + } else { + this.updateStyle(opts); } - this.updateStyle(opts); - this.visible = isVisible(opts); }; proto.needsNewSource = function(opts) { - // for some reason changing layer to 'fill' or 'symbol' // w/o changing the source throws an exception in mapbox-gl 0.18 ; // stay safe and make new source on type changes - return ( this.sourceType !== opts.sourcetype || this.source !== opts.source || @@ -93,29 +85,27 @@ proto.updateSource = function(opts) { proto.updateLayer = function(opts) { var map = this.map; + var convertedOpts = convertOpts(opts); if(map.getLayer(this.idLayer)) map.removeLayer(this.idLayer); this.layerType = opts.type; - if(!isVisible(opts)) return; - - map.addLayer({ - id: this.idLayer, - source: this.idSource, - 'source-layer': opts.sourcelayer || '', - type: opts.type - }, opts.below); - - // the only way to make a layer invisible is to remove it - var layoutOpts = { visibility: 'visible' }; - this.mapbox.setOptions(this.idLayer, 'setLayoutProperty', layoutOpts); + if(isVisible(opts)) { + map.addLayer({ + id: this.idLayer, + source: this.idSource, + 'source-layer': opts.sourcelayer || '', + type: opts.type, + layout: convertedOpts.layout, + paint: convertedOpts.paint + }, opts.below); + } }; proto.updateStyle = function(opts) { - var convertedOpts = convertOpts(opts); - if(isVisible(opts)) { + var convertedOpts = convertOpts(opts); this.mapbox.setOptions(this.idLayer, 'setLayoutProperty', convertedOpts.layout); this.mapbox.setOptions(this.idLayer, 'setPaintProperty', convertedOpts.paint); } @@ -123,7 +113,6 @@ proto.updateStyle = function(opts) { proto.dispose = function dispose() { var map = this.map; - map.removeLayer(this.idLayer); map.removeSource(this.idSource); }; @@ -198,19 +187,18 @@ function convertOpts(opts) { } function convertSourceOpts(opts) { - var sourceType = opts.sourcetype, - source = opts.source, - sourceOpts = { type: sourceType }, - isSourceAString = (typeof source === 'string'), - field; - - if(sourceType === 'geojson') field = 'data'; - else if(sourceType === 'vector') { - field = isSourceAString ? 'url' : 'tiles'; + var sourceType = opts.sourcetype; + var source = opts.source; + var sourceOpts = {type: sourceType}; + var field; + + if(sourceType === 'geojson') { + field = 'data'; + } else if(sourceType === 'vector') { + field = typeof source === 'string' ? 'url' : 'tiles'; } sourceOpts[field] = source; - return sourceOpts; } diff --git a/src/plots/mapbox/mapbox.js b/src/plots/mapbox/mapbox.js index 608ef00ee34..4df6dfd4555 100644 --- a/src/plots/mapbox/mapbox.js +++ b/src/plots/mapbox/mapbox.js @@ -50,9 +50,7 @@ function Mapbox(opts) { var proto = Mapbox.prototype; module.exports = function createMapbox(opts) { - var mapbox = new Mapbox(opts); - - return mapbox; + return new Mapbox(opts); }; proto.plot = function(calcData, fullLayout, promises) { @@ -76,8 +74,7 @@ proto.plot = function(calcData, fullLayout, promises) { promise = new Promise(function(resolve, reject) { self.createMap(calcData, fullLayout, resolve, reject); }); - } - else { + } else { promise = new Promise(function(resolve, reject) { self.updateMap(calcData, fullLayout, resolve, reject); }); @@ -120,15 +117,14 @@ proto.createMap = function(calcData, fullLayout, resolve, reject) { self.div.removeChild(controlContainer); // make sure canvas does not inherit left and top css - map._canvas.canvas.style.left = '0px'; - map._canvas.canvas.style.top = '0px'; + map._canvas.style.left = '0px'; + map._canvas.style.top = '0px'; self.rejectOnError(reject); map.once('load', function() { self.updateData(calcData); self.updateLayout(fullLayout); - self.resolveOnRender(resolve); }); @@ -164,7 +160,6 @@ proto.createMap = function(calcData, fullLayout, resolve, reject) { var bb = self.div.getBoundingClientRect(); // some hackery to get Fx.hover to work - evt.clientX = evt.point.x + bb.left; evt.clientY = evt.point.y + bb.top; @@ -209,11 +204,17 @@ proto.createMap = function(calcData, fullLayout, resolve, reject) { gd.emit('plotly_doubleclick', null); }); + + // define clear select on map creation, to keep one ref per map, + // so that map.on / map.off in updateFx works as expected + self.clearSelect = function() { + gd._fullLayout._zoomlayer.selectAll('.select-outline').remove(); + }; }; proto.updateMap = function(calcData, fullLayout, resolve, reject) { - var self = this, - map = self.map; + var self = this; + var map = self.map; self.rejectOnError(reject); @@ -223,29 +224,23 @@ proto.updateMap = function(calcData, fullLayout, resolve, reject) { self.styleObj = styleObj; map.setStyle(styleObj.style); - map.style.once('load', function() { - + map.once('styledata', function() { // need to rebuild trace layers on reload // to avoid 'lost event' errors self.traceHash = {}; - self.updateData(calcData); self.updateLayout(fullLayout); - self.resolveOnRender(resolve); }); - } - else { + } else { self.updateData(calcData); self.updateLayout(fullLayout); - self.resolveOnRender(resolve); } }; proto.updateData = function(calcData) { var traceHash = this.traceHash; - var traceObj, trace, i, j; // update or create trace objects @@ -255,8 +250,9 @@ proto.updateData = function(calcData) { trace = calcTrace[0].trace; traceObj = traceHash[trace.uid]; - if(traceObj) traceObj.update(calcTrace); - else if(trace._module) { + if(traceObj) { + traceObj.update(calcTrace); + } else if(trace._module) { traceHash[trace.uid] = trace._module.plot(this, calcTrace); } } @@ -269,7 +265,6 @@ proto.updateData = function(calcData) { for(j = 0; j < calcData.length; j++) { trace = calcData[j][0].trace; - if(id === trace.uid) continue id_loop; } @@ -300,7 +295,8 @@ proto.resolveOnRender = function(resolve) { map.on('render', function onRender() { if(map.loaded()) { map.off('render', onRender); - resolve(); + // resolve at end of render loop + setTimeout(resolve, 0); } }); }; @@ -323,19 +319,15 @@ proto.createFramework = function(fullLayout) { var self = this; var div = self.div = document.createElement('div'); - div.id = self.uid; div.style.position = 'absolute'; - self.container.appendChild(div); // create mock x/y axes for hover routine - self.xaxis = { _id: 'x', c2p: function(v) { return self.project(v).x; } }; - self.yaxis = { _id: 'y', c2p: function(v) { return self.project(v).y; } @@ -376,6 +368,7 @@ proto.updateFx = function(fullLayout) { if(dragMode === 'select' || dragMode === 'lasso') { map.dragPan.disable(); + map.on('zoomstart', self.clearSelect); var dragOptions = { element: self.div, @@ -397,18 +390,16 @@ proto.updateFx = function(fullLayout) { dragElement.init(dragOptions); } else { map.dragPan.enable(); + map.off('zoomstart', self.clearSelect); self.div.onmousedown = null; } }; proto.updateFramework = function(fullLayout) { - var domain = fullLayout[this.id].domain, - size = fullLayout._size; + var domain = fullLayout[this.id].domain; + var size = fullLayout._size; var style = this.div.style; - - // TODO Is this correct? It seems to get the map zoom level wrong? - style.width = size.w * (domain.x[1] - domain.x[0]) + 'px'; style.height = size.h * (domain.y[1] - domain.y[0]) + 'px'; style.left = size.l + domain.x[0] * size.w + 'px'; @@ -422,10 +413,10 @@ proto.updateFramework = function(fullLayout) { }; proto.updateLayers = function() { - var opts = this.opts, - layers = opts.layers, - layerList = this.layerList, - i; + var opts = this.opts; + var layers = opts.layers; + var layerList = this.layerList; + var i; // if the layer arrays don't match, // don't try to be smart, @@ -441,8 +432,7 @@ proto.updateLayers = function() { for(i = 0; i < layers.length; i++) { layerList.push(createMapboxLayer(this, i, layers[i])); } - } - else { + } else { for(i = 0; i < layers.length; i++) { layerList[i].update(layers[i]); } @@ -458,41 +448,15 @@ proto.destroy = function() { }; proto.toImage = function() { + this.map.stop(); return this.map.getCanvas().toDataURL(); }; -// convenience wrapper to create blank GeoJSON sources -// and avoid 'invalid GeoJSON' errors -proto.initSource = function(idSource) { - var blank = { - type: 'geojson', - data: { - type: 'Feature', - geometry: { - type: 'Point', - coordinates: [] - } - } - }; - - return this.map.addSource(idSource, blank); -}; - -// convenience wrapper to set data of GeoJSON sources -proto.setSourceData = function(idSource, data) { - this.map.getSource(idSource).setData(data); -}; - // convenience wrapper to create set multiple layer // 'layout' or 'paint options at once. proto.setOptions = function(id, methodName, opts) { - var map = this.map, - keys = Object.keys(opts); - - for(var i = 0; i < keys.length; i++) { - var key = keys[i]; - - map[methodName](id, key, opts[key]); + for(var k in opts) { + this.map[methodName](id, k, opts[k]); } }; @@ -517,25 +481,25 @@ proto.getView = function() { }; function getStyleObj(val) { - var styleValues = layoutAttributes.style.values, - styleDflt = layoutAttributes.style.dflt, - styleObj = {}; + var styleValues = layoutAttributes.style.values; + var styleDflt = layoutAttributes.style.dflt; + var styleObj = {}; if(Lib.isPlainObject(val)) { styleObj.id = val.id; styleObj.style = val; - } - else if(typeof val === 'string') { + } else if(typeof val === 'string') { styleObj.id = val; styleObj.style = (styleValues.indexOf(val) !== -1) ? convertStyleVal(val) : val; - } - else { + } else { styleObj.id = styleDflt; styleObj.style = convertStyleVal(styleDflt); } + styleObj.transition = {duration: 0, delay: 0}; + return styleObj; } diff --git a/src/snapshot/helpers.js b/src/snapshot/helpers.js index 62057db8af1..ad76c746da3 100644 --- a/src/snapshot/helpers.js +++ b/src/snapshot/helpers.js @@ -10,12 +10,13 @@ 'use strict'; exports.getDelay = function(fullLayout) { - - // polar clears fullLayout._has for some reason if(!fullLayout._has) return 0; - // maybe we should add a 'gl' (and 'svg') layoutCategory ?? - return (fullLayout._has('gl3d') || fullLayout._has('gl2d')) ? 500 : 0; + return ( + fullLayout._has('gl3d') || + fullLayout._has('gl2d') || + fullLayout._has('mapbox') + ) ? 500 : 0; }; exports.getRedrawFunc = function(gd) { diff --git a/src/traces/scattermapbox/attributes.js b/src/traces/scattermapbox/attributes.js index 1c9005ec2ac..49a20454a0e 100644 --- a/src/traces/scattermapbox/attributes.js +++ b/src/traces/scattermapbox/attributes.js @@ -20,7 +20,6 @@ var overrideAll = require('../../plot_api/edit_types').overrideAll; var lineAttrs = scatterGeoAttrs.line; var markerAttrs = scatterGeoAttrs.marker; - module.exports = overrideAll({ lon: scatterGeoAttrs.lon, lat: scatterGeoAttrs.lat, @@ -108,14 +107,10 @@ module.exports = overrideAll({ textposition: mapboxAttrs.layers.symbol.textposition, selected: { - marker: { - opacity: scatterAttrs.selected.marker.opacity - } + marker: scatterAttrs.selected.marker }, unselected: { - marker: { - opacity: scatterAttrs.unselected.marker.opacity - } + marker: scatterAttrs.unselected.marker }, hoverinfo: extendFlat({}, plotAttrs.hoverinfo, { diff --git a/src/traces/scattermapbox/convert.js b/src/traces/scattermapbox/convert.js index e93511580ef..34439328ed2 100644 --- a/src/traces/scattermapbox/convert.js +++ b/src/traces/scattermapbox/convert.js @@ -6,7 +6,6 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var isNumeric = require('fast-isnumeric'); @@ -16,30 +15,26 @@ var BADNUM = require('../../constants/numerical').BADNUM; var geoJsonUtils = require('../../lib/geojson_utils'); var Colorscale = require('../../components/colorscale'); +var Drawing = require('../../components/drawing'); var makeBubbleSizeFn = require('../scatter/make_bubble_size_func'); var subTypes = require('../scatter/subtypes'); var convertTextOpts = require('../../plots/mapbox/convert_text_opts'); -var DESELECTDIM = require('../../constants/interactions').DESELECTDIM; - -var COLOR_PROP = 'circle-color'; -var SIZE_PROP = 'circle-radius'; -var OPACITY_PROP = 'circle-opacity'; module.exports = function convert(calcTrace) { var trace = calcTrace[0].trace; - var isVisible = (trace.visible === true), - hasFill = (trace.fill !== 'none'), - hasLines = subTypes.hasLines(trace), - hasMarkers = subTypes.hasMarkers(trace), - hasText = subTypes.hasText(trace), - hasCircles = (hasMarkers && trace.marker.symbol === 'circle'), - hasSymbols = (hasMarkers && trace.marker.symbol !== 'circle'); + var isVisible = (trace.visible === true); + var hasFill = (trace.fill !== 'none'); + var hasLines = subTypes.hasLines(trace); + var hasMarkers = subTypes.hasMarkers(trace); + var hasText = subTypes.hasText(trace); + var hasCircles = (hasMarkers && trace.marker.symbol === 'circle'); + var hasSymbols = (hasMarkers && trace.marker.symbol !== 'circle'); - var fill = initContainer(), - line = initContainer(), - circle = initContainer(), - symbol = initContainer(); + var fill = initContainer(); + var line = initContainer(); + var circle = initContainer(); + var symbol = initContainer(); var opts = { fill: fill, @@ -80,18 +75,14 @@ module.exports = function convert(calcTrace) { } if(hasCircles) { - var hash = {}; - hash[COLOR_PROP] = {}; - hash[SIZE_PROP] = {}; - hash[OPACITY_PROP] = {}; - - circle.geojson = makeCircleGeoJSON(calcTrace, hash); + var circleOpts = makeCircleOpts(calcTrace); + circle.geojson = circleOpts.geojson; circle.layout.visibility = 'visible'; Lib.extendFlat(circle.paint, { - 'circle-opacity': calcCircleOpacity(trace, hash), - 'circle-color': calcCircleColor(trace, hash), - 'circle-radius': calcCircleRadius(trace, hash) + 'circle-color': circleOpts.mcc, + 'circle-radius': circleOpts.mrc, + 'circle-opacity': circleOpts.mo }); } @@ -121,6 +112,8 @@ module.exports = function convert(calcTrace) { var iconSize = (trace.marker || {}).size, textOpts = convertTextOpts(trace.textposition, iconSize); + // all data-driven below !! + Lib.extendFlat(symbol.layout, { 'text-size': trace.textfont.size, 'text-anchor': textOpts.anchor, @@ -148,107 +141,99 @@ function initContainer() { }; } -// N.B. `hash` is mutated here -// -// The `hash` object contains mapping between values -// (e.g. calculated marker.size and marker.color items) -// and their index in the input arrayOk attributes. -// -// GeoJSON features have their 'data-driven' properties set to -// the index of the first value found in the data. -// -// The `hash` object is then converted to mapbox `stops` arrays -// mapping index to value. -// -// The solution prove to be more robust than trying to generate -// `stops` arrays from scale functions. -// -// TODO axe this when we bump mapbox-gl and rewrite this using -// "identity" property functions. -// See https://github.com/plotly/plotly.js/pull/1543 -// -function makeCircleGeoJSON(calcTrace, hash) { +function makeCircleOpts(calcTrace) { var trace = calcTrace[0].trace; var marker = trace.marker; + var selectedpoints = trace.selectedpoints; + var arrayColor = Array.isArray(marker.color); + var arraySize = Array.isArray(marker.size); + var arrayOpacity = Array.isArray(marker.opacity); + var i; + + function addTraceOpacity(o) { return trace.opacity * o; } + + function size2radius(s) { return s / 2; } var colorFn; - if(Colorscale.hasColorscale(trace, 'marker')) { - colorFn = Colorscale.makeColorScaleFunc( - Colorscale.extractScale(marker.colorscale, marker.cmin, marker.cmax) - ); - } else if(Array.isArray(marker.color)) { - colorFn = Lib.identity; + if(arrayColor) { + if(Colorscale.hasColorscale(trace, 'marker')) { + colorFn = Colorscale.makeColorScaleFunc( + Colorscale.extractScale(marker.colorscale, marker.cmin, marker.cmax) + ); + } else { + colorFn = Lib.identity; + } } var sizeFn; - if(subTypes.isBubble(trace)) { + if(arraySize) { sizeFn = makeBubbleSizeFn(trace); } - var combineOpacities; - if(trace.selectedpoints) { - combineOpacities = function(d, mo) { - return trace.opacity * mo * (d.selected ? 1 : DESELECTDIM); - }; - } else { - combineOpacities = function(d, mo) { - return trace.opacity * mo; - }; - } - var opacityFn; - if(Array.isArray(marker.opacity)) { - opacityFn = function(d) { - var mo = isNumeric(d.mo) ? +Lib.constrain(d.mo, 0, 1) : 0; - return combineOpacities(d, mo); - }; - } else if(trace.selectedpoints) { - opacityFn = function(d) { - return combineOpacities(d, marker.opacity); + if(arrayOpacity) { + opacityFn = function(mo) { + var mo2 = isNumeric(mo) ? +Lib.constrain(mo, 0, 1) : 0; + return addTraceOpacity(mo2); }; } - // Translate vals in trace arrayOk containers - // into a val-to-index hash object - function translate(props, key, val, index) { - if(hash[key][val] === undefined) hash[key][val] = index; - - props[key] = hash[key][val]; - } - var features = []; - - for(var i = 0; i < calcTrace.length; i++) { + for(i = 0; i < calcTrace.length; i++) { var calcPt = calcTrace[i]; var lonlat = calcPt.lonlat; if(isBADNUM(lonlat)) continue; var props = {}; - if(colorFn) { - var mcc = calcPt.mcc = colorFn(calcPt.mc); - translate(props, COLOR_PROP, mcc, i); - } - if(sizeFn) { - translate(props, SIZE_PROP, sizeFn(calcPt.ms), i); - } - if(opacityFn) { - translate(props, OPACITY_PROP, opacityFn(calcPt), i); - } + if(colorFn) props.mcc = calcPt.mcc = colorFn(calcPt.mc); + if(sizeFn) props.mrc = calcPt.mrc = sizeFn(calcPt.ms); + if(opacityFn) props.mo = opacityFn(calcPt.mo); + if(selectedpoints) props.selected = calcPt.selected || 0; features.push({ type: 'Feature', - geometry: { - type: 'Point', - coordinates: lonlat - }, + geometry: {type: 'Point', coordinates: lonlat}, properties: props }); } + var fns; + if(selectedpoints) { + fns = Drawing.makeSelectedPointStyleFns(trace); + + for(i = 0; i < features.length; i++) { + var d = features[i].properties; + + var mo2 = fns.opacityFn(d); + if(mo2 !== undefined) d.mo = addTraceOpacity(mo2); + else if(d.mo === undefined) d.mo = addTraceOpacity(marker.opacity); + + if(fns.colorFn) { + var mc2 = fns.colorFn(d); + if(mc2) d.mcc = mc2; + else if(!d.mcc) d.mcc = marker.color; + } + + if(fns.sizeFn) { + var mrc2 = fns.sizeFn(d); + if(mrc2 !== undefined) d.mrc = mrc2; + else if(d.mrc === undefined) d.mrc = size2radius(marker.size); + } + } + } + return { - type: 'FeatureCollection', - features: features + geojson: {type: 'FeatureCollection', features: features}, + mcc: arrayColor || (fns && fns.colorFn) ? + {type: 'identity', property: 'mcc'} : + marker.color, + mrc: arraySize || (fns && fns.sizeFn) ? + {type: 'identity', property: 'mrc'} : + size2radius(marker.size), + mo: arrayOpacity || selectedpoints ? + {type: 'identity', property: 'mo'} : + addTraceOpacity(marker.opacity) }; } @@ -293,84 +278,6 @@ function makeSymbolGeoJSON(calcTrace) { }; } -function calcCircleColor(trace, hash) { - var marker = trace.marker, - out; - - if(Array.isArray(marker.color)) { - var vals = Object.keys(hash[COLOR_PROP]), - stops = []; - - for(var i = 0; i < vals.length; i++) { - var val = vals[i]; - - stops.push([ hash[COLOR_PROP][val], val ]); - } - - out = { - property: COLOR_PROP, - stops: stops - }; - - } - else { - out = marker.color; - } - - return out; -} - -function calcCircleRadius(trace, hash) { - var marker = trace.marker, - out; - - if(Array.isArray(marker.size)) { - var vals = Object.keys(hash[SIZE_PROP]), - stops = []; - - for(var i = 0; i < vals.length; i++) { - var val = vals[i]; - - stops.push([ hash[SIZE_PROP][val], +val ]); - } - - out = { - property: SIZE_PROP, - stops: stops.sort(ascending) - }; - } - else { - out = marker.size / 2; - } - - return out; -} - -function calcCircleOpacity(trace, hash) { - var marker = trace.marker; - var out; - - if(Array.isArray(marker.opacity) || trace.selectedpoints) { - var vals = Object.keys(hash[OPACITY_PROP]); - var stops = []; - - for(var i = 0; i < vals.length; i++) { - var val = vals[i]; - stops.push([hash[OPACITY_PROP][val], +val]); - } - - out = { - property: OPACITY_PROP, - stops: stops.sort(ascending) - }; - } - else { - out = trace.opacity * marker.opacity; - } - - return out; -} - function getFillFunc(attr) { if(Array.isArray(attr)) { return function(v) { return v; }; @@ -385,8 +292,6 @@ function getFillFunc(attr) { function blankFillFunc() { return ''; } -function ascending(a, b) { return a[0] - b[0]; } - // only need to check lon (OR lat) function isBADNUM(lonlat) { return lonlat[0] === BADNUM; diff --git a/src/traces/scattermapbox/defaults.js b/src/traces/scattermapbox/defaults.js index 210f9e1d47b..c748d804df4 100644 --- a/src/traces/scattermapbox/defaults.js +++ b/src/traces/scattermapbox/defaults.js @@ -39,7 +39,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout } if(subTypes.hasMarkers(traceOut)) { - handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noLine: true, noSelect: true}); + handleMarkerDefaults(traceIn, traceOut, defaultColor, layout, coerce, {noLine: true}); // array marker.size and marker.color are only supported with circles diff --git a/src/traces/scattermapbox/hover.js b/src/traces/scattermapbox/hover.js index a1e632cc907..0f21d133aae 100644 --- a/src/traces/scattermapbox/hover.js +++ b/src/traces/scattermapbox/hover.js @@ -10,20 +10,22 @@ 'use strict'; var Fx = require('../../components/fx'); +var Lib = require('../../lib'); var getTraceColor = require('../scatter/get_trace_color'); var fillHoverText = require('../scatter/fill_hover_text'); var BADNUM = require('../../constants/numerical').BADNUM; module.exports = function hoverPoints(pointData, xval, yval) { - var cd = pointData.cd, - trace = cd[0].trace, - xa = pointData.xa, - ya = pointData.ya; + var cd = pointData.cd; + var trace = cd[0].trace; + var xa = pointData.xa; + var ya = pointData.ya; + var subplot = pointData.subplot; // compute winding number about [-180, 180] globe var winding = (xval >= 0) ? - Math.floor((xval + 180) / 360) : - Math.ceil((xval - 180) / 360); + Math.floor((xval + 180) / 360) : + Math.ceil((xval - 180) / 360); // shift longitude to [-180, 180] to determine closest point var lonShift = winding * 360; @@ -31,11 +33,13 @@ module.exports = function hoverPoints(pointData, xval, yval) { function distFn(d) { var lonlat = d.lonlat; - if(lonlat[0] === BADNUM) return Infinity; - var dx = Math.abs(xa.c2p(lonlat) - xa.c2p([xval2, lonlat[1]])); - var dy = Math.abs(ya.c2p(lonlat) - ya.c2p([lonlat[0], yval])); + var lon = Lib.wrap180(lonlat[0]); + var lat = lonlat[1]; + var pt = subplot.project([lon, lat]); + var dx = pt.x - xa.c2p([xval2, lat]); + var dy = pt.y - ya.c2p([lon, yval]); var rad = Math.max(3, d.mrc || 0); return Math.max(Math.sqrt(dx * dx + dy * dy) - rad, 1 - 3 / rad); @@ -46,14 +50,14 @@ module.exports = function hoverPoints(pointData, xval, yval) { // skip the rest (for this trace) if we didn't find a close point if(pointData.index === false) return; - var di = cd[pointData.index], - lonlat = di.lonlat, - lonlatShifted = [lonlat[0] + lonShift, lonlat[1]]; + var di = cd[pointData.index]; + var lonlat = di.lonlat; + var lonlatShifted = [Lib.wrap180(lonlat[0]) + lonShift, lonlat[1]]; // shift labels back to original winded globe - var xc = xa.c2p(lonlatShifted), - yc = ya.c2p(lonlatShifted), - rad = di.mrc || 1; + var xc = xa.c2p(lonlatShifted); + var yc = ya.c2p(lonlatShifted); + var rad = di.mrc || 1; pointData.x0 = xc - rad; pointData.x1 = xc + rad; @@ -72,7 +76,6 @@ function getExtraText(trace, di, labels) { var isAll = parts.indexOf('all') !== -1; var hasLon = parts.indexOf('lon') !== -1; var hasLat = parts.indexOf('lat') !== -1; - var lonlat = di.lonlat; var text = []; diff --git a/src/traces/scattermapbox/plot.js b/src/traces/scattermapbox/plot.js index 82fc1439587..cba49fbee18 100644 --- a/src/traces/scattermapbox/plot.js +++ b/src/traces/scattermapbox/plot.js @@ -6,56 +6,29 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var convert = require('./convert'); - -function ScatterMapbox(mapbox, uid) { - this.mapbox = mapbox; - this.map = mapbox.map; - +function ScatterMapbox(subplot, uid) { + this.subplot = subplot; this.uid = uid; - this.idSourceFill = uid + '-source-fill'; - this.idSourceLine = uid + '-source-line'; - this.idSourceCircle = uid + '-source-circle'; - this.idSourceSymbol = uid + '-source-symbol'; - - this.idLayerFill = uid + '-layer-fill'; - this.idLayerLine = uid + '-layer-line'; - this.idLayerCircle = uid + '-layer-circle'; - this.idLayerSymbol = uid + '-layer-symbol'; - - this.mapbox.initSource(this.idSourceFill); - this.mapbox.initSource(this.idSourceLine); - this.mapbox.initSource(this.idSourceCircle); - this.mapbox.initSource(this.idSourceSymbol); - - this.map.addLayer({ - id: this.idLayerFill, - source: this.idSourceFill, - type: 'fill' - }); + this.sourceIds = { + fill: uid + '-source-fill', + line: uid + '-source-line', + circle: uid + '-source-circle', + symbol: uid + '-source-symbol' + }; - this.map.addLayer({ - id: this.idLayerLine, - source: this.idSourceLine, - type: 'line' - }); - - this.map.addLayer({ - id: this.idLayerCircle, - source: this.idSourceCircle, - type: 'circle' - }); + this.layerIds = { + fill: uid + '-layer-fill', + line: uid + '-layer-line', + circle: uid + '-layer-circle', + symbol: uid + '-layer-symbol' + }; - this.map.addLayer({ - id: this.idLayerSymbol, - source: this.idSourceSymbol, - type: 'symbol' - }); + this.order = ['fill', 'line', 'circle', 'symbol']; // We could merge the 'fill' source with the 'line' source and // the 'circle' source with the 'symbol' source if ever having @@ -64,33 +37,43 @@ function ScatterMapbox(mapbox, uid) { var proto = ScatterMapbox.prototype; -proto.update = function update(calcTrace) { - var mapbox = this.mapbox; - var opts = convert(calcTrace); +proto.addSource = function(k, opts) { + this.subplot.map.addSource(this.sourceIds[k], { + type: 'geojson', + data: opts.geojson + }); +}; - mapbox.setOptions(this.idLayerFill, 'setLayoutProperty', opts.fill.layout); - mapbox.setOptions(this.idLayerLine, 'setLayoutProperty', opts.line.layout); - mapbox.setOptions(this.idLayerCircle, 'setLayoutProperty', opts.circle.layout); - mapbox.setOptions(this.idLayerSymbol, 'setLayoutProperty', opts.symbol.layout); +proto.setSourceData = function(k, opts) { + this.subplot.map + .getSource(this.sourceIds[k]) + .setData(opts.geojson); +}; - if(isVisible(opts.fill)) { - mapbox.setSourceData(this.idSourceFill, opts.fill.geojson); - mapbox.setOptions(this.idLayerFill, 'setPaintProperty', opts.fill.paint); - } +proto.addLayer = function(k, opts) { + this.subplot.map.addLayer({ + type: k, + id: this.layerIds[k], + source: this.sourceIds[k], + layout: opts.layout, + paint: opts.paint + }); +}; - if(isVisible(opts.line)) { - mapbox.setSourceData(this.idSourceLine, opts.line.geojson); - mapbox.setOptions(this.idLayerLine, 'setPaintProperty', opts.line.paint); - } +proto.update = function update(calcTrace) { + var subplot = this.subplot; + var optsAll = convert(calcTrace); - if(isVisible(opts.circle)) { - mapbox.setSourceData(this.idSourceCircle, opts.circle.geojson); - mapbox.setOptions(this.idLayerCircle, 'setPaintProperty', opts.circle.paint); - } + for(var i = 0; i < this.order.length; i++) { + var k = this.order[i]; + var opts = optsAll[k]; - if(isVisible(opts.symbol)) { - mapbox.setSourceData(this.idSourceSymbol, opts.symbol.geojson); - mapbox.setOptions(this.idLayerSymbol, 'setPaintProperty', opts.symbol.paint); + subplot.setOptions(this.layerIds[k], 'setLayoutProperty', opts.layout); + + if(opts.layout.visibility === 'visible') { + this.setSourceData(k, opts); + subplot.setOptions(this.layerIds[k], 'setPaintProperty', opts.paint); + } } // link ref for quick update during selections @@ -98,28 +81,30 @@ proto.update = function update(calcTrace) { }; proto.dispose = function dispose() { - var map = this.map; - - map.removeLayer(this.idLayerFill); - map.removeLayer(this.idLayerLine); - map.removeLayer(this.idLayerCircle); - map.removeLayer(this.idLayerSymbol); + var map = this.subplot.map; - map.removeSource(this.idSourceFill); - map.removeSource(this.idSourceLine); - map.removeSource(this.idSourceCircle); - map.removeSource(this.idSourceSymbol); + for(var i = 0; i < this.order.length; i++) { + var k = this.order[i]; + map.removeLayer(this.layerIds[k]); + map.removeSource(this.sourceIds[k]); + } }; -function isVisible(layerOpts) { - return layerOpts.layout.visibility === 'visible'; -} - -module.exports = function createScatterMapbox(mapbox, calcTrace) { +module.exports = function createScatterMapbox(subplot, calcTrace) { var trace = calcTrace[0].trace; + var scatterMapbox = new ScatterMapbox(subplot, trace.uid); + var optsAll = convert(calcTrace); + + for(var i = 0; i < scatterMapbox.order.length; i++) { + var k = scatterMapbox.order[i]; + var opts = optsAll[k]; - var scatterMapbox = new ScatterMapbox(mapbox, trace.uid); - scatterMapbox.update(calcTrace); + scatterMapbox.addSource(k, opts); + scatterMapbox.addLayer(k, opts); + } + + // link ref for quick update during selections + calcTrace[0].trace._glTrace = scatterMapbox; return scatterMapbox; }; diff --git a/src/traces/scattermapbox/select.js b/src/traces/scattermapbox/select.js index cce4d709c8c..4f6e151d6a9 100644 --- a/src/traces/scattermapbox/select.js +++ b/src/traces/scattermapbox/select.js @@ -6,9 +6,9 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; +var Lib = require('../../lib'); var subtypes = require('../scatter/subtypes'); module.exports = function selectPoints(searchInfo, polygon) { @@ -17,8 +17,7 @@ module.exports = function selectPoints(searchInfo, polygon) { var ya = searchInfo.yaxis; var selection = []; var trace = cd[0].trace; - - var di, lonlat, x, y, i; + var i; if(!subtypes.hasMarkers(trace)) return []; @@ -28,12 +27,12 @@ module.exports = function selectPoints(searchInfo, polygon) { } } else { for(i = 0; i < cd.length; i++) { - di = cd[i]; - lonlat = di.lonlat; - x = xa.c2p(lonlat); - y = ya.c2p(lonlat); + var di = cd[i]; + var lonlat = di.lonlat; + var lonlat2 = [Lib.wrap180(lonlat[0]), lonlat[1]]; + var xy = [xa.c2p(lonlat2), ya.c2p(lonlat2)]; - if(polygon.contains([x, y])) { + if(polygon.contains(xy)) { selection.push({ pointNumber: i, lon: lonlat[0], diff --git a/tasks/noci_test.sh b/tasks/noci_test.sh index c92ea7dd62c..70e53415410 100755 --- a/tasks/noci_test.sh +++ b/tasks/noci_test.sh @@ -1,13 +1,22 @@ #! /bin/bash EXIT_STATE=0 +root=$(dirname $0)/.. -# tests that aren't run on CI +# tests that aren't run on CI (yet) # jasmine specs with @noCI tag npm run test-jasmine -- --tags=noCI --nowatch || EXIT_STATE=$? # mapbox image tests take too much resources on CI -npm run test-image -- mapbox_* --queue || EXIT_STATE=$? + +# since the update to mapbox-gl@0.44.0, we must use 'new' image-exporter +# as mapbox-gl versions >0.22.1 aren't supported on nw.js@0.12 used in the +# 'old' image server +$root/../image-exporter/bin/plotly-graph-exporter.js $root/test/image/mocks/mapbox_* \ + --plotly $root/build/plotly.js \ + --mapbox-access-token "pk.eyJ1IjoiZXRwaW5hcmQiLCJhIjoiY2luMHIzdHE0MGFxNXVubTRxczZ2YmUxaCJ9.hwWZful0U2CQxit4ItNsiQ" \ + --output-dir $root/test/image/baselines/ \ + --verbose exit $EXIT_STATE diff --git a/test/image/baselines/mapbox_0.png b/test/image/baselines/mapbox_0.png index c5378b6cf85..68b8dee4b15 100644 Binary files a/test/image/baselines/mapbox_0.png and b/test/image/baselines/mapbox_0.png differ diff --git a/test/image/baselines/mapbox_angles.png b/test/image/baselines/mapbox_angles.png index 54eae19c19f..0fabd18879c 100644 Binary files a/test/image/baselines/mapbox_angles.png and b/test/image/baselines/mapbox_angles.png differ diff --git a/test/image/baselines/mapbox_bubbles-text.png b/test/image/baselines/mapbox_bubbles-text.png index 01a663867f0..a36d9aba981 100644 Binary files a/test/image/baselines/mapbox_bubbles-text.png and b/test/image/baselines/mapbox_bubbles-text.png differ diff --git a/test/image/baselines/mapbox_bubbles.png b/test/image/baselines/mapbox_bubbles.png index ae38027605e..0fe4978231d 100644 Binary files a/test/image/baselines/mapbox_bubbles.png and b/test/image/baselines/mapbox_bubbles.png differ diff --git a/test/image/baselines/mapbox_connectgaps.png b/test/image/baselines/mapbox_connectgaps.png index af554d97a38..cb6e1eec4cc 100644 Binary files a/test/image/baselines/mapbox_connectgaps.png and b/test/image/baselines/mapbox_connectgaps.png differ diff --git a/test/image/baselines/mapbox_custom-style.png b/test/image/baselines/mapbox_custom-style.png index 23d2ed05b92..dca5187424e 100644 Binary files a/test/image/baselines/mapbox_custom-style.png and b/test/image/baselines/mapbox_custom-style.png differ diff --git a/test/image/baselines/mapbox_fill.png b/test/image/baselines/mapbox_fill.png index 98fc78f86bd..0291fcc60e9 100644 Binary files a/test/image/baselines/mapbox_fill.png and b/test/image/baselines/mapbox_fill.png differ diff --git a/test/image/baselines/mapbox_layers.png b/test/image/baselines/mapbox_layers.png index 95da9fd0db4..edfa60da6eb 100644 Binary files a/test/image/baselines/mapbox_layers.png and b/test/image/baselines/mapbox_layers.png differ diff --git a/test/image/baselines/mapbox_symbol-text.png b/test/image/baselines/mapbox_symbol-text.png index 1ec7cd40459..d7f3ddf8233 100644 Binary files a/test/image/baselines/mapbox_symbol-text.png and b/test/image/baselines/mapbox_symbol-text.png differ diff --git a/test/image/mocks/mapbox_bubbles.json b/test/image/mocks/mapbox_bubbles.json index c35b8eb247f..904de36145d 100644 --- a/test/image/mocks/mapbox_bubbles.json +++ b/test/image/mocks/mapbox_bubbles.json @@ -46,6 +46,29 @@ "opacity": 0.5 } } + }, + { + "type": "scattermapbox", + "selectedpoints": [0, 2], + "mode": "markers", + "lon": [-10, -20, -30], + "lat": [-10, -20, -30], + "marker": {"size": 20}, + "selected": { + "marker": { + "size": 40, + "color": "green" + } + }, + "unselected": { + "marker": { + "size": 10, + "color": "red" + } + }, + "hoverlabel": { + "bgcolor": "grey" + } } ], "layout": { @@ -56,6 +79,7 @@ "showlegend": false, "height": 450, "width": 600, - "margin": {"l": 10} + "margin": {"l": 10}, + "dragmode": "select" } } diff --git a/test/jasmine/tests/mapbox_test.js b/test/jasmine/tests/mapbox_test.js index 3ca613b6b36..60430c94915 100644 --- a/test/jasmine/tests/mapbox_test.js +++ b/test/jasmine/tests/mapbox_test.js @@ -265,7 +265,7 @@ describe('mapbox credentials', function() { var cnt = 0; var msg = [ 'An API access token is required to use Mapbox GL.', - 'See https://www.mapbox.com/developers/api/#access-tokens' + 'See https://www.mapbox.com/api-documentation/#access-tokens' ].join(' '); Plotly.plot(gd, [{ @@ -405,10 +405,12 @@ describe('@noCI, mapbox plots', function() { function assertMarkerColor(expectations) { return new Promise(function(resolve) { setTimeout(function() { - var colors = getStyle(gd, 'circle', 'circle-color'); + var objs = getStyle(gd, 'circle', 'circle-color'); expectations.forEach(function(expected, i) { - expect(colors[i]).toBeCloseToArray(expected); + var obj = objs[i]; + var rgba = [obj.r, obj.g, obj.b, obj.a]; + expect(rgba).toBeCloseToArray(expected); }); resolve(); @@ -459,10 +461,9 @@ describe('@noCI, mapbox plots', function() { relayoutCnt++; }); - function assertLayout(style, center, zoom, dims) { + function assertLayout(center, zoom, dims) { var mapInfo = getMapInfo(gd); - expect(mapInfo.style.name).toEqual(style); expect([mapInfo.center.lng, mapInfo.center.lat]) .toBeCloseToArray(center); expect(mapInfo.zoom).toBeCloseTo(zoom); @@ -473,13 +474,13 @@ describe('@noCI, mapbox plots', function() { }); } - assertLayout('Mapbox Dark', [-4.710, 19.475], 1.234, [80, 100, 908, 270]); + assertLayout([-4.710, 19.475], 1.234, [80, 100, 908, 270]); Plotly.relayout(gd, 'mapbox.center', { lon: 0, lat: 0 }).then(function() { expect(restyleCnt).toEqual(0); expect(relayoutCnt).toEqual(1); - assertLayout('Mapbox Dark', [0, 0], 1.234, [80, 100, 908, 270]); + assertLayout([0, 0], 1.234, [80, 100, 908, 270]); return Plotly.relayout(gd, 'mapbox.zoom', '6'); }) @@ -487,31 +488,43 @@ describe('@noCI, mapbox plots', function() { expect(restyleCnt).toEqual(0); expect(relayoutCnt).toEqual(2); - assertLayout('Mapbox Dark', [0, 0], 6, [80, 100, 908, 270]); + assertLayout([0, 0], 6, [80, 100, 908, 270]); - return Plotly.relayout(gd, 'mapbox.style', 'light'); + return Plotly.relayout(gd, 'mapbox.domain.x', [0, 0.5]); }) .then(function() { expect(restyleCnt).toEqual(0); expect(relayoutCnt).toEqual(3); - assertLayout('Mapbox Light', [0, 0], 6, [80, 100, 908, 270]); + assertLayout([0, 0], 6, [80, 100, 454, 270]); - return Plotly.relayout(gd, 'mapbox.domain.x', [0, 0.5]); + return Plotly.relayout(gd, 'mapbox.domain.y[0]', 0.5); }) .then(function() { expect(restyleCnt).toEqual(0); expect(relayoutCnt).toEqual(4); - assertLayout('Mapbox Light', [0, 0], 6, [80, 100, 454, 270]); + assertLayout([0, 0], 6, [80, 100, 454, 135]); + }) + .catch(failTest) + .then(done); + }, LONG_TIMEOUT_INTERVAL); - return Plotly.relayout(gd, 'mapbox.domain.y[0]', 0.5); + it('should be able to relayout the map style', function(done) { + function assertLayout(style) { + var mapInfo = getMapInfo(gd); + expect(mapInfo.style.name).toEqual(style); + } + + assertLayout('Mapbox Dark'); + + Plotly.relayout(gd, 'mapbox.style', 'light').then(function() { + assertLayout('Mapbox Light'); + + return Plotly.relayout(gd, 'mapbox.style', 'dark'); }) .then(function() { - expect(restyleCnt).toEqual(0); - expect(relayoutCnt).toEqual(5); - - assertLayout('Mapbox Light', [0, 0], 6, [80, 100, 454, 135]); + assertLayout('Mapbox Dark'); }) .catch(failTest) .then(done); @@ -567,7 +580,12 @@ describe('@noCI, mapbox plots', function() { return new Promise(function(resolve) { setTimeout(function() { Object.keys(expectations).forEach(function(k) { - expect(((layer || {}).paint || {})[k]).toEqual(expectations[k]); + try { + var obj = layer.paint._values[k].value.value; + expect(String(obj)).toBe(String(expectations[k]), k); + } catch(e) { + fail('could not find paint values in layer'); + } }); resolve(); }, TRANSITION_DELAY); @@ -600,8 +618,8 @@ describe('@noCI, mapbox plots', function() { expect(countVisibleLayers(gd)).toEqual(2); return assertLayerStyle(gd, { - 'fill-color': [1, 0, 0, 1], - 'fill-outline-color': [0, 0, 1, 1], + 'fill-color': 'rgba(255,0,0,1)', + 'fill-outline-color': 'rgba(0,0,255,1)', 'fill-opacity': 0.3 }, 0); }) @@ -617,7 +635,7 @@ describe('@noCI, mapbox plots', function() { return assertLayerStyle(gd, { 'line-width': 3, - 'line-color': [0, 0, 1, 1], + 'line-color': 'rgba(0,0,255,1)', 'line-opacity': 0.6 }, 1); }) @@ -876,7 +894,7 @@ describe('@noCI, mapbox plots', function() { var subplot = gd._fullLayout.mapbox._subplot, map = subplot.map; - var sources = map.style.sources, + var sources = map.style.sourceCaches, layers = map.style._layers, uid = subplot.uid; @@ -925,7 +943,7 @@ describe('@noCI, mapbox plots', function() { var info = mapInfo.layers[l]; if(l.indexOf(mode) === -1) return; - if(info.layout.visibility === 'visible') cntPerMode++; + if(info.visibility === 'visible') cntPerMode++; }); cnts.push(cntPerMode); @@ -950,7 +968,7 @@ describe('@noCI, mapbox plots', function() { if(l.indexOf(mode) === -1) return; - values.push(info.paint[prop]); + values.push(info.paint._values[prop].value.value); }); return values; @@ -1012,13 +1030,12 @@ describe('@noCI, mapbox plots', function() { return promise; } - }); describe('@noCI, mapbox toImage', function() { // decreased from 1e5 - perhaps chrome got better at encoding these // because I get 99330 and the image still looks correct - var MINIMUM_LENGTH = 8e4; + var MINIMUM_LENGTH = 7e4; var gd; diff --git a/test/jasmine/tests/scattermapbox_test.js b/test/jasmine/tests/scattermapbox_test.js index bb4874239fd..dddb8c77a58 100644 --- a/test/jasmine/tests/scattermapbox_test.js +++ b/test/jasmine/tests/scattermapbox_test.js @@ -113,7 +113,11 @@ describe('scattermapbox defaults', function() { }); describe('scattermapbox convert', function() { - 'use strict'; + var base = { + type: 'scattermapbox', + lon: [10, '20', 30, 20, null, 20, 10], + lat: [20, 20, '10', null, 10, 10, 20] + }; function _convert(trace) { var gd = { data: [trace] }; @@ -126,11 +130,13 @@ describe('scattermapbox convert', function() { return convert(calcTrace); } - var base = { - type: 'scattermapbox', - lon: [10, '20', 30, 20, null, 20, 10], - lat: [20, 20, '10', null, 10, 10, 20] - }; + function assertVisibility(opts, expectations) { + var actual = ['fill', 'line', 'circle', 'symbol'].map(function(l) { + return opts[l].layout.visibility; + }); + + expect(actual).toEqual(expectations, 'layer visibility'); + } it('should generate correct output for markers + circle bubbles traces', function() { var opts = _convert(Lib.extendFlat({}, base, { @@ -145,16 +151,14 @@ describe('scattermapbox convert', function() { assertVisibility(opts, ['none', 'none', 'visible', 'none']); expect(opts.circle.paint['circle-color']).toEqual({ - property: 'circle-color', - stops: [ - [0, 'rgb(220, 220, 220)'], [1, '#444'], [2, 'rgb(178, 10, 28)'] - ] - }, 'circle-color stops'); + property: 'mcc', + type: 'identity' + }, 'circle-color paint'); expect(opts.circle.paint['circle-radius']).toEqual({ - property: 'circle-radius', - stops: [ [0, 5], [1, 10], [2, 0] ] - }, 'circle-radius stops'); + property: 'mrc', + type: 'identity' + }, 'circle-radius paint'); expect(opts.circle.paint['circle-opacity']).toBe(0.7, 'circle-opacity'); @@ -164,11 +168,11 @@ describe('scattermapbox convert', function() { // N.B repeated values have same geojson props expect(circleProps).toEqual([ - { 'circle-color': 0, 'circle-radius': 0 }, - { 'circle-color': 1, 'circle-radius': 1 }, - { 'circle-color': 2, 'circle-radius': 2 }, - { 'circle-color': 1, 'circle-radius': 2 }, - { 'circle-color': 1, 'circle-radius': 2 } + { 'mcc': 'rgb(220, 220, 220)', 'mrc': 5 }, + { 'mcc': '#444', 'mrc': 10 }, + { 'mcc': 'rgb(178, 10, 28)', 'mrc': 0 }, + { 'mcc': '#444', 'mrc': 0 }, + { 'mcc': '#444', 'mrc': 0 } ], 'geojson feature properties'); }); @@ -189,27 +193,26 @@ describe('scattermapbox convert', function() { expect(opts.circle.paint['circle-radius']).toBe(5, 'circle-radius'); expect(opts.circle.paint['circle-opacity']).toEqual({ - property: 'circle-opacity', - stops: [ [0, 0.5], [1, 0], [2, 0.25], [6, 0.4] ] - }, 'circle-opacity stops'); + property: 'mo', + type: 'identity' + }, 'circle-opacity paint'); var circleProps = opts.circle.geojson.features.map(function(f) { return f.properties; }); - expect(circleProps).toEqual([ - { 'circle-opacity': 0 }, - { 'circle-opacity': 1 }, - { 'circle-opacity': 2 }, + { 'mo': 0.5 }, + { 'mo': 0 }, + { 'mo': 0.25 }, // lat === null // lon === null - { 'circle-opacity': 1 }, - { 'circle-opacity': 6 }, + { 'mo': 0 }, + { 'mo': 0.4 }, ], 'geojson feature properties'); }); - it('should fill circle-opacity correctly during selections', function() { + it('should fill circle props correctly during selections', function() { var _base = { type: 'scattermapbox', mode: 'markers', @@ -219,50 +222,179 @@ describe('scattermapbox convert', function() { }; var specs = [{ + msg: 'base case', patch: { selectedpoints: [1, 2] }, - expected: {stops: [[0, 0.2], [1, 1]], props: [0, 1, 1]} + expected: { + opacity: [0.2, 1, 1] + } }, { + msg: 'with set trace opacity', patch: { opacity: 0.5, selectedpoints: [1, 2] }, - expected: {stops: [[0, 0.1], [1, 0.5]], props: [0, 1, 1]} + expected: { + opacity: [0.1, 0.5, 0.5] + } }, { + msg: 'with set scalar marker.opacity', patch: { marker: {opacity: 0.6}, selectedpoints: [1, 2] }, - expected: {stops: [[0, 0.12], [1, 0.6]], props: [0, 1, 1]} + expected: { + opacity: [0.12, 0.6, 0.6] + } }, { + msg: 'width set array marker.opacity', patch: { marker: { opacity: [0.5, 1, 0.6], }, selectedpoints: [0, 2] }, - expected: {stops: [[0, 0.5], [1, 0.2], [2, 0.6]], props: [0, 1, 2]} + expected: { + opacity: [0.5, 0.2, 0.6] + } }, { + msg: 'with set array marker.opacity including invalid items', patch: { marker: {opacity: [2, null, -0.6]}, selectedpoints: [0, 1, 2] }, - expected: {stops: [[0, 1], [1, 0]], props: [0, 1, 1]} + expected: { + opacity: [1, 0, 0] + } + }, { + msg: 'with set selected & unselected styles', + patch: { + selected: { + marker: { + opacity: 1, + color: 'green', + size: 20 + } + }, + unselected: { + marker: { + opacity: 0, + color: 'red', + size: 5 + } + }, + selectedpoints: [0, 2] + }, + expected: { + opacity: [1, 0, 1], + color: ['green', 'red', 'green'], + size: [10, 2.5, 10] + } + }, { + msg: 'with set selected styles only', + patch: { + selected: { + marker: { + opacity: 1, + color: 'green', + size: 20 + } + }, + selectedpoints: [0, 2] + }, + expected: { + opacity: [1, 0.2, 1], + color: ['green', '#1f77b4', 'green'], + size: [10, 3, 10] + } + }, { + msg: 'with set selected styles only + array items', + patch: { + marker: { + opacity: [0.5, 0.6, 0.7], + color: ['blue', 'yellow', 'cyan'], + size: [50, 60, 70] + }, + selected: { + marker: { + opacity: 1, + color: 'green', + size: 20 + } + }, + selectedpoints: [0, 2] + }, + expected: { + opacity: [1, 0.12, 1], + color: ['green', 'yellow', 'green'], + size: [10, 30, 10] + } + }, { + msg: 'with set unselected styles only', + patch: { + unselected: { + marker: { + opacity: 0, + color: 'red', + size: 5 + } + }, + selectedpoints: [0, 2] + }, + expected: { + opacity: [1, 0, 1], + color: ['#1f77b4', 'red', '#1f77b4'], + size: [3, 2.5, 3] + + } + }, { + msg: 'with set unselected styles only + array items', + patch: { + marker: { + opacity: [0.5, 0.6, 0.7], + color: ['blue', 'yellow', 'cyan'], + size: [50, 60, 70] + }, + unselected: { + marker: { + opacity: 0, + color: 'red', + size: 5 + } + }, + selectedpoints: [0, 2] + }, + expected: { + opacity: [0.5, 0, 0.7], + color: ['blue', 'red', 'cyan'], + size: [25, 2.5, 35] + } }]; specs.forEach(function(s, i) { - var msg0 = '- case ' + i + ' '; + var msg0 = s.msg + ' - case ' + i + '- '; var opts = _convert(Lib.extendDeep({}, _base, s.patch)); + var features = opts.circle.geojson.features; + + function _assert(kProp, kExp) { + var actual = features.map(function(f) { return f.properties[kProp]; }); + var expected = s.expected[kExp]; + var msg = msg0 + ' marker.' + kExp; + + if(Array.isArray(expected)) { + expect(actual).toEqual(expected, msg); + } else { + actual.forEach(function(a) { + expect(a).toBe(undefined, msg); + }); + } + } - expect(opts.circle.paint['circle-opacity'].stops) - .toEqual(s.expected.stops, msg0 + 'stops'); - - var props = opts.circle.geojson.features.map(function(f) { - return f.properties['circle-opacity']; - }); - - expect(props).toEqual(s.expected.props, msg0 + 'props'); + _assert('mo', 'opacity'); + _assert('mcc', 'color'); + // N.B. sizes in props should be half of the input values + _assert('mrc', 'size'); }); }); @@ -388,14 +520,16 @@ describe('scattermapbox convert', function() { marker: { size: ['5', '49', '5', ''] } })); - expect(opts.circle.paint['circle-radius'].stops) - .toBeCloseTo2DArray([[0, 2.5], [1, 24.5]], 'no replicate stops'); + expect(opts.circle.paint['circle-radius']).toEqual({ + property: 'mrc', + type: 'identity' + }, 'circle-radius paint'); var radii = opts.circle.geojson.features.map(function(f) { - return f.properties['circle-radius']; + return f.properties.mrc; }); - expect(radii).toBeCloseToArray([0, 1, 0], 'link features to correct stops'); + expect(radii).toBeCloseToArray([2.5, 24.5, 2.5], 'circle radii'); }); it('should generate correct output for traces with only blank points', function() { @@ -413,21 +547,10 @@ describe('scattermapbox convert', function() { expect(opts.line.geojson.coordinates).toEqual([], 'line coords'); expect(opts.fill.geojson.coordinates).toEqual([], 'fill coords'); }); - - function assertVisibility(opts, expectations) { - var actual = ['fill', 'line', 'circle', 'symbol'].map(function(l) { - return opts[l].layout.visibility; - }); - - expect(actual).toEqual(expectations, 'layer visibility'); - } }); describe('@noCI scattermapbox hover', function() { - 'use strict'; - var hoverPoints = ScatterMapbox.hoverPoints; - var gd; beforeAll(function(done) { @@ -439,9 +562,9 @@ describe('@noCI scattermapbox hover', function() { var data = [{ type: 'scattermapbox', - lon: [10, 20, 30], - lat: [10, 20, 30], - text: ['A', 'B', 'C'] + lon: [10, 20, 30, 300], + lat: [10, 20, 30, 10], + text: ['A', 'B', 'C', 'D'] }]; Plotly.plot(gd, data, { autosize: true }).then(done); @@ -453,16 +576,17 @@ describe('@noCI scattermapbox hover', function() { }); function getPointData(gd) { - var cd = gd.calcdata, - mapbox = gd._fullLayout.mapbox._subplot; + var cd = gd.calcdata; + var subplot = gd._fullLayout.mapbox._subplot; return { index: false, distance: 20, cd: cd[0], trace: cd[0][0].trace, - xa: mapbox.xaxis, - ya: mapbox.yaxis + subplot: subplot, + xa: subplot.xaxis, + ya: subplot.yaxis }; } @@ -480,6 +604,19 @@ describe('@noCI scattermapbox hover', function() { expect(out.color).toEqual('#1f77b4'); }); + it('should generate hover label info (lon > 180 case)', function() { + var xval = 301; + var yval = 11; + var out = hoverPoints(getPointData(gd), xval, yval)[0]; + + expect(out.index).toEqual(3); + expect([out.x0, out.x1, out.y0, out.y1]).toBeCloseToArray([ + 1122.33, 1124.33, 105.41, 107.41 + ]); + expect(out.extraText).toEqual('(300°, 10°)
D'); + expect(out.color).toEqual('#1f77b4'); + }); + it('should skip over blank and non-string text items', function(done) { var xval = 11, yval = 11, @@ -632,49 +769,24 @@ describe('@noCI scattermapbox hover', function() { describe('@noCI Test plotly events on a scattermapbox plot:', function() { var mock = require('@mocks/mapbox_0.json'); + var pointPos = [440, 290]; + var nearPos = [460, 290]; + var blankPos = [10, 10]; + var mockCopy; + var gd; - var mockCopy, gd; - - var blankPos = [10, 10], - pointPos, - nearPos; - - function getPointData(gd) { - var cd = gd.calcdata, - mapbox = gd._fullLayout.mapbox._subplot; - - return { - index: false, - distance: 20, - cd: cd[0], - trace: cd[0][0].trace, - xa: mapbox.xaxis, - ya: mapbox.yaxis - }; - } - - beforeAll(function(done) { + beforeAll(function() { Plotly.setPlotConfig({ mapboxAccessToken: require('@build/credentials.json').MAPBOX_ACCESS_TOKEN }); - - gd = createGraphDiv(); - mockCopy = Lib.extendDeep({}, mock); - - Plotly.plot(gd, mockCopy.data, mockCopy.layout).then(function() { - var bb = gd._fullLayout.mapbox._subplot.div.getBoundingClientRect(), - xval = 10, - yval = 10, - point = ScatterMapbox.hoverPoints(getPointData(gd), xval, yval)[0]; - pointPos = [Math.floor(bb.left + (point.x0 + point.x1) / 2), - Math.floor(bb.top + (point.y0 + point.y1) / 2)]; - nearPos = [pointPos[0] - 30, pointPos[1] - 30]; - }).then(destroyGraphDiv).then(done); }); - beforeEach(function() { + beforeEach(function(done) { gd = createGraphDiv(); mockCopy = Lib.extendDeep({}, mock); + mockCopy.layout.width = 800; + mockCopy.layout.height = 500; + Plotly.plot(gd, mockCopy).then(done); }); afterEach(destroyGraphDiv); @@ -682,9 +794,7 @@ describe('@noCI Test plotly events on a scattermapbox plot:', function() { describe('click events', function() { var futureData; - beforeEach(function(done) { - Plotly.plot(gd, mockCopy.data, mockCopy.layout).then(done); - + beforeEach(function() { futureData = undefined; gd.on('plotly_click', function(data) { futureData = data; @@ -720,16 +830,15 @@ describe('@noCI Test plotly events on a scattermapbox plot:', function() { describe('modified click events', function() { var clickOpts = { - altKey: true, - ctrlKey: true, - metaKey: true, - shiftKey: true - }, - futureData; + altKey: true, + ctrlKey: true, + metaKey: true, + shiftKey: true + }; - beforeEach(function(done) { - Plotly.plot(gd, mockCopy.data, mockCopy.layout).then(done); + var futureData; + beforeEach(function() { futureData = undefined; gd.on('plotly_click', function(data) { futureData = data; @@ -774,9 +883,7 @@ describe('@noCI Test plotly events on a scattermapbox plot:', function() { describe('hover events', function() { var futureData; - beforeEach(function(done) { - Plotly.plot(gd, mockCopy.data, mockCopy.layout).then(done); - + beforeEach(function() { gd.on('plotly_hover', function(data) { futureData = data; }); @@ -786,8 +893,8 @@ describe('@noCI Test plotly events on a scattermapbox plot:', function() { mouseEvent('mousemove', blankPos[0], blankPos[1]); mouseEvent('mousemove', pointPos[0], pointPos[1]); - var pt = futureData.points[0], - evt = futureData.event; + var pt = futureData.points[0]; + var evt = futureData.event; expect(Object.keys(pt)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat' @@ -808,9 +915,7 @@ describe('@noCI Test plotly events on a scattermapbox plot:', function() { describe('unhover events', function() { var futureData; - beforeEach(function(done) { - Plotly.plot(gd, mockCopy.data, mockCopy.layout).then(done); - + beforeEach(function() { gd.on('plotly_unhover', function(data) { futureData = data; }); @@ -818,8 +923,8 @@ describe('@noCI Test plotly events on a scattermapbox plot:', function() { it('should contain the correct fields', function(done) { move(pointPos[0], pointPos[1], nearPos[0], nearPos[1], HOVERMINTIME + 10).then(function() { - var pt = futureData.points[0], - evt = futureData.event; + var pt = futureData.points[0]; + var evt = futureData.event; expect(Object.keys(pt)).toEqual([ 'data', 'fullData', 'curveNumber', 'pointNumber', 'pointIndex', 'lon', 'lat' diff --git a/test/jasmine/tests/select_test.js b/test/jasmine/tests/select_test.js index 49efc4a33cd..7d2af86b3e0 100644 --- a/test/jasmine/tests/select_test.js +++ b/test/jasmine/tests/select_test.js @@ -530,6 +530,28 @@ describe('Test select box and lasso in general:', function() { .catch(fail) .then(done); }); + + it('scroll zoom should clear selection regions', function(done) { + var gd = createGraphDiv(); + var mockCopy = Lib.extendDeep({}, mock); + mockCopy.layout.dragmode = 'select'; + mockCopy.config = {scrollZoom: true}; + + Plotly.plot(gd, mockCopy).then(function() { + resetEvents(gd); + drag(selectPath); + return selectedPromise; + }) + .then(function() { + mouseEvent('mousemove', selectPath[0][0], selectPath[0][1]); + mouseEvent('scroll', selectPath[0][0], selectPath[0][1], {deltaX: 0, deltaY: -20}); + }) + .then(function() { + assertSelectionNodes(0, 0); + }) + .catch(fail) + .then(done); + }); }); describe('Test select box and lasso per trace:', function() {