From ff2eddffb73ca156f8b04835b58303522b917c39 Mon Sep 17 00:00:00 2001 From: Brian Chevalier Date: Sat, 26 Dec 2020 03:28:01 -0700 Subject: [PATCH 1/2] Initial vega-lite & portal charts viewers (#31) --- package-lock.json | 752 +++++++++++++++++++++++++++- package.json | 3 + src/examples/data.cljc | 130 +++++ src/portal/ui/app.cljs | 6 + src/portal/ui/styled.cljs | 2 +- src/portal/ui/viewer/charts.cljs | 83 +++ src/portal/ui/viewer/vega_lite.cljs | 168 +++++++ 7 files changed, 1134 insertions(+), 10 deletions(-) create mode 100644 src/portal/ui/viewer/charts.cljs create mode 100644 src/portal/ui/viewer/vega_lite.cljs diff --git a/package-lock.json b/package-lock.json index 5edc8fc4..b3c1f318 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2,6 +2,16 @@ "requires": true, "lockfileVersion": 1, "dependencies": { + "@types/clone": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/clone/-/clone-2.1.0.tgz", + "integrity": "sha512-d/aS/lPOnUSruPhgNtT8jW39fHRVTLQy9sodysP1kkG8EdAtdZu1vt8NJaYA8w/6Z9j8izkAsx1A/yJhcYR1CA==" + }, + "@types/fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha512-mky/O83TXmGY39P1H9YbUpjV6l6voRYlufqfFCvel8l1phuy8HRjdWc1rrPuN53ITBJlbyMSV6z3niOySO5pgQ==" + }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -35,6 +45,24 @@ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "array-flat-polyfill": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-flat-polyfill/-/array-flat-polyfill-1.0.1.tgz", + "integrity": "sha512-hfJmKupmQN0lwi0xG6FQ5U8Rd97RnIERplymOv/qpq8AoNKPPAnxJadjFA23FNWm88wykh9HmpLJUUwUtNU/iw==" + }, "asn1.js": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", @@ -325,6 +353,34 @@ "safe-buffer": "^5.0.1" } }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "combine-source-map": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", @@ -345,6 +401,11 @@ } } }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -456,6 +517,134 @@ "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.14.2.tgz", "integrity": "sha512-YE2xlTKtM035/94llhgsp9qFQxGi47EkQJ1pZ+mLT/98GpIsbjkMGAb7Rmu9hNxVfYFOLf10hP+rPVqnoccLgw==" }, + "d3-array": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.9.1.tgz", + "integrity": "sha512-Ob7RdOtkqsjx1NWyQHMFLtCSk6/aKTxDdC4ZIolX+O+mDD2RzrsYgAyc0WGAlfYFVELLSilS7w8BtE3PKM8bHg==" + }, + "d3-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz", + "integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==" + }, + "d3-delaunay": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-5.3.0.tgz", + "integrity": "sha512-amALSrOllWVLaHTnDLHwMIiz0d1bBu9gZXd1FiLfXf8sHcX9jrcj81TVZOqD4UX7MgBZZ07c8GxzEgBpJqc74w==", + "requires": { + "delaunator": "4" + } + }, + "d3-dispatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz", + "integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA==" + }, + "d3-dsv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-2.0.0.tgz", + "integrity": "sha512-E+Pn8UJYx9mViuIUkoc93gJGGYut6mSDKy2+XaPwccwkRGlR+LO97L2VCCRjQivTwLHkSnAJG7yo00BWY6QM+w==", + "requires": { + "commander": "2", + "iconv-lite": "0.4", + "rw": "1" + } + }, + "d3-force": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-2.1.1.tgz", + "integrity": "sha512-nAuHEzBqMvpFVMf9OX75d00OxvOXdxY+xECIXjW6Gv8BRrXu6gAWbv/9XKrvfJ5i5DCokDW7RYE50LRoK092ew==", + "requires": { + "d3-dispatch": "1 - 2", + "d3-quadtree": "1 - 2", + "d3-timer": "1 - 2" + } + }, + "d3-format": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-2.0.0.tgz", + "integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==" + }, + "d3-geo": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-2.0.1.tgz", + "integrity": "sha512-M6yzGbFRfxzNrVhxDJXzJqSLQ90q1cCyb3EWFZ1LF4eWOBYxFypw7I/NFVBNXKNqxv1bqLathhYvdJ6DC+th3A==", + "requires": { + "d3-array": ">=2.5" + } + }, + "d3-geo-projection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-geo-projection/-/d3-geo-projection-3.0.0.tgz", + "integrity": "sha512-1JE+filVbkEX2bT25dJdQ05iA4QHvUwev6o0nIQHOSrNlHCAKfVss/U10vEM3pA4j5v7uQoFdQ4KLbx9BlEbWA==", + "requires": { + "commander": "2", + "d3-array": "1 - 2", + "d3-geo": "1.12.0 - 2", + "resolve": "^1.1.10" + } + }, + "d3-hierarchy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-2.0.0.tgz", + "integrity": "sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw==" + }, + "d3-interpolate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", + "integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==", + "requires": { + "d3-color": "1 - 2" + } + }, + "d3-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-2.0.0.tgz", + "integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==" + }, + "d3-quadtree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-2.0.0.tgz", + "integrity": "sha512-b0Ed2t1UUalJpc3qXzKi+cPGxeXRr4KU9YSlocN74aTzp6R/Ud43t79yLLqxHRWZfsvWXmbDWPpoENK1K539xw==" + }, + "d3-scale": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.3.tgz", + "integrity": "sha512-8E37oWEmEzj57bHcnjPVOBS3n4jqakOeuv1EDdQSiSrYnMCBdMd3nc4HtKk7uia8DUHcY/CGuJ42xxgtEYrX0g==", + "requires": { + "d3-array": "^2.3.0", + "d3-format": "1 - 2", + "d3-interpolate": "1.2.0 - 2", + "d3-time": "1 - 2", + "d3-time-format": "2 - 3" + } + }, + "d3-shape": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-2.0.0.tgz", + "integrity": "sha512-djpGlA779ua+rImicYyyjnOjeubyhql1Jyn1HK0bTyawuH76UQRWXd+pftr67H6Fa8hSwetkgb/0id3agKWykw==", + "requires": { + "d3-path": "1 - 2" + } + }, + "d3-time": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-2.0.0.tgz", + "integrity": "sha512-2mvhstTFcMvwStWd9Tj3e6CEqtOivtD8AUiHT8ido/xmzrI9ijrUUihZ6nHuf/vsScRBonagOdj0Vv+SEL5G3Q==" + }, + "d3-time-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-3.0.0.tgz", + "integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==", + "requires": { + "d3-time": "1 - 2" + } + }, + "d3-timer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz", + "integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA==" + }, "dash-ast": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", @@ -468,6 +657,11 @@ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", "dev": true }, + "delaunator": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-4.0.1.tgz", + "integrity": "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==" + }, "deps-sort": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz", @@ -558,6 +752,16 @@ } } }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, "events": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", @@ -574,6 +778,21 @@ "safe-buffer": "^5.1.1" } }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-patch": { + "version": "3.0.0-1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.0.0-1.tgz", + "integrity": "sha512-6pdFb07cknxvPzCeLsFHStEy+MysPJPgZQ9LbQ/2O67unQF93SNqfdSqnPPl71YMHX+AD8gbl7iuoGFzHEdDuw==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, "fast-safe-stringify": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", @@ -589,8 +808,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "get-assigned-identifiers": { "version": "1.2.0", @@ -598,6 +816,11 @@ "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", "dev": true }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -616,7 +839,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -678,6 +900,14 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -745,11 +975,15 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz", "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", - "dev": true, "requires": { "has": "^1.0.3" } }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -770,6 +1004,11 @@ "jsonify": "~0.0.0" } }, + "json-stringify-pretty-compact": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-2.0.0.tgz", + "integrity": "sha512-WRitRfs6BGq4q8gTgOy4ek7iPFXjbra0H3PmDLKm2xnZ+Gh1HUhiKGgCZkSPNULlP7mvfu6FV/mOLhCarspADQ==" + }, "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", @@ -806,6 +1045,14 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -891,6 +1138,11 @@ "xtend": "^4.0.0" } }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -954,8 +1206,7 @@ "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, "path-platform": { "version": "0.11.15", @@ -1130,11 +1381,15 @@ } } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, "resolve": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", - "dev": true, "requires": { "is-core-module": "^2.1.0", "path-parse": "^1.0.6" @@ -1150,6 +1405,11 @@ "inherits": "^2.0.1" } }, + "rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1159,8 +1419,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "scheduler": { "version": "0.20.1", @@ -1171,6 +1430,14 @@ "object-assign": "^4.1.1" } }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, "sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", @@ -1283,6 +1550,16 @@ "readable-stream": "^2.0.2" } }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -1292,6 +1569,14 @@ "safe-buffer": "~5.2.0" } }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + }, "subarg": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", @@ -1335,6 +1620,19 @@ "process": "~0.11.0" } }, + "topojson-client": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz", + "integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==", + "requires": { + "commander": "2" + } + }, + "tslib": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz", + "integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ==" + }, "tty-browserify": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", @@ -1407,12 +1705,419 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "vega": { + "version": "5.17.3", + "resolved": "https://registry.npmjs.org/vega/-/vega-5.17.3.tgz", + "integrity": "sha512-c8N2pNg9MMmC6shNpoxVw3aVp2XPFOgmWNX5BEOAdCaGHRnSgzNy44+gYdGRaIe6+ljTzZg99Mf+OLO50IP42A==", + "requires": { + "vega-crossfilter": "~4.0.5", + "vega-dataflow": "~5.7.3", + "vega-encode": "~4.8.3", + "vega-event-selector": "~2.0.6", + "vega-expression": "~4.0.1", + "vega-force": "~4.0.7", + "vega-format": "~1.0.4", + "vega-functions": "~5.10.0", + "vega-geo": "~4.3.8", + "vega-hierarchy": "~4.0.9", + "vega-label": "~1.0.0", + "vega-loader": "~4.4.0", + "vega-parser": "~6.1.2", + "vega-projection": "~1.4.5", + "vega-regression": "~1.0.9", + "vega-runtime": "~6.1.3", + "vega-scale": "~7.1.1", + "vega-scenegraph": "~4.9.2", + "vega-statistics": "~1.7.9", + "vega-time": "~2.0.4", + "vega-transforms": "~4.9.3", + "vega-typings": "~0.19.2", + "vega-util": "~1.16.0", + "vega-view": "~5.9.2", + "vega-view-transforms": "~4.5.8", + "vega-voronoi": "~4.1.5", + "vega-wordcloud": "~4.1.3" + } + }, + "vega-canvas": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/vega-canvas/-/vega-canvas-1.2.6.tgz", + "integrity": "sha512-rgeYUpslYn/amIfnuv3Sw6n4BGns94OjjZNtUc9IDji6b+K8LGS/kW+Lvay8JX/oFqtulBp8RLcHN6QjqPLA9Q==" + }, + "vega-crossfilter": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/vega-crossfilter/-/vega-crossfilter-4.0.5.tgz", + "integrity": "sha512-yF+iyGP+ZxU7Tcj5yBsMfoUHTCebTALTXIkBNA99RKdaIHp1E690UaGVLZe6xde2n5WaYpho6I/I6wdAW3NXcg==", + "requires": { + "d3-array": "^2.7.1", + "vega-dataflow": "^5.7.3", + "vega-util": "^1.15.2" + } + }, + "vega-dataflow": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/vega-dataflow/-/vega-dataflow-5.7.3.tgz", + "integrity": "sha512-2ipzKgQUmbSXcQBH+9XF0BYbXyZrHvjlbJ8ifyRWYQk78w8kMvE6wy/rcdXYK6iVZ6aAbEDDT7jTI+rFt3tGLA==", + "requires": { + "vega-format": "^1.0.4", + "vega-loader": "^4.3.2", + "vega-util": "^1.15.2" + } + }, + "vega-embed": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/vega-embed/-/vega-embed-6.14.2.tgz", + "integrity": "sha512-cZsI0+eSB1BubRFkpeZs9mdWQGfO0T7i78dffGULg+1+Up+74aB/cg7refC+KsnEEGOeOtP9RWz9Ttkabs2oYA==", + "requires": { + "fast-json-patch": "^3.0.0-1", + "json-stringify-pretty-compact": "^2.0.0", + "semver": "^7.3.4", + "vega-schema-url-parser": "^2.1.0", + "vega-themes": "^2.9.1", + "vega-tooltip": "^0.24.2" + } + }, + "vega-encode": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/vega-encode/-/vega-encode-4.8.3.tgz", + "integrity": "sha512-JoRYtaV2Hs8spWLzTu/IjR7J9jqRmuIOEicAaWj6T9NSZrNWQzu2zF3IVsX85WnrIDIRUDaehXaFZvy9uv9RQg==", + "requires": { + "d3-array": "^2.7.1", + "d3-interpolate": "^2.0.1", + "vega-dataflow": "^5.7.3", + "vega-scale": "^7.0.3", + "vega-util": "^1.15.2" + } + }, + "vega-event-selector": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vega-event-selector/-/vega-event-selector-2.0.6.tgz", + "integrity": "sha512-UwCu50Sqd8kNZ1X/XgiAY+QAyQUmGFAwyDu7y0T5fs6/TPQnDo/Bo346NgSgINBEhEKOAMY1Nd/rPOk4UEm/ew==" + }, + "vega-expression": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/vega-expression/-/vega-expression-4.0.1.tgz", + "integrity": "sha512-ZrDj0hP8NmrCpdLFf7Rd/xMUHGoSYsAOTaYp7uXZ2dkEH5x0uPy5laECMc8TiQvL8W+8IrN2HAWCMRthTSRe2Q==", + "requires": { + "vega-util": "^1.16.0" + } + }, + "vega-force": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/vega-force/-/vega-force-4.0.7.tgz", + "integrity": "sha512-pyLKdwXSZ9C1dVIqdJOobvBY29rLvZjvRRTla9BU/nMwAiAGlGi6WKUFdRGdneyGe3zo2nSZDTZlZM/Z5VaQNA==", + "requires": { + "d3-force": "^2.1.1", + "vega-dataflow": "^5.7.3", + "vega-util": "^1.15.2" + } + }, + "vega-format": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vega-format/-/vega-format-1.0.4.tgz", + "integrity": "sha512-oTAeub3KWm6nKhXoYCx1q9G3K43R6/pDMXvqDlTSUtjoY7b/Gixm8iLcir5S9bPjvH40n4AcbZsPmNfL/Up77A==", + "requires": { + "d3-array": "^2.7.1", + "d3-format": "^2.0.0", + "d3-time-format": "^3.0.0", + "vega-time": "^2.0.3", + "vega-util": "^1.15.2" + } + }, + "vega-functions": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/vega-functions/-/vega-functions-5.10.0.tgz", + "integrity": "sha512-1l28OxUwOj8FEvRU62Oz2hiTuDECrvx1DPU1qLebBKhlgaKbcCk3XyHrn1kUzhMKpXq+SFv5VPxchZP47ASSvQ==", + "requires": { + "d3-array": "^2.7.1", + "d3-color": "^2.0.0", + "d3-geo": "^2.0.1", + "vega-dataflow": "^5.7.3", + "vega-expression": "^4.0.1", + "vega-scale": "^7.1.1", + "vega-scenegraph": "^4.9.2", + "vega-selections": "^5.1.5", + "vega-statistics": "^1.7.9", + "vega-time": "^2.0.4", + "vega-util": "^1.16.0" + } + }, + "vega-geo": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/vega-geo/-/vega-geo-4.3.8.tgz", + "integrity": "sha512-fsGxV96Q/QRgPqOPtMBZdI+DneIiROKTG3YDZvGn0EdV16OG5LzFhbNgLT5GPzI+kTwgLpAsucBHklexlB4kfg==", + "requires": { + "d3-array": "^2.7.1", + "d3-color": "^2.0.0", + "d3-geo": "^2.0.1", + "vega-canvas": "^1.2.5", + "vega-dataflow": "^5.7.3", + "vega-projection": "^1.4.5", + "vega-statistics": "^1.7.9", + "vega-util": "^1.15.2" + } + }, + "vega-hierarchy": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/vega-hierarchy/-/vega-hierarchy-4.0.9.tgz", + "integrity": "sha512-4XaWK6V38/QOZ+vllKKTafiwL25m8Kd+ebHmDV+Q236ONHmqc/gv82wwn9nBeXPEfPv4FyJw2SRoqa2Jol6fug==", + "requires": { + "d3-hierarchy": "^2.0.0", + "vega-dataflow": "^5.7.3", + "vega-util": "^1.15.2" + } + }, + "vega-label": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vega-label/-/vega-label-1.0.0.tgz", + "integrity": "sha512-hCdm2pcHgkKgxnzW9GvX5JmYNiUMlOXOibtMmBzvFBQHX3NiV9giQ5nsPiQiFbV08VxEPtM+VYXr2HyrIcq5zQ==", + "requires": { + "vega-canvas": "^1.2.5", + "vega-dataflow": "^5.7.3", + "vega-scenegraph": "^4.9.2", + "vega-util": "^1.15.2" + } + }, + "vega-lite": { + "version": "4.17.0", + "resolved": "https://registry.npmjs.org/vega-lite/-/vega-lite-4.17.0.tgz", + "integrity": "sha512-MO2XsaVZqx6iWWmVA5vwYFamvhRUsKfVp7n0pNlkZ2/21cuxelSl92EePZ2YGmzL6z4/3K7r/45zaG8p+qNHeg==", + "requires": { + "@types/clone": "~2.1.0", + "@types/fast-json-stable-stringify": "^2.0.0", + "array-flat-polyfill": "^1.0.1", + "clone": "~2.1.2", + "fast-deep-equal": "~3.1.3", + "fast-json-stable-stringify": "~2.1.0", + "json-stringify-pretty-compact": "~2.0.0", + "tslib": "~2.0.3", + "vega-event-selector": "~2.0.6", + "vega-expression": "~3.0.0", + "vega-util": "~1.16.0", + "yargs": "~16.0.3" + }, + "dependencies": { + "vega-expression": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vega-expression/-/vega-expression-3.0.1.tgz", + "integrity": "sha512-+UwOFEkBnAWo8Zud6i8O4Pd2W6QqmPUOaAhjNtj0OxRL+d+Duoy7M4edUDZ+YuoUcMnjjBFfDQu7oRAA1fIMEQ==", + "requires": { + "vega-util": "^1.15.2" + } + } + } + }, + "vega-loader": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/vega-loader/-/vega-loader-4.4.0.tgz", + "integrity": "sha512-e5enQECdau7rJob0NFB5pGumh3RaaSWWm90+boxMy3ay2b4Ki/3XIvo+C4F1Lx04qSxvQF7tO2LJcklRm6nqRA==", + "requires": { + "d3-dsv": "^2.0.0", + "node-fetch": "^2.6.1", + "topojson-client": "^3.1.0", + "vega-format": "^1.0.4", + "vega-util": "^1.16.0" + } + }, + "vega-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/vega-parser/-/vega-parser-6.1.2.tgz", + "integrity": "sha512-aGyZrNzPrBruEb/WhemKDuDjQsIkMDGIgnSJci0b+9ZVxjyAzMl7UfGbiYorPiJlnIercjUJbMoFD6fCIf4gqQ==", + "requires": { + "vega-dataflow": "^5.7.3", + "vega-event-selector": "^2.0.6", + "vega-functions": "^5.10.0", + "vega-scale": "^7.1.1", + "vega-util": "^1.15.2" + } + }, + "vega-projection": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/vega-projection/-/vega-projection-1.4.5.tgz", + "integrity": "sha512-85kWcPv0zrrNfxescqHtSYpRknilrS0K3CVRZc7IYQxnLtL1oma9WEbrSr1LCmDoCP5hl2Z1kKbomPXkrQX5Ag==", + "requires": { + "d3-geo": "^2.0.1", + "d3-geo-projection": "^3.0.0" + } + }, + "vega-regression": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/vega-regression/-/vega-regression-1.0.9.tgz", + "integrity": "sha512-KSr3QbCF0vJEAWFVY2MA9X786oiJncTTr3gqRMPoaLr/Yo3f7OPKXRoUcw36RiWa0WCOEMgTYtM28iK6ZuSgaA==", + "requires": { + "d3-array": "^2.7.1", + "vega-dataflow": "^5.7.3", + "vega-statistics": "^1.7.9", + "vega-util": "^1.15.2" + } + }, + "vega-runtime": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/vega-runtime/-/vega-runtime-6.1.3.tgz", + "integrity": "sha512-gE+sO2IfxMUpV0RkFeQVnHdmPy3K7LjHakISZgUGsDI/ZFs9y+HhBf8KTGSL5pcZPtQsZh3GBQ0UonqL1mp9PA==", + "requires": { + "vega-dataflow": "^5.7.3", + "vega-util": "^1.15.2" + } + }, + "vega-scale": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/vega-scale/-/vega-scale-7.1.1.tgz", + "integrity": "sha512-yE0to0prA9E5PBJ/XP77TO0BMkzyUVyt7TH5PAwj+CZT7PMsMO6ozihelRhoIiVcP0Ae/ByCEQBUQkzN5zJ0ZA==", + "requires": { + "d3-array": "^2.7.1", + "d3-interpolate": "^2.0.1", + "d3-scale": "^3.2.2", + "vega-time": "^2.0.4", + "vega-util": "^1.15.2" + } + }, + "vega-scenegraph": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/vega-scenegraph/-/vega-scenegraph-4.9.2.tgz", + "integrity": "sha512-epm1CxcB8AucXQlSDeFnmzy0FCj+HV2k9R6ch2lfLRln5lPLEfgJWgFcFhVf5jyheY0FSeHH52Q5zQn1vYI1Ow==", + "requires": { + "d3-path": "^2.0.0", + "d3-shape": "^2.0.0", + "vega-canvas": "^1.2.5", + "vega-loader": "^4.3.3", + "vega-scale": "^7.1.1", + "vega-util": "^1.15.2" + } + }, + "vega-schema-url-parser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/vega-schema-url-parser/-/vega-schema-url-parser-2.1.0.tgz", + "integrity": "sha512-JHT1PfOyVzOohj89uNunLPirs05Nf59isPT5gnwIkJph96rRgTIBJE7l7yLqndd7fLjr3P8JXHGAryRp74sCaQ==" + }, + "vega-selections": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/vega-selections/-/vega-selections-5.1.5.tgz", + "integrity": "sha512-oRSsfkqYqA5xfEJqDpgnSDd+w0k6p6SGYisMD6rGXMxuPl0x0Uy6RvDr4nbEtB+dpWdoWEvgrsZVS6axyDNWvQ==", + "requires": { + "vega-expression": "^4.0.0", + "vega-util": "^1.15.2" + } + }, + "vega-statistics": { + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/vega-statistics/-/vega-statistics-1.7.9.tgz", + "integrity": "sha512-T0sd2Z08k/mHxr1Vb4ajLWytPluLFYnsYqyk4SIS5czzUs4errpP2gUu63QJ0B7CKNu33vnS9WdOMOo/Eprr/Q==", + "requires": { + "d3-array": "^2.7.1" + } + }, + "vega-themes": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/vega-themes/-/vega-themes-2.9.1.tgz", + "integrity": "sha512-N6GU8u1EpfqxswXpBKLYouD3gYGfvrKWTC07JSrnlvGUzKzXMPDm4fN8FP8+cBpTwBL6JDZBd86A1Haea/nTfQ==" + }, + "vega-time": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vega-time/-/vega-time-2.0.4.tgz", + "integrity": "sha512-U314UDR9+ZlWrD3KBaeH+j/c2WSMdvcZq5yJfFT0yTg1jsBKAQBYFGvl+orackD8Zx3FveHOxx3XAObaQeDX+Q==", + "requires": { + "d3-array": "^2.7.1", + "d3-time": "^2.0.0", + "vega-util": "^1.15.2" + } + }, + "vega-tooltip": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/vega-tooltip/-/vega-tooltip-0.24.2.tgz", + "integrity": "sha512-b7IeYQl/piNVsMmTliOgTnwSOhBs67KqoZ9UzP1I3XpH7TKbSuc3YHA7b1CSxkRR0hHKdradby4UI8c9rdH74w==", + "requires": { + "vega-util": "^1.15.2" + } + }, + "vega-transforms": { + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/vega-transforms/-/vega-transforms-4.9.3.tgz", + "integrity": "sha512-PdqQd5oPlRyD405M2w+Sz9Bo+i7Rwi8o03SVK7RaeQsJC2FffKGJ6acIaSEgOq+yD1Q2k/1SePmCXcmLUlIiEA==", + "requires": { + "d3-array": "^2.7.1", + "vega-dataflow": "^5.7.3", + "vega-statistics": "^1.7.9", + "vega-time": "^2.0.4", + "vega-util": "^1.15.2" + } + }, + "vega-typings": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/vega-typings/-/vega-typings-0.19.2.tgz", + "integrity": "sha512-YU/S9rDk4d+t4+4eTa9fzuw87PMNteeVtpcL51kUO8H7HvGaoW7ll8RHKLkR0NYBEGPRoFDKUxnoyMvhgjsdYw==", + "requires": { + "vega-util": "^1.15.2" + } + }, + "vega-util": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/vega-util/-/vega-util-1.16.0.tgz", + "integrity": "sha512-6mmz6mI+oU4zDMeKjgvE2Fjz0Oh6zo6WGATcvCfxH2gXBzhBHmy5d25uW5Zjnkc6QBXSWPLV9Xa6SiqMsrsKog==" + }, + "vega-view": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/vega-view/-/vega-view-5.9.2.tgz", + "integrity": "sha512-XAwKWyVjLClR3aCbTLCWdZj7aZozOULNg7078GxJIgVcBJOENCAidceI/H7JieyUZ96p3AiEHLQdWr167InBpg==", + "requires": { + "d3-array": "^2.7.1", + "d3-timer": "^2.0.0", + "vega-dataflow": "^5.7.3", + "vega-format": "^1.0.4", + "vega-functions": "^5.10.0", + "vega-runtime": "^6.1.3", + "vega-scenegraph": "^4.9.2", + "vega-util": "^1.15.2" + } + }, + "vega-view-transforms": { + "version": "4.5.8", + "resolved": "https://registry.npmjs.org/vega-view-transforms/-/vega-view-transforms-4.5.8.tgz", + "integrity": "sha512-966m7zbzvItBL8rwmF2nKG14rBp7q+3sLCKWeMSUrxoG+M15Smg5gWEGgwTG3A/RwzrZ7rDX5M1sRaAngRH25g==", + "requires": { + "vega-dataflow": "^5.7.3", + "vega-scenegraph": "^4.9.2", + "vega-util": "^1.15.2" + } + }, + "vega-voronoi": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/vega-voronoi/-/vega-voronoi-4.1.5.tgz", + "integrity": "sha512-950IkgCFLj0zG33EWLAm1hZcp+FMqWcNQliMYt+MJzOD5S4MSpZpZ7K4wp2M1Jktjw/CLKFL9n38JCI0i3UonA==", + "requires": { + "d3-delaunay": "^5.3.0", + "vega-dataflow": "^5.7.3", + "vega-util": "^1.15.2" + } + }, + "vega-wordcloud": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/vega-wordcloud/-/vega-wordcloud-4.1.3.tgz", + "integrity": "sha512-is4zYn9FMAyp9T4SAcz2P/U/wqc0Lx3P5YtpWKCbOH02a05vHjUQrQ2TTPOuvmMfAEDCSKvbMSQIJMOE018lJA==", + "requires": { + "vega-canvas": "^1.2.5", + "vega-dataflow": "^5.7.3", + "vega-scale": "^7.1.1", + "vega-statistics": "^1.7.9", + "vega-util": "^1.15.2" + } + }, "vm-browserify": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "dev": true }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -1430,6 +2135,35 @@ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true + }, + "y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yargs": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.0.3.tgz", + "integrity": "sha512-6+nLw8xa9uK1BOEOykaiYAJVh6/CjxWXK/q9b5FpRgNslt8s22F2xMBqVIKgCRjNgGvGPBy8Vog7WN7yh4amtA==", + "requires": { + "cliui": "^7.0.0", + "escalade": "^3.0.2", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.1", + "yargs-parser": "^20.0.0" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" } } } diff --git a/package.json b/package.json index 26eab053..1bdef8b3 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,8 @@ { "dependencies": { + "vega-lite": "^4.17.0", + "vega-embed": "^6.14.2", + "vega": "^5.17.3", "csv-parse": "^4.14.2", "react": "17.0.1", "react-dom": "17.0.1", diff --git a/src/examples/data.cljc b/src/examples/data.cljc index 2cd2b8a0..a1939af6 100644 --- a/src/examples/data.cljc +++ b/src/examples/data.cljc @@ -85,6 +85,135 @@ [:a {:href "https://github.com/djblue/portal"} "djblue/portal"]] {:portal.viewer/default :portal.viewer/hiccup})) +(def line-chart + {:data {:values (map #(-> {:time % :value (Math/sin %)}) + (range 0 (* 2 3.14) 0.25))} + :encoding {:x {:field "time" :type "quantitative"} + :y {:field "value" :type "quantitative"}} + :mark "line"}) + +(def bar-chart + {:data + {:values + [{:a "A", :b 28} + {:a "B", :b 55} + {:a "C", :b 43} + {:a "D", :b 91} + {:a "E", :b 81} + {:a "F", :b 53}]} + :mark "bar" + :encoding + {:x + {:field "a" + :type "nominal" + :axis {:labelAngle 0}} + :y {:field "b", :type "quantitative"}}}) + +(def pie-chart + {:description + "A simple pie chart with labels." + :data + {:values + [{:category "a", :value 4} + {:category "b", :value 6} + {:category "c", :value 10} + {:category "d", :value 3} + {:category "e", :value 7} + {:category "f", :value 8}]} + :encoding + {:theta + {:field "value" + :type "quantitative" + :stack true} + :color + {:field "category" + :type "nominal" + :legend nil}} + :layer + [{:mark {:type "arc", :outerRadius 80}} + {:mark {:type "text", :radius 90} + :encoding + {:text + {:field "category", :type "nominal"}}}] + :view {:stroke nil}}) + +(def tabular-data + (map #(-> {:x % + :y (#?(:clj Math/sin + :cljs js/Math.sin) %)}) + (range 0 (* 2 3.14) 0.25))) + +(def numerical-collection + {:x (range -3.12 3.14 0.1) + :y (map #(+ % (/ (* -1 % % %) 6)) + (range -3.14 3.14 0.1))}) + +(def scatter-chart + {:$schema + "https://vega.github.io/schema/vega-lite/v4.json" + :description + "A scatterplot showing horsepower and miles per gallons for various cars." + :data {:url "https://vega.github.io/vega-lite/data/cars.json"} + :mark "point" + :encoding + {:x + {:field "Horsepower", :type "quantitative"} + :y + {:field "Miles_per_Gallon" + :type "quantitative"}}}) + +(def geographic-data + {:width "container" + :height "container" + :data {:url "https://vega.github.io/vega-lite/data/airports.csv"} + :projection {:type "albersUsa"} + :mark "circle" + :encoding + {:longitude + {:field "longitude", :type "quantitative"} + :latitude + {:field "latitude", :type "quantitative"} + :size {:value 10}} + :config {:view {:stroke "transparent"}}}) + +(def histogram-heatmap-2D + {:$schema + "https://vega.github.io/schema/vega-lite/v4.json" + :data {:url "https://vega.github.io/vega-lite/data/movies.json"} + :transform + [{:filter + {:and + [{:field "IMDB Rating", :valid true} + {:field "Rotten Tomatoes Rating" + :valid true}]}}] + :mark "rect" + :width "container" + :height "container" + :encoding + {:x + {:bin {:maxbins 60} + :field "IMDB Rating" + :type "quantitative"} + :y + {:bin {:maxbins 40} + :field "Rotten Tomatoes Rating" + :type "quantitative"} + :color + {:aggregate "count", :type "quantitative"}} + :config {:view {:stroke "transparent"}}}) + +(def data-visualization + {::vega-lite + {::line-chart line-chart + ::pie-chart pie-chart + ::bar-chart bar-chart + ::scatter-chart scatter-chart + ::histogram-heatmap-2D histogram-heatmap-2D + ::geographic-data geographic-data} + ::portal-charts + {::tabular-data tabular-data + ::numerical-collection numerical-collection}}) + (def data {::platform-data platform-data ::hacker-news hn/stories @@ -93,4 +222,5 @@ ::themes c/themes ::clojure-data clojure-data ::hiccup hiccup + ::data-visualization data-visualization ::string-data string-data}) diff --git a/src/portal/ui/app.cljs b/src/portal/ui/app.cljs index b6e7d597..defc46cf 100644 --- a/src/portal/ui/app.cljs +++ b/src/portal/ui/app.cljs @@ -5,6 +5,7 @@ [portal.ui.inspector :as ins :refer [inspector]] [portal.ui.state :refer [state tap-state]] [portal.ui.styled :as s] + [portal.ui.viewer.charts :as charts] [portal.ui.viewer.csv :as csv] [portal.ui.viewer.diff :as diff] [portal.ui.viewer.edn :as edn] @@ -18,6 +19,7 @@ [portal.ui.viewer.text :as text] [portal.ui.viewer.transit :as transit] [portal.ui.viewer.tree :as tree] + [portal.ui.viewer.vega-lite :as vega-lite] [reagent.core :as r])) (defn filter-data [settings value] @@ -130,6 +132,10 @@ (def viewers [ex/viewer + vega-lite/viewer + charts/line-chart + charts/scatter-chart + charts/histogram-chart image/viewer {:name :portal.viewer/map :predicate map? :component ins/inspect-map} {:name :portal.viewer/coll :predicate coll? :component ins/inspect-coll} diff --git a/src/portal/ui/styled.cljs b/src/portal/ui/styled.cljs index 99e57f40..553db829 100644 --- a/src/portal/ui/styled.cljs +++ b/src/portal/ui/styled.cljs @@ -14,7 +14,7 @@ (def exclude? #{:opacity :z-index}) -(defn- style->css [style] +(defn style->css [style] (reduce-kv (fn [css k v] (str diff --git a/src/portal/ui/viewer/charts.cljs b/src/portal/ui/viewer/charts.cljs new file mode 100644 index 00000000..c1bded86 --- /dev/null +++ b/src/portal/ui/viewer/charts.cljs @@ -0,0 +1,83 @@ +(ns portal.ui.viewer.charts + (:require [clojure.spec.alpha :as sp] + [portal.colors :as c] + [portal.ui.viewer.vega-lite :as v])) + +;; collection of maps of [{:x 0 :y 0} ...] maps +(sp/def :tabular/x number?) +(sp/def :tabular/y number?) +(sp/def ::data + (sp/keys :req-un [:tabular/x :tabular/y])) +(sp/def ::tabular-data + (sp/coll-of ::data :min-count 2)) + +;; :x [0 1 2 ...] :y [0 1 2 ...] +(sp/def :numerical-coll/x + (sp/coll-of number? :min-count 2)) +(sp/def :numerical-coll/y + (sp/coll-of number? :min-count 2)) +(sp/def ::numerical-collection + (sp/keys :req-un [:numerical-coll/x :numerical-coll/y])) + +(defn normalize-data + "Normalize data to conform to vega-lite specification" + [data] + (cond + (sp/valid? ::tabular-data data) + data + (sp/valid? ::numerical-collection data) + (for [[x y] (map vector (:x data) (:y data))] {:x x :y y}))) + +(defn line-chart-viewer + [settings value] + [v/vega-lite-viewer + settings + {:data + {:values (normalize-data value)} + :encoding + {:x {:field "x" :type "quantitative"} + :y {:field "y" :type "quantitative"} + :color {:value (::c/number settings)}} + :mark "line" + :selection {:grid {:type "interval" :bind "scales"}}}]) + +(defn scatter-chart-viewer + [settings value] + [v/vega-lite-viewer + settings + {:data {:values (normalize-data value)} + :encoding + {:x {:field "x" :type "quantitative"} + :y {:field "y" :type "quantitative"} + :color {:value (::c/number settings)} + :tooltip + [{:field "x" :type "quantitative"} + {:field "y" :type "quantitative"}]} + :mark "circle" + :selection {:grid {:type "interval" :bind "scales"}}}]) + +(defn histogram-chart-viewer + [settings value] + [v/vega-lite-viewer + settings + {:data {:values (normalize-data value)} + :mark "bar" + :encoding + {:x {:bin true :field "x" :type "quantitative"} + :y {:aggregate "count" :type "quantitative"} + :color {:value (::c/number settings)}}}]) + +(def line-chart + {:predicate (partial sp/valid? (sp/or :tabular ::tabular-data ::numerical-collection ::numerical-collection)) + :component line-chart-viewer + :name :portal.viewer/line-chart}) + +(def scatter-chart + {:predicate (partial sp/valid? (sp/or :tabular ::tabular-data ::numerical-collection ::numerical-collection)) + :component scatter-chart-viewer + :name :portal.viewer/scatter-chart}) + +(def histogram-chart + {:predicate (partial sp/valid? (sp/or :tabular ::tabular-data ::numerical-collection ::numerical-collection)) + :component histogram-chart-viewer + :name :portal.viewer/histogram-chart}) \ No newline at end of file diff --git a/src/portal/ui/viewer/vega_lite.cljs b/src/portal/ui/viewer/vega_lite.cljs new file mode 100644 index 00000000..f66860dd --- /dev/null +++ b/src/portal/ui/viewer/vega_lite.cljs @@ -0,0 +1,168 @@ +(ns portal.ui.viewer.vega-lite + (:require ["vega-embed" :as vegaEmbed] + [clojure.spec.alpha :as sp] + [clojure.string :as str] + [portal.colors :as c] + [portal.ui.styled :as s] + [reagent.core :as r] + [reagent.dom :as rd])) + +;; Vega-lite spec +;; https://vega.github.io/vega-lite/docs/spec.html + +(sp/def ::field + (sp/or :key keyword? :string string?)) + +(sp/def ::x + (sp/keys :req-un [::field] + :opt-un [::type ::title ::axis])) + +(sp/def ::y + (sp/keys :req-un [::field] + :opt-un [::type ::title ::axis])) + +(sp/def ::encoding + (sp/keys :opt-un [::x ::y ::theta])) + +(sp/def ::values + (sp/coll-of map?)) + +(sp/def ::inline-data + (sp/keys :req-un [::values])) + +(sp/def ::remote-data + (sp/keys :req-un [::url])) + +(sp/def ::data + (sp/or :remote-data ::remote-data :inline ::inline-data)) + +(sp/def ::mark-string + #{"bar" "circle" "square" "rect" "tick" "line" "area" "point" "geoshape" "rule" "text" "boxplot" "errorband" "errorbar"}) + +(sp/def ::mark-object + (sp/keys :req-un [::mark-string] + :opt-un [::aria ::description ::style ::tooltip ::clip ::invalid ::order])) + +(sp/def ::mark + (sp/or :mark ::mark-string :mark-object ::mark-object)) + +(sp/def ::layer coll?) + +;; https://vega.github.io/vega-lite/docs/spec.html#single +(sp/def ::single-view + (sp/keys :req-un [::data ::encoding ::mark] + :opt-un [::title ::name ::description ::transform ::width ::height])) + +;; https://vega.github.io/vega-lite/docs/spec.html#layered-and-multi-view-specifications +(sp/def ::layered-view + (sp/keys :req-un [::data ::encoding ::layer] + :opt-un [::title ::name ::description ::transform ::width ::height])) + +(sp/def ::vega-lite + (sp/or :single-view ::single-view :layered-view ::layered-view)) + +(defn- default-config + "Specifies a nicer set of vega-lite specification styles. + All defaults can be overridden by users data" + [settings] + (let [background (::c/background settings) + text (::c/text settings) + border (::c/border settings)] + {:width "container" + :height "container" + :padding "30" + :autosize + {:type "fit" + :resize true + :contains "padding"} + :config + {:legend + {:labelColor text + :titleColor text} + :view + {:stroke "transparent"} + :axis + {:domainColor border + :domainWidth "3" + :tickColor border + :gridColor border + :gridDash [10 2] + :titleColor text + :labelColor text}} + :background background})) + +(defn- map->css [m] + (reduce-kv + (fn [css k v] + (str css + (str/join " " (map name k)) + "{" (s/style->css v) "}\n")) + "" + m)) + +(defn- vega-lite-styles + "CSS styles applied to the vega embed elements. Allow filling most of the container." + [settings] + [:style + (map->css + {[:.vega-embed :.chart-wrapper] + {:width "100%" :height "100%"} + [:.vega-embed] + {:width "100%" + :height "90%" + :border-color (::c/border settings) + :border-width 1 + :border-style :solid} + [:.vega-embed :summary] + {:opacity 1 + :cursor :default + :margin-right (:spacing/padding settings) + :margin-top (:spacing/padding settings)}})]) + +(defn- deep-merge + "Recursively merges maps. + http://dnaeon.github.io/recursively-merging-maps-in-clojure/" + [& maps] + (letfn [(m [& xs] + (if (some #(and (map? %) (not (record? %))) xs) + (apply merge-with m xs) + (last xs)))] + (reduce m maps))) + +;; The following is based on Oz to avoid bringing in extra deps +;; https://github.com/metasoarous/oz/blob/master/src/cljs/oz/core.cljs +(defn- vega-embed + [elem doc opts] + (-> (vegaEmbed elem (clj->js doc) (clj->js opts)) + (.catch (fn [err] (js/console.error err))))) + +(defn- vega-class + "Creates React Class component for vega(-lite)" + [doc opts] + (r/create-class + {:display-name + (:mode doc) + :component-did-mount + (fn [this] + (vega-embed (rd/dom-node this) doc opts)) + :component-will-update + (fn [this [_ new-doc new-opts]] + (vega-embed (rd/dom-node this) new-doc new-opts)) + :reagent-render + (fn [_] + [:div.viz])})) + +(defn vega-lite-viewer + [settings value] + [s/div + [vega-lite-styles settings] + [:h1 (:title value)] + [:p (:description value)] + [vega-class + (deep-merge (default-config settings) value) + {:mode "vega-lite" :renderer :canvas}]]) + +(def viewer + {:predicate (partial sp/valid? ::vega-lite) + :component vega-lite-viewer + :name :portal.viewer/vega-lite}) \ No newline at end of file From d60f8bbbcdba024a2e6cfdc7b69734223cb6a357 Mon Sep 17 00:00:00 2001 From: Brian Chevalier Date: Tue, 29 Dec 2020 20:00:09 -0700 Subject: [PATCH 2/2] Fix CI --- .github/workflows/clojure.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/clojure.yml b/.github/workflows/clojure.yml index 9f93edd0..5060982e 100644 --- a/.github/workflows/clojure.yml +++ b/.github/workflows/clojure.yml @@ -23,7 +23,9 @@ jobs: - run: make install/chrome install/clojure - run: make ci - run: make app + if: ${{ github.event_name == 'push' }} - uses: peaceiris/actions-gh-pages@v3 + if: ${{ github.event_name == 'push' }} with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./target/pwa-release/