diff --git a/package-lock.json b/package-lock.json index 98c01d8ee..fc6b85d0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,9 @@ "d3-brush": "^3.0.0", "d3-color": "^3.1.0", "d3-ease": "^3.0.1", + "d3-fetch": "^3.0.1", "d3-format": "^3.1.0", + "d3-geo": "^3.1.1", "d3-hierarchy": "^3.1.0", "d3-interpolate": "^3.0.1", "d3-sankey": "^0.12.3", @@ -34,12 +36,15 @@ "d3-shape": "^3.2.0", "d3-time-format": "^3.0.0", "d3-transition": "^3.0.1", + "d3-zoom": "^3.0.0", "emoji-flags": "^1.2.0", + "lodash": "^4.17.21", "moment-timezone": "^0.5.40", "ng-in-viewport": "^6.1.5", "ngx-moment": "^5.0.0", "resize-observer-polyfill": "^1.5.1", "rxjs": "^6.5.3 || ^7.4.0", + "topojson-client": "^3.1.0", "tslib": "^2.3.0", "zone.js": "~0.11.4" }, @@ -58,15 +63,20 @@ "@swimlane/prettier-config-swimlane": "^3.0.2", "@types/d3-array": "^2.12.1", "@types/d3-ease": "^2.0.0", + "@types/d3-fetch": "^3.0.7", + "@types/d3-geo": "^3.1.0", "@types/d3-interpolate": "^2.0.0", "@types/d3-scale": "^3.3.0", "@types/d3-selection": "^2.0.0", "@types/d3-shape": "^2.1.0", "@types/d3-transition": "^2.0.0", + "@types/d3-zoom": "^3.0.8", "@types/jasmine": "^3.6.0", "@types/jasminewd2": "~2.0.3", "@types/json-schema": "^7.0.4", + "@types/lodash": "^4.17.1", "@types/node": "^12.11.1", + "@types/topojson-client": "^3.1.4", "@typescript-eslint/eslint-plugin": "5.11.0", "@typescript-eslint/parser": "5.11.0", "angular-cli-ghpages": "^0.6.2", @@ -3851,11 +3861,35 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmmirror.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "dev": true + }, "node_modules/@types/d3-ease": { "version": "2.0.0", "dev": true, "license": "MIT" }, + "node_modules/@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmmirror.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "dev": true, + "dependencies": { + "@types/d3-dsv": "*" + } + }, + "node_modules/@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "dev": true, + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@types/d3-interpolate": { "version": "2.0.0", "dev": true, @@ -3903,6 +3937,16 @@ "@types/d3-selection": "*" } }, + "node_modules/@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmmirror.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "dev": true, + "dependencies": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "node_modules/@types/eslint": { "version": "8.2.1", "dev": true, @@ -3926,6 +3970,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/geojson": { + "version": "7946.0.14", + "resolved": "https://registry.npmmirror.com/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==", + "dev": true + }, "node_modules/@types/http-proxy": { "version": "1.17.7", "dev": true, @@ -3952,6 +4002,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/lodash": { + "version": "4.17.1", + "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.1.tgz", + "integrity": "sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q==", + "dev": true + }, "node_modules/@types/node": { "version": "12.19.9", "dev": true, @@ -3980,6 +4036,25 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/topojson-client": { + "version": "3.1.4", + "resolved": "https://registry.npmmirror.com/@types/topojson-client/-/topojson-client-3.1.4.tgz", + "integrity": "sha512-Ntf3ZSetMYy7z3PrVCvcqmdRoVhgKA9UKN0ZuuZf8Ts2kcyL4qK34IXBs6qO5fem62EK4k03PtkJPVoroVu4/w==", + "dev": true, + "dependencies": { + "@types/geojson": "*", + "@types/topojson-specification": "*" + } + }, + "node_modules/@types/topojson-specification": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/@types/topojson-specification/-/topojson-specification-1.0.5.tgz", + "integrity": "sha512-C7KvcQh+C2nr6Y2Ub4YfgvWvWCgP2nOQMtfhlnwsRL4pYmmwzBS7HclGiS87eQfDOU/DLQpX6GEscviaz4yLIQ==", + "dev": true, + "dependencies": { + "@types/geojson": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "5.11.0", "dev": true, @@ -5836,7 +5911,6 @@ }, "node_modules/commander": { "version": "2.20.3", - "dev": true, "license": "MIT" }, "node_modules/commondir": { @@ -6671,6 +6745,49 @@ "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz", "integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==" }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-dsv/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/d3-ease": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", @@ -6679,6 +6796,17 @@ "node": ">=12" } }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-format": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", @@ -6687,6 +6815,17 @@ "node": ">=12" } }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-hierarchy": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", @@ -6831,6 +6970,21 @@ "d3-selection": "2 - 3" } }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/damerau-levenshtein": { "version": "1.0.6", "dev": true, @@ -10849,8 +11003,8 @@ }, "node_modules/lodash": { "version": "4.17.21", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash._basecallback": { "version": "3.3.1", @@ -15270,6 +15424,11 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "node_modules/rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", @@ -15308,7 +15467,6 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "dev": true, "license": "MIT" }, "node_modules/sass": { @@ -16543,6 +16701,19 @@ "node": ">=0.6" } }, + "node_modules/topojson-client": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/topojson-client/-/topojson-client-3.1.0.tgz", + "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", + "dependencies": { + "commander": "2" + }, + "bin": { + "topo2geo": "bin/topo2geo", + "topomerge": "bin/topomerge", + "topoquantize": "bin/topoquantize" + } + }, "node_modules/tough-cookie": { "version": "2.5.0", "dev": true, @@ -19881,10 +20052,34 @@ "version": "2.0.1", "dev": true }, + "@types/d3-dsv": { + "version": "3.0.7", + "resolved": "https://registry.npmmirror.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", + "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", + "dev": true + }, "@types/d3-ease": { "version": "2.0.0", "dev": true }, + "@types/d3-fetch": { + "version": "3.0.7", + "resolved": "https://registry.npmmirror.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", + "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", + "dev": true, + "requires": { + "@types/d3-dsv": "*" + } + }, + "@types/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/@types/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", + "dev": true, + "requires": { + "@types/geojson": "*" + } + }, "@types/d3-interpolate": { "version": "2.0.0", "dev": true, @@ -19925,6 +20120,16 @@ "@types/d3-selection": "*" } }, + "@types/d3-zoom": { + "version": "3.0.8", + "resolved": "https://registry.npmmirror.com/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", + "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", + "dev": true, + "requires": { + "@types/d3-interpolate": "*", + "@types/d3-selection": "*" + } + }, "@types/eslint": { "version": "8.2.1", "dev": true, @@ -19945,6 +20150,12 @@ "version": "0.0.50", "dev": true }, + "@types/geojson": { + "version": "7946.0.14", + "resolved": "https://registry.npmmirror.com/@types/geojson/-/geojson-7946.0.14.tgz", + "integrity": "sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==", + "dev": true + }, "@types/http-proxy": { "version": "1.17.7", "dev": true, @@ -19967,6 +20178,12 @@ "version": "7.0.6", "dev": true }, + "@types/lodash": { + "version": "4.17.1", + "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.1.tgz", + "integrity": "sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q==", + "dev": true + }, "@types/node": { "version": "12.19.9", "dev": true @@ -19990,6 +20207,25 @@ "version": "3.0.17", "dev": true }, + "@types/topojson-client": { + "version": "3.1.4", + "resolved": "https://registry.npmmirror.com/@types/topojson-client/-/topojson-client-3.1.4.tgz", + "integrity": "sha512-Ntf3ZSetMYy7z3PrVCvcqmdRoVhgKA9UKN0ZuuZf8Ts2kcyL4qK34IXBs6qO5fem62EK4k03PtkJPVoroVu4/w==", + "dev": true, + "requires": { + "@types/geojson": "*", + "@types/topojson-specification": "*" + } + }, + "@types/topojson-specification": { + "version": "1.0.5", + "resolved": "https://registry.npmmirror.com/@types/topojson-specification/-/topojson-specification-1.0.5.tgz", + "integrity": "sha512-C7KvcQh+C2nr6Y2Ub4YfgvWvWCgP2nOQMtfhlnwsRL4pYmmwzBS7HclGiS87eQfDOU/DLQpX6GEscviaz4yLIQ==", + "dev": true, + "requires": { + "@types/geojson": "*" + } + }, "@typescript-eslint/eslint-plugin": { "version": "5.11.0", "dev": true, @@ -21180,8 +21416,7 @@ } }, "commander": { - "version": "2.20.3", - "dev": true + "version": "2.20.3" }, "commondir": { "version": "1.0.1", @@ -21746,16 +21981,57 @@ } } }, + "d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "requires": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + } + } + }, "d3-ease": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==" }, + "d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "requires": { + "d3-dsv": "1 - 3" + } + }, "d3-format": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==" }, + "d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "requires": { + "d3-array": "2.5.0 - 3" + } + }, "d3-hierarchy": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", @@ -21872,6 +22148,18 @@ "d3-timer": "1 - 3" } }, + "d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "requires": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + } + }, "damerau-levenshtein": { "version": "1.0.6", "dev": true @@ -24468,7 +24756,8 @@ }, "lodash": { "version": "4.17.21", - "dev": true + "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash._basecallback": { "version": "3.3.1", @@ -27346,6 +27635,11 @@ "queue-microtask": "^1.2.2" } }, + "rw": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "rxjs": { "version": "6.6.7", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", @@ -27375,8 +27669,7 @@ } }, "safer-buffer": { - "version": "2.1.2", - "dev": true + "version": "2.1.2" }, "sass": { "version": "1.44.0", @@ -28200,6 +28493,14 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, + "topojson-client": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/topojson-client/-/topojson-client-3.1.0.tgz", + "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", + "requires": { + "commander": "2" + } + }, "tough-cookie": { "version": "2.5.0", "dev": true, diff --git a/package.json b/package.json index 0e195056e..d8f831c79 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,9 @@ "d3-brush": "^3.0.0", "d3-color": "^3.1.0", "d3-ease": "^3.0.1", + "d3-fetch": "^3.0.1", "d3-format": "^3.1.0", + "d3-geo": "^3.1.1", "d3-hierarchy": "^3.1.0", "d3-interpolate": "^3.0.1", "d3-sankey": "^0.12.3", @@ -56,12 +58,15 @@ "d3-shape": "^3.2.0", "d3-time-format": "^3.0.0", "d3-transition": "^3.0.1", + "d3-zoom": "^3.0.0", "emoji-flags": "^1.2.0", + "lodash": "^4.17.21", "moment-timezone": "^0.5.40", "ng-in-viewport": "^6.1.5", "ngx-moment": "^5.0.0", "resize-observer-polyfill": "^1.5.1", "rxjs": "^6.5.3 || ^7.4.0", + "topojson-client": "^3.1.0", "tslib": "^2.3.0", "zone.js": "~0.11.4" }, @@ -80,15 +85,20 @@ "@swimlane/prettier-config-swimlane": "^3.0.2", "@types/d3-array": "^2.12.1", "@types/d3-ease": "^2.0.0", + "@types/d3-fetch": "^3.0.7", + "@types/d3-geo": "^3.1.0", "@types/d3-interpolate": "^2.0.0", "@types/d3-scale": "^3.3.0", "@types/d3-selection": "^2.0.0", "@types/d3-shape": "^2.1.0", "@types/d3-transition": "^2.0.0", + "@types/d3-zoom": "^3.0.8", "@types/jasmine": "^3.6.0", "@types/jasminewd2": "~2.0.3", "@types/json-schema": "^7.0.4", + "@types/lodash": "^4.17.1", "@types/node": "^12.11.1", + "@types/topojson-client": "^3.1.4", "@typescript-eslint/eslint-plugin": "5.11.0", "@typescript-eslint/parser": "5.11.0", "angular-cli-ghpages": "^0.6.2", diff --git a/projects/swimlane/ngx-charts/package.json b/projects/swimlane/ngx-charts/package.json index 449fa2fca..6d199956a 100644 --- a/projects/swimlane/ngx-charts/package.json +++ b/projects/swimlane/ngx-charts/package.json @@ -32,8 +32,8 @@ "peerDependencies": { "@angular/animations": ">=12.0.0", "@angular/cdk": ">=12.0.0", - "@angular/core": ">=12.0.0", "@angular/common": ">=12.0.0", + "@angular/core": ">=12.0.0", "@angular/forms": ">=12.0.0", "@angular/platform-browser": ">=12.0.0", "@angular/platform-browser-dynamic": ">=12.0.0", @@ -45,6 +45,7 @@ "d3-color": "^3.1.0", "d3-ease": "^3.0.1", "d3-format": "^3.1.0", + "d3-geo": "^3.1.1", "d3-hierarchy": "^3.1.0", "d3-interpolate": "^3.0.1", "d3-sankey": "^0.12.3", @@ -53,6 +54,7 @@ "d3-shape": "^3.2.0", "d3-time-format": "^3.0.0", "d3-transition": "^3.0.1", + "lodash": "^4.17.21", "rfdc": "^1.3.0", "tslib": "^2.0.0" }, diff --git a/projects/swimlane/ngx-charts/src/lib/common/base-chart.component.ts b/projects/swimlane/ngx-charts/src/lib/common/base-chart.component.ts index 1fb86981b..afa62c710 100644 --- a/projects/swimlane/ngx-charts/src/lib/common/base-chart.component.ts +++ b/projects/swimlane/ngx-charts/src/lib/common/base-chart.component.ts @@ -1,20 +1,21 @@ import { isPlatformBrowser, isPlatformServer } from '@angular/common'; import { - ElementRef, - NgZone, + AfterViewInit, ChangeDetectorRef, Component, - Input, - Output, + ElementRef, EventEmitter, - AfterViewInit, - OnDestroy, + Inject, + Input, + NgZone, OnChanges, - SimpleChanges, + OnDestroy, + OnInit, + Output, PLATFORM_ID, - Inject, - OnInit + SimpleChanges } from '@angular/core'; +import { cloneDeep } from 'lodash'; import { fromEvent as observableFromEvent } from 'rxjs'; import { debounceTime } from 'rxjs/operators'; @@ -80,7 +81,7 @@ export class BaseChartComponent implements OnChanges, AfterViewInit, OnDestroy, if (this.results) { this.results = this.cloneData(this.results); } else { - this.results = []; + (this.results) = []; } if (this.view) { @@ -181,42 +182,6 @@ export class BaseChartComponent implements OnChanges, AfterViewInit, OnDestroy, * @memberOf BaseChart */ private cloneData(data): any { - const results = []; - - for (const item of data) { - const copy = {}; - - if (item['name'] !== undefined) { - copy['name'] = item['name']; - } - - if (item['value'] !== undefined) { - copy['value'] = item['value']; - } - - if (item['series'] !== undefined) { - copy['series'] = []; - for (const seriesItem of item['series']) { - const seriesItemCopy = Object.assign({}, seriesItem); - copy['series'].push(seriesItemCopy); - } - } - - if (item['extra'] !== undefined) { - copy['extra'] = JSON.parse(JSON.stringify(item['extra'])); - } - - if (item['source'] !== undefined) { - copy['source'] = item['source']; - } - - if (item['target'] !== undefined) { - copy['target'] = item['target']; - } - - results.push(copy); - } - - return results; + return cloneDeep(data); } } diff --git a/projects/swimlane/ngx-charts/src/lib/common/types/view-dimension.interface.ts b/projects/swimlane/ngx-charts/src/lib/common/types/view-dimension.interface.ts index 5085a054f..5551f4cc1 100644 --- a/projects/swimlane/ngx-charts/src/lib/common/types/view-dimension.interface.ts +++ b/projects/swimlane/ngx-charts/src/lib/common/types/view-dimension.interface.ts @@ -4,3 +4,7 @@ export interface ViewDimensions { xOffset?: number; yOffset?: number; } + +export interface Results { + [key: string]: any; +} \ No newline at end of file diff --git a/projects/swimlane/ngx-charts/src/lib/geo-map/geo-map.component.scss b/projects/swimlane/ngx-charts/src/lib/geo-map/geo-map.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/projects/swimlane/ngx-charts/src/lib/geo-map/geo-map.component.ts b/projects/swimlane/ngx-charts/src/lib/geo-map/geo-map.component.ts new file mode 100644 index 000000000..2d0bc15e0 --- /dev/null +++ b/projects/swimlane/ngx-charts/src/lib/geo-map/geo-map.component.ts @@ -0,0 +1,141 @@ +import { + ChangeDetectionStrategy, + Component, + ContentChild, + ElementRef, + EventEmitter, + Input, + OnInit, + Output, + TemplateRef, + ViewEncapsulation +} from '@angular/core'; +import { BaseChartComponent } from '@swimlane/ngx-charts/common/base-chart.component'; +import { LegendOptions, LegendPosition } from '@swimlane/ngx-charts/common/types/legend.model'; +import { DataItem, GeoMapChartSeries } from '@swimlane/ngx-charts/models/chart-data.model'; +import { ColorHelper } from '@swimlane/ngx-charts/common/color.helper'; +import { ScaleType } from '@swimlane/ngx-charts/common/types/scale-type.enum'; +import { Results, ViewDimensions } from '@swimlane/ngx-charts/common/types/view-dimension.interface'; +import { geoEquirectangular, geoMercator, geoPath } from 'd3-geo'; +import { select } from 'd3-selection'; + +@Component({ + selector: 'ngx-charts-geo-map', + template: ` + `, + styleUrls: ['../common/base-chart.component.scss', './geo-map.component.scss'], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class GeoMapComponent extends BaseChartComponent implements OnInit { + @Input() results: T; + @Input() labels: boolean = false; + @Input() legend: boolean = false; + @Input() legendTitle: string = 'Legend'; + @Input() legendPosition: LegendPosition = LegendPosition.Right; + @Input() explodeSlices: boolean = false; + @Input() doughnut: boolean = false; + @Input() arcWidth: number = 0.25; + @Input() gradient: boolean; + @Input() activeEntries: any[] = []; + @Input() tooltipDisabled: boolean = false; + @Input() labelFormatting: any; + @Input() trimLabels: boolean = true; + @Input() maxLabelLength: number = 10; + @Input() tooltipText: any; + @Input() painter: (params: { + element: ElementRef; + selector: string; + results: T; + compInstance: GeoMapComponent; + }) => any; + @Output() dblclick = new EventEmitter(); + // optional margins + @Input() margins: number[]; + @Output() select = new EventEmitter(); + @Output() activate = new EventEmitter(); + @Output() deactivate = new EventEmitter(); + + @ContentChild('mapTpl') mapTpl: TemplateRef; + + data: DataItem[]; + colors: ColorHelper; + domain: string[]; + dims: ViewDimensions; + legendOptions: LegendOptions; + geoJSON: any; + projections: any; + + ngOnInit() { + super.ngOnInit(); + this.projections = geoEquirectangular() + .scale(150) // 地图缩放比例 + .translate([this.width / 2, this.height / 2]); // 平移至中心 + } + + update() { + super.update(); + this.legendOptions = this.getLegendOptions(); + this.geoJSON = (this.results as GeoMapChartSeries).GeoJSON; + + if (!this.geoJSON) return; + + if (this.painter) { + this.painter({ + element: this.chartElement, + selector: '.ngx-charts', + results: this.results, + compInstance: this + }); + } else { + /** + * TODO: 感觉有问题,我怎么知道需要绘制多少轮廓线,可能州级别和国家轮廓线清晰度不一样 + */ + const projection = geoMercator() + .center([107, 31]) //地图中心位置,107是经度,31是纬度 + .scale(600) //设置缩放量 + .translate([this.width / 2, this.height / 2]); // 设置平移量 + + const path = geoPath(projection); + const svg = select(this.chartElement.nativeElement).select('.ngx-charts'); + const g = svg.append('g'); + const states = g + .selectAll('path') + .data(this.geoJSON['features']) // 绑定数据 + .enter() + .append('path') + .style('fill', 'white') + .style('stroke-width', '10px') + .attr('d', path); + } + } + + getDomain(): string[] { + return this.results.map(d => d.label); + } + + onClick(data: DataItem | string): void { + this.select.emit(data); + } + + setColors(): void { + this.colors = new ColorHelper(this.scheme, ScaleType.Ordinal, this.domain, this.customColors); + } + + getLegendOptions(): LegendOptions { + return { + scaleType: ScaleType.Ordinal, + domain: this.domain, + colors: this.colors, + title: this.legendTitle, + position: this.legendPosition + }; + } +} diff --git a/projects/swimlane/ngx-charts/src/lib/geo-map/geo-map.module.ts b/projects/swimlane/ngx-charts/src/lib/geo-map/geo-map.module.ts new file mode 100644 index 000000000..9707c39fc --- /dev/null +++ b/projects/swimlane/ngx-charts/src/lib/geo-map/geo-map.module.ts @@ -0,0 +1,11 @@ +import { NgModule } from '@angular/core'; +import { GeoMapComponent } from '@swimlane/ngx-charts/geo-map/geo-map.component'; +import { ChartCommonModule } from '@swimlane/ngx-charts/common/chart-common.module'; +import {PieChartModule} from "@swimlane/ngx-charts/pie-chart/pie-chart.module"; + +@NgModule({ + imports: [ChartCommonModule, PieChartModule], + declarations: [GeoMapComponent], + exports: [GeoMapComponent] +}) +export class GeoMapModule {} diff --git a/projects/swimlane/ngx-charts/src/lib/models/chart-data.model.ts b/projects/swimlane/ngx-charts/src/lib/models/chart-data.model.ts index 0b84fd626..39f96c4de 100644 --- a/projects/swimlane/ngx-charts/src/lib/models/chart-data.model.ts +++ b/projects/swimlane/ngx-charts/src/lib/models/chart-data.model.ts @@ -103,3 +103,12 @@ export interface IBoxModel { // TODO: Replace by IColorGradient Interface gradientStops?: Array<{ offset: number; color: string; opacity: number }>; } + +export interface GeoMapChartSeries { + /** + * GeoJSON or TopoJSON + */ + GeoJSON: any; + + [key: string]: any; +} diff --git a/projects/swimlane/ngx-charts/src/lib/ngx-charts.module.ts b/projects/swimlane/ngx-charts/src/lib/ngx-charts.module.ts index 32543706c..ae6ea2364 100644 --- a/projects/swimlane/ngx-charts/src/lib/ngx-charts.module.ts +++ b/projects/swimlane/ngx-charts/src/lib/ngx-charts.module.ts @@ -13,6 +13,7 @@ import { TreeMapModule } from './tree-map/tree-map.module'; import { GaugeModule } from './gauge/gauge.module'; import { ngxChartsPolyfills } from './polyfills'; import { SankeyModule } from './sankey/sankey.module'; +import { GeoMapModule } from '@swimlane/ngx-charts/geo-map/geo-map.module'; @NgModule({ exports: [ @@ -28,7 +29,8 @@ import { SankeyModule } from './sankey/sankey.module'; NumberCardModule, PieChartModule, TreeMapModule, - GaugeModule + GaugeModule, + GeoMapModule ] }) export class NgxChartsModule { diff --git a/src/app/app.component.html b/src/app/app.component.html index a68efd1e8..3b50d05a7 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1051,6 +1051,49 @@

{{ model.name }}: {{ model.value }}

(onFilter)="onFilter($event)" > + + + +
{{ barChart | json }}
{{ lineChartSeries | json }}
{{ timelineFilterBarData | json }}
+
{{ geoMapChartData | json }}