From f1e029ca63bcdef76e38461762452631f0e19886 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Wed, 27 Mar 2024 12:16:07 -0700 Subject: [PATCH 1/9] In-progress vega adding --- packages/components/package.json | 3 + packages/components/src/styles/common.css | 4 + .../src/widgets/DistWidget/index.tsx | 102 +++- .../src/widgets/PlotWidget/index.tsx | 104 +++- pnpm-lock.yaml | 455 +++++++++++++++++- 5 files changed, 646 insertions(+), 22 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 61e728fc78..9842a40e45 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -36,10 +36,13 @@ "react-draggable": "^4.4.6", "react-hook-form": "^7.50.0", "react-markdown": "^9.0.1", + "react-vega": "^7.6.0", "remark-gfm": "^4.0.0", "shikiji": "^0.10.2", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", + "vega": "^5.28.0", + "vega-lite": "^5.17.0", "zod": "^3.22.4" }, "devDependencies": { diff --git a/packages/components/src/styles/common.css b/packages/components/src/styles/common.css index 8bf7a040e4..99fba2b68a 100644 --- a/packages/components/src/styles/common.css +++ b/packages/components/src/styles/common.css @@ -54,3 +54,7 @@ .cm-tooltip-autocomplete .cm-tooltip { background: white; } + +.vega-embed { + width: 100%; +} diff --git a/packages/components/src/widgets/DistWidget/index.tsx b/packages/components/src/widgets/DistWidget/index.tsx index 977eb57b8b..2827b62169 100644 --- a/packages/components/src/widgets/DistWidget/index.tsx +++ b/packages/components/src/widgets/DistWidget/index.tsx @@ -1,3 +1,5 @@ +import { Vega } from "react-vega"; + import { SqDistributionsPlot, SqScale } from "@quri/squiggle-lang"; import { generateDistributionPlotSettings } from "../../components/PlaygroundSettings.js"; @@ -13,6 +15,93 @@ import { DistributionsChart } from "./DistributionsChart.js"; // Note that for distributions, this only applies to the internals, there's also extra margin and details. export const CHART_TO_DIST_HEIGHT_ADJUSTMENT = 0.55; +const foo = ( + +); + widgetRegistry.register("Dist", { Preview(value) { const dist = value.value; @@ -80,12 +169,11 @@ widgetRegistry.register("Dist", { ), }); - return ( - - ); + return foo; + // }, }); diff --git a/packages/components/src/widgets/PlotWidget/index.tsx b/packages/components/src/widgets/PlotWidget/index.tsx index 52e4bd5f5a..bf941ec586 100644 --- a/packages/components/src/widgets/PlotWidget/index.tsx +++ b/packages/components/src/widgets/PlotWidget/index.tsx @@ -1,11 +1,98 @@ -import { DistributionsChart } from "../DistWidget/DistributionsChart.js"; -import { CHART_TO_DIST_HEIGHT_ADJUSTMENT } from "../DistWidget/index.js"; +import { Vega } from "react-vega"; + import { DistFunctionChart } from "../LambdaWidget/FunctionChart/DistFunctionChart.js"; import { NumericFunctionChart } from "../LambdaWidget/FunctionChart/NumericFunctionChart.js"; import { widgetRegistry } from "../registry.js"; import { RelativeValuesGridChart } from "./RelativeValuesGridChart/index.js"; import { ScatterChart } from "./ScatterChart/index.js"; +const foo = ( + +); + widgetRegistry.register("Plot", { Chart: (value, settings) => { const plot = value.value; @@ -13,13 +100,12 @@ widgetRegistry.register("Plot", { switch (plot.tag) { case "distributions": - return ( - - ); + return foo; + // case "numericFn": { return ( =18'} dev: false + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: false + /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -9965,6 +9981,13 @@ packages: internmap: 2.0.3 dev: false + /d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + dependencies: + internmap: 2.0.3 + dev: false + /d3-axis@3.0.0: resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} engines: {node: '>=12'} @@ -10056,6 +10079,16 @@ packages: engines: {node: '>=12'} dev: false + /d3-geo-projection@4.0.0: + resolution: {integrity: sha512-p0bK60CEzph1iqmnxut7d/1kyTmm3UWtPlwdkM31AU+LW+BXazd5zJdoCn7VFxNCHXRngPHRnsNn5uGjLRGndg==} + engines: {node: '>=12'} + hasBin: true + dependencies: + commander: 7.2.0 + d3-array: 3.2.4 + d3-geo: 3.1.0 + dev: false + /d3-geo@3.1.0: resolution: {integrity: sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==} engines: {node: '>=12'} @@ -11582,6 +11615,10 @@ packages: merge2: 1.4.1 micromatch: 4.0.5 + /fast-json-patch@3.1.1: + resolution: {integrity: sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==} + dev: false + /fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} dev: true @@ -11956,7 +11993,6 @@ packages: /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - dev: true /get-intrinsic@1.2.2: resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} @@ -14035,6 +14071,10 @@ packages: jsonify: 0.0.1 dev: true + /json-stringify-pretty-compact@3.0.0: + resolution: {integrity: sha512-Rc2suX5meI0S3bfdZuA7JMFBGkJ875ApfVyq2WHELjBiiG22My/l7/8zPpH/CfFVQHuVLd8NLR0nv6vi0BYYKA==} + dev: false + /json-to-pretty-yaml@1.2.2: resolution: {integrity: sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==} engines: {node: '>= 0.2.0'} @@ -17459,6 +17499,22 @@ packages: tslib: 2.6.2 dev: false + /react-vega@7.6.0(react@18.2.0)(vega-lite@5.17.0)(vega@5.28.0): + resolution: {integrity: sha512-2oMML4wH9qWLnZPRxJm06ozwrVN/K+nkjqdI5/ofWWsrBnnH4iB9rRKrsV8px0nlWgZrwfdCH4g5RUiyyJHWSA==} + peerDependencies: + react: ^16 || ^17 || ^18 + vega: '*' + vega-lite: '*' + dependencies: + '@types/react': 18.2.52 + fast-deep-equal: 3.1.3 + prop-types: 15.8.1 + react: 18.2.0 + vega: 5.28.0 + vega-embed: 6.24.0(vega-lite@5.17.0)(vega@5.28.0) + vega-lite: 5.17.0(vega@5.28.0) + dev: false + /react@18.2.0: resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} engines: {node: '>=0.10.0'} @@ -17835,7 +17891,6 @@ packages: /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} - dev: true /require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} @@ -19036,6 +19091,13 @@ packages: engines: {node: '>=0.6'} dev: true + /topojson-client@3.1.0: + resolution: {integrity: sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==} + hasBin: true + dependencies: + commander: 2.20.3 + dev: false + /tough-cookie@4.1.3: resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} engines: {node: '>=6'} @@ -19844,6 +19906,390 @@ packages: engines: {node: '>= 0.8'} dev: true + /vega-canvas@1.2.7: + resolution: {integrity: sha512-OkJ9CACVcN9R5Pi9uF6MZBF06pO6qFpDYHWSKBJsdHP5o724KrsgR6UvbnXFH82FdsiTOff/HqjuaG8C7FL+9Q==} + dev: false + + /vega-crossfilter@4.1.1: + resolution: {integrity: sha512-yesvlMcwRwxrtAd9IYjuxWJJuAMI0sl7JvAFfYtuDkkGDtqfLXUcCzHIATqW6igVIE7tWwGxnbfvQLhLNgK44Q==} + dependencies: + d3-array: 3.2.4 + vega-dataflow: 5.7.5 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-dataflow@5.7.5: + resolution: {integrity: sha512-EdsIl6gouH67+8B0f22Owr2tKDiMPNNR8lEvJDcxmFw02nXd8juimclpLvjPQriqn6ta+3Dn5txqfD117H04YA==} + dependencies: + vega-format: 1.1.1 + vega-loader: 4.5.1 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-embed@6.24.0(vega-lite@5.17.0)(vega@5.28.0): + resolution: {integrity: sha512-ANCksO3lXhdLzQn7Mfistm1dsRwQhxTYICVpru7TMc+Ywe7C4vOLWuaVv9Qvem2IgQyuVCal0EoTMKvIVYykFg==} + peerDependencies: + vega: ^5.21.0 + vega-lite: '*' + dependencies: + fast-json-patch: 3.1.1 + json-stringify-pretty-compact: 3.0.0 + semver: 7.5.4 + tslib: 2.6.2 + vega: 5.28.0 + vega-interpreter: 1.0.5 + vega-lite: 5.17.0(vega@5.28.0) + vega-schema-url-parser: 2.2.0 + vega-themes: 2.14.0(vega-lite@5.17.0)(vega@5.28.0) + vega-tooltip: 0.34.0 + dev: false + bundledDependencies: + - yallist + + /vega-encode@4.9.2: + resolution: {integrity: sha512-c3J0LYkgYeXQxwnYkEzL15cCFBYPRaYUon8O2SZ6O4PhH4dfFTXBzSyT8+gh8AhBd572l2yGDfxpEYA6pOqdjg==} + dependencies: + d3-array: 3.2.4 + d3-interpolate: 3.0.1 + vega-dataflow: 5.7.5 + vega-scale: 7.3.1 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-event-selector@3.0.1: + resolution: {integrity: sha512-K5zd7s5tjr1LiOOkjGpcVls8GsH/f2CWCrWcpKy74gTCp+llCdwz0Enqo013ZlGaRNjfgD/o1caJRt3GSaec4A==} + dev: false + + /vega-expression@5.1.0: + resolution: {integrity: sha512-u8Rzja/cn2PEUkhQN3zUj3REwNewTA92ExrcASNKUJPCciMkHJEjESwFYuI6DWMCq4hQElQ92iosOAtwzsSTqA==} + dependencies: + '@types/estree': 1.0.1 + vega-util: 1.17.2 + dev: false + + /vega-force@4.2.0: + resolution: {integrity: sha512-aE2TlP264HXM1r3fl58AvZdKUWBNOGkIvn4EWyqeJdgO2vz46zSU7x7TzPG4ZLuo44cDRU5Ng3I1eQk23Asz6A==} + dependencies: + d3-force: 3.0.0 + vega-dataflow: 5.7.5 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-format@1.1.1: + resolution: {integrity: sha512-Rll7YgpYbsgaAa54AmtEWrxaJqgOh5fXlvM2wewO4trb9vwM53KBv4Q/uBWCLK3LLGeBXIF6gjDt2LFuJAUtkQ==} + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-time-format: 4.1.0 + vega-time: 2.1.1 + vega-util: 1.17.2 + dev: false + + /vega-functions@5.14.0: + resolution: {integrity: sha512-Q0rocHmJDfQ0tS91kdN8WcEosq1e3HPK1Yf5z36SPYPmTzKw3uxUGE52tLxC832acAYqPmi8R41wAoI/yFQTPg==} + dependencies: + d3-array: 3.2.4 + d3-color: 3.1.0 + d3-geo: 3.1.0 + vega-dataflow: 5.7.5 + vega-expression: 5.1.0 + vega-scale: 7.3.1 + vega-scenegraph: 4.11.2 + vega-selections: 5.4.2 + vega-statistics: 1.9.0 + vega-time: 2.1.1 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-geo@4.4.1: + resolution: {integrity: sha512-s4WeZAL5M3ZUV27/eqSD3v0FyJz3PlP31XNSLFy4AJXHxHUeXT3qLiDHoVQnW5Om+uBCPDtTT1ROx1smGIf2aA==} + dependencies: + d3-array: 3.2.4 + d3-color: 3.1.0 + d3-geo: 3.1.0 + vega-canvas: 1.2.7 + vega-dataflow: 5.7.5 + vega-projection: 1.6.0 + vega-statistics: 1.9.0 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-hierarchy@4.1.1: + resolution: {integrity: sha512-h5mbrDtPKHBBQ9TYbvEb/bCqmGTlUX97+4CENkyH21tJs7naza319B15KRK0NWOHuhbGhFmF8T0696tg+2c8XQ==} + dependencies: + d3-hierarchy: 3.1.2 + vega-dataflow: 5.7.5 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-interpreter@1.0.5: + resolution: {integrity: sha512-po6oTOmeQqr1tzTCdD15tYxAQLeUnOVirAysgVEemzl+vfmvcEP7jQmlc51jz0jMA+WsbmE6oJywisQPu/H0Bg==} + dev: false + + /vega-label@1.2.1: + resolution: {integrity: sha512-n/ackJ5lc0Xs9PInCaGumYn2awomPjJ87EMVT47xNgk2bHmJoZV1Ve/1PUM6Eh/KauY211wPMrNp/9Im+7Ripg==} + dependencies: + vega-canvas: 1.2.7 + vega-dataflow: 5.7.5 + vega-scenegraph: 4.11.2 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-lite@5.17.0(vega@5.28.0): + resolution: {integrity: sha512-PPm1HRdDFDdl2fga3cHm3lHjJV/xcB+Cn77xe7Av1yRLY1GMbPaJS42s+e7XHGmbeDee+H/KK9lUdQK28xs7nA==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + vega: ^5.24.0 + dependencies: + json-stringify-pretty-compact: 3.0.0 + tslib: 2.6.2 + vega: 5.28.0 + vega-event-selector: 3.0.1 + vega-expression: 5.1.0 + vega-util: 1.17.2 + yargs: 17.7.2 + dev: false + + /vega-loader@4.5.1: + resolution: {integrity: sha512-qy5x32SaT0YkEujQM2yKqvLGV9XWQ2aEDSugBFTdYzu/1u4bxdUSRDREOlrJ9Km3RWIOgFiCkobPmFxo47SKuA==} + dependencies: + d3-dsv: 3.0.1 + node-fetch: 2.7.0 + topojson-client: 3.1.0 + vega-format: 1.1.1 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-parser@6.3.0: + resolution: {integrity: sha512-swS5RuP2imRarMpGWaAZusoKkXc4Z5WxWx349pkqxIAf4F7H8Ya9nThEkSWsFozd75O9nWh0QLifds8Xb7KjUg==} + dependencies: + vega-dataflow: 5.7.5 + vega-event-selector: 3.0.1 + vega-functions: 5.14.0 + vega-scale: 7.3.1 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-projection@1.6.0: + resolution: {integrity: sha512-LGUaO/kpOEYuTlul+x+lBzyuL9qmMwP1yShdUWYLW+zXoeyGbs5OZW+NbPPwLYqJr5lpXDr/vGztFuA/6g2xvQ==} + dependencies: + d3-geo: 3.1.0 + d3-geo-projection: 4.0.0 + vega-scale: 7.3.1 + dev: false + + /vega-regression@1.2.0: + resolution: {integrity: sha512-6TZoPlhV/280VbxACjRKqlE0Nv48z5g4CSNf1FmGGTWS1rQtElPTranSoVW4d7ET5eVQ6f9QLxNAiALptvEq+g==} + dependencies: + d3-array: 3.2.4 + vega-dataflow: 5.7.5 + vega-statistics: 1.9.0 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-runtime@6.1.4: + resolution: {integrity: sha512-0dDYXyFLQcxPQ2OQU0WuBVYLRZnm+/CwVu6i6N4idS7R9VXIX5581EkCh3pZ20pQ/+oaA7oJ0pR9rJgJ6rukRQ==} + dependencies: + vega-dataflow: 5.7.5 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-scale@7.3.1: + resolution: {integrity: sha512-tyTlaaCpHN2Ik/PPKl/j9ThadBDjPtypqW1D7IsUSkzfoZ7RPlI2jwAaoj2C/YW5jFRbEOx3njmjogp48I5CvA==} + dependencies: + d3-array: 3.2.4 + d3-interpolate: 3.0.1 + d3-scale: 4.0.2 + vega-time: 2.1.1 + vega-util: 1.17.2 + dev: false + + /vega-scenegraph@4.11.2: + resolution: {integrity: sha512-PXSvv/L7Ek+9mwOTPLpzgkXdfGCR+AcWV5aquPGrqCWoiIF49VJkKFNT1HWxj3RZJX0XKo2r7SuXvRBb9EJ1aA==} + dependencies: + d3-path: 3.1.0 + d3-shape: 3.2.0 + vega-canvas: 1.2.7 + vega-loader: 4.5.1 + vega-scale: 7.3.1 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-schema-url-parser@2.2.0: + resolution: {integrity: sha512-yAtdBnfYOhECv9YC70H2gEiqfIbVkq09aaE4y/9V/ovEFmH9gPKaEgzIZqgT7PSPQjKhsNkb6jk6XvSoboxOBw==} + dev: false + + /vega-selections@5.4.2: + resolution: {integrity: sha512-99FUhYmg0jOJr2/K4TcEURmJRkuibrCDc8KBUX7qcQEITzrZ5R6a4QE+sarCvbb3hi8aA9GV2oyST6MQeA9mgQ==} + dependencies: + d3-array: 3.2.4 + vega-expression: 5.1.0 + vega-util: 1.17.2 + dev: false + + /vega-statistics@1.9.0: + resolution: {integrity: sha512-GAqS7mkatpXcMCQKWtFu1eMUKLUymjInU0O8kXshWaQrVWjPIO2lllZ1VNhdgE0qGj4oOIRRS11kzuijLshGXQ==} + dependencies: + d3-array: 3.2.4 + dev: false + + /vega-themes@2.14.0(vega-lite@5.17.0)(vega@5.28.0): + resolution: {integrity: sha512-9dLmsUER7gJrDp8SEYKxBFmXmpyzLlToKIjxq3HCvYjz8cnNrRGyAhvIlKWOB3ZnGvfYV+vnv3ZRElSNL31nkA==} + peerDependencies: + vega: '*' + vega-lite: '*' + dependencies: + vega: 5.28.0 + vega-lite: 5.17.0(vega@5.28.0) + dev: false + + /vega-time@2.1.1: + resolution: {integrity: sha512-z1qbgyX0Af2kQSGFbApwBbX2meenGvsoX8Nga8uyWN8VIbiySo/xqizz1KrP6NbB6R+x5egKmkjdnyNThPeEWA==} + dependencies: + d3-array: 3.2.4 + d3-time: 3.1.0 + vega-util: 1.17.2 + dev: false + + /vega-tooltip@0.34.0: + resolution: {integrity: sha512-TtxwkcLZ5aWQTvKGlfWDou8tISGuxmqAW1AgGZjrDpf75qsXvgtbPdRAAls2LZMqDxpr5T1kMEZs9XbSpiI8yw==} + dependencies: + vega-util: 1.17.2 + dev: false + + /vega-transforms@4.11.1: + resolution: {integrity: sha512-DDbqEQnvy9/qEvv0bAKPqAuzgaNb7Lh2xKJFom2Yzx4tZHCl8dnKxC1lH9JnJlAMdtZuiNLPARUkf3pCNQ/olw==} + dependencies: + d3-array: 3.2.4 + vega-dataflow: 5.7.5 + vega-statistics: 1.9.0 + vega-time: 2.1.1 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-typings@1.1.0: + resolution: {integrity: sha512-uI6RWlMiGRhsgmw/LzJtjCc0kwhw2f0JpyNMTAnOy90kE4e4CiaZN5nJp8S9CcfcBoPEZHc166AOn2SSNrKn3A==} + dependencies: + '@types/geojson': 7946.0.4 + vega-event-selector: 3.0.1 + vega-expression: 5.1.0 + vega-util: 1.17.2 + dev: false + + /vega-util@1.17.2: + resolution: {integrity: sha512-omNmGiZBdjm/jnHjZlywyYqafscDdHaELHx1q96n5UOz/FlO9JO99P4B3jZg391EFG8dqhWjQilSf2JH6F1mIw==} + dev: false + + /vega-view-transforms@4.5.9: + resolution: {integrity: sha512-NxEq4ZD4QwWGRrl2yDLnBRXM9FgCI+vvYb3ZC2+nVDtkUxOlEIKZsMMw31op5GZpfClWLbjCT3mVvzO2xaTF+g==} + dependencies: + vega-dataflow: 5.7.5 + vega-scenegraph: 4.11.2 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-view@5.12.0: + resolution: {integrity: sha512-T3GY7UJNVZGrCUrAmE/OCrkoJQyOT/2dCgXgy9EvDMVv/sdrn7o1TMKhSV18nIr0m5A7m4mgKwrmguAfROY85g==} + dependencies: + d3-array: 3.2.4 + d3-timer: 3.0.1 + vega-dataflow: 5.7.5 + vega-format: 1.1.1 + vega-functions: 5.14.0 + vega-runtime: 6.1.4 + vega-scenegraph: 4.11.2 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-voronoi@4.2.2: + resolution: {integrity: sha512-Bq2YOp2MGphhQnUuLwl3dsyBs6MuEU86muTjDbBJg33+HkZtE1kIoQZr+EUHa46NBsY1NzSKddOTu8wcaFrWiQ==} + dependencies: + d3-delaunay: 6.0.2 + vega-dataflow: 5.7.5 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega-wordcloud@4.1.4: + resolution: {integrity: sha512-oeZLlnjiusLAU5vhk0IIdT5QEiJE0x6cYoGNq1th+EbwgQp153t4r026fcib9oq15glHFOzf81a8hHXHSJm1Jw==} + dependencies: + vega-canvas: 1.2.7 + vega-dataflow: 5.7.5 + vega-scale: 7.3.1 + vega-statistics: 1.9.0 + vega-util: 1.17.2 + transitivePeerDependencies: + - encoding + dev: false + + /vega@5.28.0: + resolution: {integrity: sha512-5EDVhjBUgcVdrA6LZDBLah/nuk4FRUwZqTgP/Yi32qeRCoiN0xkptQ5Sbmj6XfH7wu1SdbAbsCm1Zls+9NC/8Q==} + dependencies: + vega-crossfilter: 4.1.1 + vega-dataflow: 5.7.5 + vega-encode: 4.9.2 + vega-event-selector: 3.0.1 + vega-expression: 5.1.0 + vega-force: 4.2.0 + vega-format: 1.1.1 + vega-functions: 5.14.0 + vega-geo: 4.4.1 + vega-hierarchy: 4.1.1 + vega-label: 1.2.1 + vega-loader: 4.5.1 + vega-parser: 6.3.0 + vega-projection: 1.6.0 + vega-regression: 1.2.0 + vega-runtime: 6.1.4 + vega-scale: 7.3.1 + vega-scenegraph: 4.11.2 + vega-statistics: 1.9.0 + vega-time: 2.1.1 + vega-transforms: 4.11.1 + vega-typings: 1.1.0 + vega-util: 1.17.2 + vega-view: 5.12.0 + vega-view-transforms: 4.5.9 + vega-voronoi: 4.2.2 + vega-wordcloud: 4.1.4 + transitivePeerDependencies: + - encoding + dev: false + /vfile-location@5.0.2: resolution: {integrity: sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==} dependencies: @@ -20344,7 +20790,6 @@ packages: /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - dev: true /yallist@2.1.2: resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} @@ -20378,7 +20823,6 @@ packages: /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - dev: true /yargs@15.4.1: resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} @@ -20408,7 +20852,6 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - dev: true /yauzl@2.10.0: resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} From b5db163ddf1e0ad9b763d755b779bc99243e1b2c Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Thu, 28 Mar 2024 11:49:04 -0700 Subject: [PATCH 2/9] Initial integration of Vega Plot --- .../SquiggleChart/VegaPlot.stories.tsx | 42 +++++++ .../src/widgets/DistWidget/index.tsx | 102 ++------------- .../src/widgets/PlotWidget/index.tsx | 116 ++++-------------- .../src/widgets/PlotWidget/test.tsx | 0 packages/squiggle-lang/src/fr/plot.ts | 53 ++++++++ .../src/library/registry/frTypes.ts | 33 +++++ .../src/public/SqValue/SqPlot.ts | 17 ++- .../squiggle-lang/src/public/SqValue/index.ts | 1 + packages/squiggle-lang/src/value/VPlot.ts | 7 ++ packages/squiggle-lang/src/value/VVoid.ts | 4 + packages/squiggle-lang/src/value/index.ts | 3 +- .../squiggle-lang/src/value/simpleValue.ts | 62 ++++++---- 12 files changed, 226 insertions(+), 214 deletions(-) create mode 100644 packages/components/src/stories/SquiggleChart/VegaPlot.stories.tsx create mode 100644 packages/components/src/widgets/PlotWidget/test.tsx diff --git a/packages/components/src/stories/SquiggleChart/VegaPlot.stories.tsx b/packages/components/src/stories/SquiggleChart/VegaPlot.stories.tsx new file mode 100644 index 0000000000..22fbedd605 --- /dev/null +++ b/packages/components/src/stories/SquiggleChart/VegaPlot.stories.tsx @@ -0,0 +1,42 @@ +import type { Meta, StoryObj } from "@storybook/react"; + +import { SquiggleChart } from "../../components/SquiggleChart.js"; + +const meta = { + component: SquiggleChart, +} satisfies Meta; +export default meta; +type Story = StoryObj; + +export const Basic: Story = { + args: { + code: ` + Plot.vega( + { + data: { + values: [ + { date: "2010-01-01", value: 28 }, + { date: "2010-03-01", value: 33 }, + { date: "2010-05-01", value: 41 }, + { date: "2010-07-01", value: 37 }, + { date: "2010-09-01", value: 29 }, + { date: "2010-11-01", value: 35 }, + { date: "2011-01-01", value: 43 }, + { date: "2011-05-01", value: 56 }, + { date: "2011-07-01", value: 62 }, + ], + }, + spec: { + width: "container", + height: 300, + mark: { type: "line", point: true }, + encoding: { + x: { field: "date", type: "temporal", timeUnit: "year" }, + y: { field: "value", type: "quantitative" }, + }, + }, + } + ) + `, + }, +}; diff --git a/packages/components/src/widgets/DistWidget/index.tsx b/packages/components/src/widgets/DistWidget/index.tsx index 2827b62169..977eb57b8b 100644 --- a/packages/components/src/widgets/DistWidget/index.tsx +++ b/packages/components/src/widgets/DistWidget/index.tsx @@ -1,5 +1,3 @@ -import { Vega } from "react-vega"; - import { SqDistributionsPlot, SqScale } from "@quri/squiggle-lang"; import { generateDistributionPlotSettings } from "../../components/PlaygroundSettings.js"; @@ -15,93 +13,6 @@ import { DistributionsChart } from "./DistributionsChart.js"; // Note that for distributions, this only applies to the internals, there's also extra margin and details. export const CHART_TO_DIST_HEIGHT_ADJUSTMENT = 0.55; -const foo = ( - -); - widgetRegistry.register("Dist", { Preview(value) { const dist = value.value; @@ -169,11 +80,12 @@ widgetRegistry.register("Dist", { ), }); - return foo; - // + return ( + + ); }, }); diff --git a/packages/components/src/widgets/PlotWidget/index.tsx b/packages/components/src/widgets/PlotWidget/index.tsx index bf941ec586..f1d978fce5 100644 --- a/packages/components/src/widgets/PlotWidget/index.tsx +++ b/packages/components/src/widgets/PlotWidget/index.tsx @@ -1,97 +1,14 @@ -import { Vega } from "react-vega"; +import { Vega, VisualizationSpec } from "react-vega"; +import { DistributionsChart } from "../DistWidget/DistributionsChart.js"; +import { CHART_TO_DIST_HEIGHT_ADJUSTMENT } from "../DistWidget/index.js"; import { DistFunctionChart } from "../LambdaWidget/FunctionChart/DistFunctionChart.js"; import { NumericFunctionChart } from "../LambdaWidget/FunctionChart/NumericFunctionChart.js"; import { widgetRegistry } from "../registry.js"; import { RelativeValuesGridChart } from "./RelativeValuesGridChart/index.js"; import { ScatterChart } from "./ScatterChart/index.js"; -const foo = ( - -); +const vega = (spec: VisualizationSpec) => ; widgetRegistry.register("Plot", { Chart: (value, settings) => { @@ -99,13 +16,15 @@ widgetRegistry.register("Plot", { const environment = value.context.project.getEnvironment(); switch (plot.tag) { - case "distributions": - return foo; - // + case "distributions": { + return ( + + ); + } case "numericFn": { return ( ); + case "vega": { + const data = { + width: "container", + height: 300, + data: JSON.parse(plot.data), + ...JSON.parse(plot.spec), + }; + return vega(data); + } default: // can happen if squiggle-lang version is too fresh and we messed up the components -> squiggle-lang dependency return `Unsupported plot ${plot satisfies never}`; diff --git a/packages/components/src/widgets/PlotWidget/test.tsx b/packages/components/src/widgets/PlotWidget/test.tsx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/squiggle-lang/src/fr/plot.ts b/packages/squiggle-lang/src/fr/plot.ts index 11c35f5322..932076735e 100644 --- a/packages/squiggle-lang/src/fr/plot.ts +++ b/packages/squiggle-lang/src/fr/plot.ts @@ -4,6 +4,7 @@ import { REArgumentError, REOther } from "../errors/messages.js"; import { makeFnExample } from "../library/registry/core.js"; import { makeDefinition } from "../library/registry/fnDefinition.js"; import { + frAny, frArray, frBool, frDeprecated, @@ -27,6 +28,7 @@ import { } from "../library/registry/helpers.js"; import { Lambda } from "../reducer/lambda.js"; import { clamp, sort, uniq } from "../utility/E_A_Floats.js"; +import { simpleValueFromValue } from "../value/simpleValue.js"; import { VDomain } from "../value/VDomain.js"; import { LabeledDistribution, Plot } from "../value/VPlot.js"; import { Scale } from "../value/VScale.js"; @@ -549,4 +551,55 @@ Plot.scatter({ ), ], }), + maker.make({ + name: "vega", + output: "Plot", + examples: [ + makeFnExample( + `xDist = SampleSet.fromDist(2 to 5) +yDist = normal({p5:-3, p95:3}) * 5 - xDist ^ 2 +Plot.scatter({ + xDist: xDist, + yDist: yDist, + xScale: Scale.log({min: 1.5}), +})`, + { isInteractive: true } + ), + makeFnExample( + `xDist = SampleSet.fromDist(normal({p5:-2, p95:5})) +yDist = normal({p5:-3, p95:3}) * 5 - xDist +Plot.scatter({ + xDist: xDist, + yDist: yDist, + xScale: Scale.symlog({title: "X Axis Title"}), + yScale: Scale.symlog({title: "Y Axis Title"}), +})`, + { isInteractive: true } + ), + ], + definitions: [ + makeDefinition( + [ + frDict( + ["spec", frAny()], + ["data", frAny()], + ["config", frOptional(frAny())], + ["mark", frOptional(frAny())], + ["encoding", frOptional(frAny())], + ["height", frOptional(frAny())], + ["view", frOptional(frAny())], + ["projection", frOptional(frAny())] + ), + ], + frPlot, + ([{ spec, data }]) => { + return { + type: "vega", + spec: simpleValueFromValue(spec, true), + data: simpleValueFromValue(data, true), + }; + } + ), + ], + }), ]; diff --git a/packages/squiggle-lang/src/library/registry/frTypes.ts b/packages/squiggle-lang/src/library/registry/frTypes.ts index e81a9f9c6d..bc773604c2 100644 --- a/packages/squiggle-lang/src/library/registry/frTypes.ts +++ b/packages/squiggle-lang/src/library/registry/frTypes.ts @@ -508,6 +508,39 @@ export function frDict< [k in K4]: T4; } & { [k in K5]: T5 } & { [k in K6]: T6 } & { [k in K7]: T7 } >; +export function frDict< + K1 extends string, + T1, + K2 extends string, + T2, + K3 extends string, + T3, + K4 extends string, + T4, + K5 extends string, + T5, + K6 extends string, + T6, + K7 extends string, + T7, + K8 extends string, + T8, +>( + kv1: [K1, FRType], + kv2: [K2, FRType], + kv3: [K3, FRType], + kv4: [K4, FRType], + kv5: [K5, FRType], + kv6: [K6, FRType], + kv7: [K7, FRType], + kv8: [K8, FRType] +): FRType< + { [k in K1]: T1 } & { [k in K2]: T2 } & { [k in K3]: T3 } & { + [k in K4]: T4; + } & { [k in K5]: T5 } & { [k in K6]: T6 } & { + [k in K7]: T7 & { [k in K8]: T8 }; + } +>; export function frDict( ...allKvs: [string, FRType][] diff --git a/packages/squiggle-lang/src/public/SqValue/SqPlot.ts b/packages/squiggle-lang/src/public/SqValue/SqPlot.ts index af20af99f0..2dfaacaa98 100644 --- a/packages/squiggle-lang/src/public/SqValue/SqPlot.ts +++ b/packages/squiggle-lang/src/public/SqValue/SqPlot.ts @@ -28,6 +28,8 @@ export function wrapPlot(value: Plot, context?: SqValueContext): SqPlot { return new SqScatterPlot(value, context); case "relativeValues": return new SqRelativeValuesPlot(value, context); + case "vega": + return new SqVegaPlot(value, context); } } @@ -304,9 +306,22 @@ export class SqRelativeValuesPlot extends SqAbstractPlot<"relativeValues"> { } } +export class SqVegaPlot extends SqAbstractPlot<"vega"> { + tag = "vega" as const; + + get spec(): any { + return JSON.stringify(this._value.spec); + } + + get data(): any { + return JSON.stringify(this._value.data); + } +} + export type SqPlot = | SqDistributionsPlot | SqNumericFnPlot | SqDistFnPlot | SqScatterPlot - | SqRelativeValuesPlot; + | SqRelativeValuesPlot + | SqVegaPlot; diff --git a/packages/squiggle-lang/src/public/SqValue/index.ts b/packages/squiggle-lang/src/public/SqValue/index.ts index b412def610..ca0e18561e 100644 --- a/packages/squiggle-lang/src/public/SqValue/index.ts +++ b/packages/squiggle-lang/src/public/SqValue/index.ts @@ -337,6 +337,7 @@ export class SqPlotValue extends SqAbstractValue<"Plot", unknown, SqPlot> { return valueToJSON(this._value); } } + export class SqTableChartValue extends SqAbstractValue< "TableChart", unknown, diff --git a/packages/squiggle-lang/src/value/VPlot.ts b/packages/squiggle-lang/src/value/VPlot.ts index 21ecc235bd..68e607d7e2 100644 --- a/packages/squiggle-lang/src/value/VPlot.ts +++ b/packages/squiggle-lang/src/value/VPlot.ts @@ -53,6 +53,11 @@ export type Plot = CommonPlotArgs & fn: Lambda; ids: readonly string[]; } + | { + type: "vega"; + spec: any; + data: any; + } ); export class VPlot extends BaseValue implements Indexable { @@ -76,6 +81,8 @@ export class VPlot extends BaseValue implements Indexable { return `Scatter plot for distributions ${this.value.xDist} and ${this.value.yDist}`; case "relativeValues": return `Plot for relative values ${this.value.ids.join(", ")}`; + case "vega": + return `Vega plot`; } } diff --git a/packages/squiggle-lang/src/value/VVoid.ts b/packages/squiggle-lang/src/value/VVoid.ts index faf06ec505..f972c43dcb 100644 --- a/packages/squiggle-lang/src/value/VVoid.ts +++ b/packages/squiggle-lang/src/value/VVoid.ts @@ -10,6 +10,10 @@ export class VVoid extends BaseValue { valueToString() { return "()"; } + + isEqual(other: VVoid) { + return true; + } } export const vVoid = () => new VVoid(); diff --git a/packages/squiggle-lang/src/value/index.ts b/packages/squiggle-lang/src/value/index.ts index a806ac749a..96ce85b797 100644 --- a/packages/squiggle-lang/src/value/index.ts +++ b/packages/squiggle-lang/src/value/index.ts @@ -71,9 +71,8 @@ export function isEqual(a: Value, b: Value): boolean { case "Array": case "Specification": case "Dict": - return a.isEqual(b as any); case "Void": - return true; + return a.isEqual(b as any); } if (a.toString() !== b.toString()) { diff --git a/packages/squiggle-lang/src/value/simpleValue.ts b/packages/squiggle-lang/src/value/simpleValue.ts index 3273b98220..99667a6de0 100644 --- a/packages/squiggle-lang/src/value/simpleValue.ts +++ b/packages/squiggle-lang/src/value/simpleValue.ts @@ -102,7 +102,10 @@ export function simpleValueFromAny(data: any): SimpleValue { return toPlainObject(data); } -export function simpleValueFromValue(value: Value): SimpleValue { +export function simpleValueFromValue( + value: Value, + jsonMode?: boolean +): SimpleValue { switch (value.type) { case "Bool": case "Number": @@ -114,16 +117,23 @@ export function simpleValueFromValue(value: Value): SimpleValue { case "Void": return null; case "Array": - return value.value.map(simpleValueFromValue); + return value.value.map((e) => simpleValueFromValue(e, jsonMode)); case "Dict": { const v: SimpleValue = ImmutableMap( - [...value.value.entries()].map(([k, v]) => [k, simpleValueFromValue(v)]) + [...value.value.entries()].map(([k, v]) => [ + k, + simpleValueFromValue(v, jsonMode), + ]) ); - const fields: [string, SimpleValue][] = [ - ["vtype", "Dict"], - ["value", v], - ]; - return ImmutableMap(fields); + if (jsonMode) { + return v; + } else { + const fields: [string, SimpleValue][] = [ + ["vtype", "Dict"], + ["value", v], + ]; + return ImmutableMap(fields); + } } case "Calculator": { const fields: [string, SimpleValue][] = [ @@ -131,7 +141,9 @@ export function simpleValueFromValue(value: Value): SimpleValue { ["fn", value.value.fn], [ "inputs", - value.value.inputs.map((x) => simpleValueFromValue(vInput(x))), + value.value.inputs.map((x) => + simpleValueFromValue(vInput(x), jsonMode) + ), ], ["autorun", value.value.autorun], ["description", value.value.description || ""], @@ -161,17 +173,20 @@ export function simpleValueFromValue(value: Value): SimpleValue { value.value.distributions.map((x) => ImmutableMap([ ["name", x.name || ""], - ["distribution", simpleValueFromValue(vDist(x.distribution))], + [ + "distribution", + simpleValueFromValue(vDist(x.distribution), jsonMode), + ], ]) ), ]); fields.push([ "xScale", - simpleValueFromValue(vScale(value.value.xScale)), + simpleValueFromValue(vScale(value.value.xScale), jsonMode), ]); fields.push([ "yScale", - simpleValueFromValue(vScale(value.value.yScale)), + simpleValueFromValue(vScale(value.value.yScale), jsonMode), ]); fields.push(["showSummary", value.value.showSummary]); break; @@ -179,11 +194,11 @@ export function simpleValueFromValue(value: Value): SimpleValue { fields.push(["fn", value.value.fn]); fields.push([ "xScale", - simpleValueFromValue(vScale(value.value.xScale)), + simpleValueFromValue(vScale(value.value.xScale), jsonMode), ]); fields.push([ "yScale", - simpleValueFromValue(vScale(value.value.yScale)), + simpleValueFromValue(vScale(value.value.yScale), jsonMode), ]); if (value.value.xPoints) { fields.push(["points", value.value.xPoints]); @@ -193,15 +208,15 @@ export function simpleValueFromValue(value: Value): SimpleValue { fields.push(["fn", value.value.fn]); fields.push([ "xScale", - simpleValueFromValue(vScale(value.value.xScale)), + simpleValueFromValue(vScale(value.value.xScale), jsonMode), ]); fields.push([ "yScale", - simpleValueFromValue(vScale(value.value.yScale)), + simpleValueFromValue(vScale(value.value.yScale), jsonMode), ]); fields.push([ "distXScale", - simpleValueFromValue(vScale(value.value.distXScale)), + simpleValueFromValue(vScale(value.value.distXScale), jsonMode), ]); if (value.value.xPoints) { fields.push(["points", value.value.xPoints]); @@ -210,19 +225,19 @@ export function simpleValueFromValue(value: Value): SimpleValue { case "scatter": fields.push([ "xDist", - simpleValueFromValue(vDist(value.value.xDist)), + simpleValueFromValue(vDist(value.value.xDist), jsonMode), ]); fields.push([ "yDist", - simpleValueFromValue(vDist(value.value.yDist)), + simpleValueFromValue(vDist(value.value.yDist), jsonMode), ]); fields.push([ "xScale", - simpleValueFromValue(vScale(value.value.xScale)), + simpleValueFromValue(vScale(value.value.xScale), jsonMode), ]); fields.push([ "yScale", - simpleValueFromValue(vScale(value.value.yScale)), + simpleValueFromValue(vScale(value.value.yScale), jsonMode), ]); break; case "relativeValues": @@ -235,7 +250,10 @@ export function simpleValueFromValue(value: Value): SimpleValue { case "TableChart": { const fields: [string, SimpleValue][] = [ ["vType", "TableChart"], - ["data", value.value.data.map(simpleValueFromValue)], + [ + "data", + value.value.data.map((e) => simpleValueFromValue(e, jsonMode)), + ], [ "columns", value.value.columns.map((column) => { From c69c27b888a624632998e913a6e0872f66f860bd Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 30 Mar 2024 07:46:36 -0700 Subject: [PATCH 3/9] Added formal Vega type --- .../SquiggleChart/VegaPlot.stories.tsx | 50 +++++++++---------- .../src/widgets/PlotWidget/index.tsx | 7 +-- packages/squiggle-lang/src/fr/plot.ts | 12 +++-- .../src/public/SqValue/SqPlot.ts | 13 +++-- packages/squiggle-lang/src/value/VPlot.ts | 17 +++++-- .../squiggle-lang/src/value/simpleValue.ts | 30 +++++++++++ 6 files changed, 82 insertions(+), 47 deletions(-) diff --git a/packages/components/src/stories/SquiggleChart/VegaPlot.stories.tsx b/packages/components/src/stories/SquiggleChart/VegaPlot.stories.tsx index 22fbedd605..26bc3c7647 100644 --- a/packages/components/src/stories/SquiggleChart/VegaPlot.stories.tsx +++ b/packages/components/src/stories/SquiggleChart/VegaPlot.stories.tsx @@ -11,32 +11,28 @@ type Story = StoryObj; export const Basic: Story = { args: { code: ` - Plot.vega( - { - data: { - values: [ - { date: "2010-01-01", value: 28 }, - { date: "2010-03-01", value: 33 }, - { date: "2010-05-01", value: 41 }, - { date: "2010-07-01", value: 37 }, - { date: "2010-09-01", value: 29 }, - { date: "2010-11-01", value: 35 }, - { date: "2011-01-01", value: 43 }, - { date: "2011-05-01", value: 56 }, - { date: "2011-07-01", value: 62 }, - ], - }, - spec: { - width: "container", - height: 300, - mark: { type: "line", point: true }, - encoding: { - x: { field: "date", type: "temporal", timeUnit: "year" }, - y: { field: "value", type: "quantitative" }, - }, - }, - } - ) - `, +Plot.vega( + { + data: { + values: [ + { date: "2010-01-01", value: 50 }, + { date: "2010-03-01", value: 33 }, + { date: "2010-05-01", value: 41 }, + { date: "2010-07-01", value: 37 }, + { date: "2010-09-01", value: 29 }, + { date: "2010-11-01", value: 35 }, + { date: "2011-01-01", value: 43 }, + { date: "2011-05-01", value: 56 }, + { date: "2011-07-01", value: 62 }, + ], + }, + mark: { type: "line", point: true }, + encoding: { + x: { field: "date", type: "temporal", timeUnit: "year" }, + y: { field: "value", type: "quantitative" }, + }, + } + ) +`, }, }; diff --git a/packages/components/src/widgets/PlotWidget/index.tsx b/packages/components/src/widgets/PlotWidget/index.tsx index f1d978fce5..16159d4136 100644 --- a/packages/components/src/widgets/PlotWidget/index.tsx +++ b/packages/components/src/widgets/PlotWidget/index.tsx @@ -62,12 +62,7 @@ widgetRegistry.register("Plot", { ); case "vega": { - const data = { - width: "container", - height: 300, - data: JSON.parse(plot.data), - ...JSON.parse(plot.spec), - }; + const data = JSON.parse(plot.spec); return vega(data); } default: diff --git a/packages/squiggle-lang/src/fr/plot.ts b/packages/squiggle-lang/src/fr/plot.ts index 932076735e..102eedb7dc 100644 --- a/packages/squiggle-lang/src/fr/plot.ts +++ b/packages/squiggle-lang/src/fr/plot.ts @@ -581,22 +581,26 @@ Plot.scatter({ makeDefinition( [ frDict( - ["spec", frAny()], ["data", frAny()], + ["height", frOptional(frNumber)], ["config", frOptional(frAny())], ["mark", frOptional(frAny())], ["encoding", frOptional(frAny())], - ["height", frOptional(frAny())], ["view", frOptional(frAny())], ["projection", frOptional(frAny())] ), ], frPlot, - ([{ spec, data }]) => { + ([{ data, config, mark, encoding, height, view, projection }]) => { return { type: "vega", - spec: simpleValueFromValue(spec, true), data: simpleValueFromValue(data, true), + config: config && simpleValueFromValue(config, true), + mark: mark && simpleValueFromValue(mark, true), + encoding: encoding && simpleValueFromValue(encoding, true), + height: height || undefined, + view: view && simpleValueFromValue(view, true), + projection: projection && simpleValueFromValue(projection, true), }; } ), diff --git a/packages/squiggle-lang/src/public/SqValue/SqPlot.ts b/packages/squiggle-lang/src/public/SqValue/SqPlot.ts index 2dfaacaa98..99d2b4de2a 100644 --- a/packages/squiggle-lang/src/public/SqValue/SqPlot.ts +++ b/packages/squiggle-lang/src/public/SqValue/SqPlot.ts @@ -1,4 +1,7 @@ +import fromPairs from "lodash/fromPairs.js"; + import { clamp, sort, uniq } from "../../utility/E_A_Floats.js"; +import { vegaPlotToSimpleValues } from "../../value/simpleValue.js"; import { Plot, vPlot } from "../../value/VPlot.js"; import { SqValueContext } from "../SqValueContext.js"; import { SqValuePathEdge } from "../SqValuePath.js"; @@ -310,11 +313,11 @@ export class SqVegaPlot extends SqAbstractPlot<"vega"> { tag = "vega" as const; get spec(): any { - return JSON.stringify(this._value.spec); - } - - get data(): any { - return JSON.stringify(this._value.data); + return JSON.stringify({ + width: "container", + height: 300, + ...fromPairs(vegaPlotToSimpleValues(this._value)), + }); } } diff --git a/packages/squiggle-lang/src/value/VPlot.ts b/packages/squiggle-lang/src/value/VPlot.ts index 68e607d7e2..980d4455c4 100644 --- a/packages/squiggle-lang/src/value/VPlot.ts +++ b/packages/squiggle-lang/src/value/VPlot.ts @@ -17,6 +17,17 @@ export type CommonPlotArgs = { title?: string; }; +export type VegaPlot = { + type: "vega"; + data: any; + config?: any; + mark?: any; + encoding?: any; + height?: number; + view?: any; + projection?: any; +}; + export type Plot = CommonPlotArgs & ( | { @@ -53,11 +64,7 @@ export type Plot = CommonPlotArgs & fn: Lambda; ids: readonly string[]; } - | { - type: "vega"; - spec: any; - data: any; - } + | VegaPlot ); export class VPlot extends BaseValue implements Indexable { diff --git a/packages/squiggle-lang/src/value/simpleValue.ts b/packages/squiggle-lang/src/value/simpleValue.ts index 99667a6de0..31c8edfc59 100644 --- a/packages/squiggle-lang/src/value/simpleValue.ts +++ b/packages/squiggle-lang/src/value/simpleValue.ts @@ -14,6 +14,7 @@ import { vDist } from "./VDist.js"; import { vInput } from "./VInput.js"; import { vLambda } from "./vLambda.js"; import { vNumber } from "./VNumber.js"; +import { VegaPlot } from "./VPlot.js"; import { vScale } from "./VScale.js"; import { vString } from "./VString.js"; import { vVoid } from "./VVoid.js"; @@ -102,6 +103,32 @@ export function simpleValueFromAny(data: any): SimpleValue { return toPlainObject(data); } +export function vegaPlotToSimpleValues( + value: VegaPlot +): [string, SimpleValue][] { + const fields: [string, SimpleValue][] = [["data", value.data]]; + if (value.config) { + fields.push(["config", value.config]); + } + if (value.mark) { + fields.push(["mark", value.mark]); + } + if (value.encoding) { + fields.push(["encoding", value.encoding]); + } + if (value.height) { + fields.push(["height", value.height]); + } + if (value.view) { + fields.push(["view", value.view]); + } + if (value.projection) { + fields.push(["projection", value.projection]); + } + console.log("FIELDS", fields); + return fields; +} + export function simpleValueFromValue( value: Value, jsonMode?: boolean @@ -244,6 +271,9 @@ export function simpleValueFromValue( fields.push(["fn", value.value.fn]); fields.push(["ids", [...value.value.ids]]); break; + case "vega": + fields.concat(vegaPlotToSimpleValues(value.value)); + break; } return ImmutableMap(fields); } From 04c0e8f8b076fb8cf5778cd97bfb8455e35018b3 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 30 Mar 2024 08:01:54 -0700 Subject: [PATCH 4/9] Lazy load Vega --- .../components/src/widgets/PlotWidget/index.tsx | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/components/src/widgets/PlotWidget/index.tsx b/packages/components/src/widgets/PlotWidget/index.tsx index 16159d4136..78d9f23c36 100644 --- a/packages/components/src/widgets/PlotWidget/index.tsx +++ b/packages/components/src/widgets/PlotWidget/index.tsx @@ -1,4 +1,5 @@ -import { Vega, VisualizationSpec } from "react-vega"; +import { lazy, Suspense } from "react"; +import { VisualizationSpec } from "react-vega"; import { DistributionsChart } from "../DistWidget/DistributionsChart.js"; import { CHART_TO_DIST_HEIGHT_ADJUSTMENT } from "../DistWidget/index.js"; @@ -8,7 +9,15 @@ import { widgetRegistry } from "../registry.js"; import { RelativeValuesGridChart } from "./RelativeValuesGridChart/index.js"; import { ScatterChart } from "./ScatterChart/index.js"; -const vega = (spec: VisualizationSpec) => ; +const VegaLazy = lazy(() => + import("react-vega").then((module) => ({ default: module.Vega })) +); + +const vega = (spec: VisualizationSpec) => ( + Loading...}> + + +); widgetRegistry.register("Plot", { Chart: (value, settings) => { @@ -62,8 +71,7 @@ widgetRegistry.register("Plot", { ); case "vega": { - const data = JSON.parse(plot.spec); - return vega(data); + return vega(JSON.parse(plot.spec)); } default: // can happen if squiggle-lang version is too fresh and we messed up the components -> squiggle-lang dependency From abffb571d5c03c3f4184e060dae02b7ec6bfa721 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 30 Mar 2024 08:19:32 -0700 Subject: [PATCH 5/9] Minor cleanup --- .../src/widgets/PlotWidget/index.tsx | 12 ++---- .../src/widgets/PlotWidget/test.tsx | 0 packages/squiggle-lang/src/fr/danger.ts | 4 +- .../squiggle-lang/src/public/SqValue/index.ts | 1 - .../squiggle-lang/src/value/simpleValue.ts | 42 ++++++++++--------- 5 files changed, 29 insertions(+), 30 deletions(-) delete mode 100644 packages/components/src/widgets/PlotWidget/test.tsx diff --git a/packages/components/src/widgets/PlotWidget/index.tsx b/packages/components/src/widgets/PlotWidget/index.tsx index 78d9f23c36..01249c9bff 100644 --- a/packages/components/src/widgets/PlotWidget/index.tsx +++ b/packages/components/src/widgets/PlotWidget/index.tsx @@ -25,7 +25,7 @@ widgetRegistry.register("Plot", { const environment = value.context.project.getEnvironment(); switch (plot.tag) { - case "distributions": { + case "distributions": return ( ); - } - case "numericFn": { + case "numericFn": return ( ); - } - case "distFn": { + case "distFn": return ( ); - } case "scatter": return ( ); - case "vega": { + case "vega": return vega(JSON.parse(plot.spec)); - } default: // can happen if squiggle-lang version is too fresh and we messed up the components -> squiggle-lang dependency return `Unsupported plot ${plot satisfies never}`; diff --git a/packages/components/src/widgets/PlotWidget/test.tsx b/packages/components/src/widgets/PlotWidget/test.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/squiggle-lang/src/fr/danger.ts b/packages/squiggle-lang/src/fr/danger.ts index 0a855ce409..936be92bb1 100644 --- a/packages/squiggle-lang/src/fr/danger.ts +++ b/packages/squiggle-lang/src/fr/danger.ts @@ -530,7 +530,7 @@ Note: The Poisson distribution is a discrete distribution. When representing thi ], definitions: [ makeDefinition([frAny()], frAny(), ([v]) => { - return simpleValueToValue(simpleValueFromValue(v)); + return simpleValueToValue(simpleValueFromValue(v, false)); }), ], }), @@ -548,7 +548,7 @@ Note: The Poisson distribution is a discrete distribution. When representing thi definitions: [ makeDefinition([frAny()], frString, ([v]) => { return JSON.stringify( - simpleValueToJson(removeLambdas(simpleValueFromValue(v))) + simpleValueToJson(removeLambdas(simpleValueFromValue(v, false))) ); }), ], diff --git a/packages/squiggle-lang/src/public/SqValue/index.ts b/packages/squiggle-lang/src/public/SqValue/index.ts index ca0e18561e..b412def610 100644 --- a/packages/squiggle-lang/src/public/SqValue/index.ts +++ b/packages/squiggle-lang/src/public/SqValue/index.ts @@ -337,7 +337,6 @@ export class SqPlotValue extends SqAbstractValue<"Plot", unknown, SqPlot> { return valueToJSON(this._value); } } - export class SqTableChartValue extends SqAbstractValue< "TableChart", unknown, diff --git a/packages/squiggle-lang/src/value/simpleValue.ts b/packages/squiggle-lang/src/value/simpleValue.ts index 31c8edfc59..469971b1da 100644 --- a/packages/squiggle-lang/src/value/simpleValue.ts +++ b/packages/squiggle-lang/src/value/simpleValue.ts @@ -125,13 +125,14 @@ export function vegaPlotToSimpleValues( if (value.projection) { fields.push(["projection", value.projection]); } - console.log("FIELDS", fields); return fields; } +// Normally this function adds "vtype" to dicts, to distinguish them from other types. +// However, if `simplifyForJson` is true, it will not add "vtype" to dicts. This is useful for deserializing JSON into the direct Squiggle-like objects. export function simpleValueFromValue( value: Value, - jsonMode?: boolean + simplifyForJson?: boolean ): SimpleValue { switch (value.type) { case "Bool": @@ -144,15 +145,15 @@ export function simpleValueFromValue( case "Void": return null; case "Array": - return value.value.map((e) => simpleValueFromValue(e, jsonMode)); + return value.value.map((e) => simpleValueFromValue(e, simplifyForJson)); case "Dict": { const v: SimpleValue = ImmutableMap( [...value.value.entries()].map(([k, v]) => [ k, - simpleValueFromValue(v, jsonMode), + simpleValueFromValue(v, simplifyForJson), ]) ); - if (jsonMode) { + if (simplifyForJson) { return v; } else { const fields: [string, SimpleValue][] = [ @@ -169,7 +170,7 @@ export function simpleValueFromValue( [ "inputs", value.value.inputs.map((x) => - simpleValueFromValue(vInput(x), jsonMode) + simpleValueFromValue(vInput(x), simplifyForJson) ), ], ["autorun", value.value.autorun], @@ -202,18 +203,18 @@ export function simpleValueFromValue( ["name", x.name || ""], [ "distribution", - simpleValueFromValue(vDist(x.distribution), jsonMode), + simpleValueFromValue(vDist(x.distribution), simplifyForJson), ], ]) ), ]); fields.push([ "xScale", - simpleValueFromValue(vScale(value.value.xScale), jsonMode), + simpleValueFromValue(vScale(value.value.xScale), simplifyForJson), ]); fields.push([ "yScale", - simpleValueFromValue(vScale(value.value.yScale), jsonMode), + simpleValueFromValue(vScale(value.value.yScale), simplifyForJson), ]); fields.push(["showSummary", value.value.showSummary]); break; @@ -221,11 +222,11 @@ export function simpleValueFromValue( fields.push(["fn", value.value.fn]); fields.push([ "xScale", - simpleValueFromValue(vScale(value.value.xScale), jsonMode), + simpleValueFromValue(vScale(value.value.xScale), simplifyForJson), ]); fields.push([ "yScale", - simpleValueFromValue(vScale(value.value.yScale), jsonMode), + simpleValueFromValue(vScale(value.value.yScale), simplifyForJson), ]); if (value.value.xPoints) { fields.push(["points", value.value.xPoints]); @@ -235,15 +236,18 @@ export function simpleValueFromValue( fields.push(["fn", value.value.fn]); fields.push([ "xScale", - simpleValueFromValue(vScale(value.value.xScale), jsonMode), + simpleValueFromValue(vScale(value.value.xScale), simplifyForJson), ]); fields.push([ "yScale", - simpleValueFromValue(vScale(value.value.yScale), jsonMode), + simpleValueFromValue(vScale(value.value.yScale), simplifyForJson), ]); fields.push([ "distXScale", - simpleValueFromValue(vScale(value.value.distXScale), jsonMode), + simpleValueFromValue( + vScale(value.value.distXScale), + simplifyForJson + ), ]); if (value.value.xPoints) { fields.push(["points", value.value.xPoints]); @@ -252,19 +256,19 @@ export function simpleValueFromValue( case "scatter": fields.push([ "xDist", - simpleValueFromValue(vDist(value.value.xDist), jsonMode), + simpleValueFromValue(vDist(value.value.xDist), simplifyForJson), ]); fields.push([ "yDist", - simpleValueFromValue(vDist(value.value.yDist), jsonMode), + simpleValueFromValue(vDist(value.value.yDist), simplifyForJson), ]); fields.push([ "xScale", - simpleValueFromValue(vScale(value.value.xScale), jsonMode), + simpleValueFromValue(vScale(value.value.xScale), simplifyForJson), ]); fields.push([ "yScale", - simpleValueFromValue(vScale(value.value.yScale), jsonMode), + simpleValueFromValue(vScale(value.value.yScale), simplifyForJson), ]); break; case "relativeValues": @@ -282,7 +286,7 @@ export function simpleValueFromValue( ["vType", "TableChart"], [ "data", - value.value.data.map((e) => simpleValueFromValue(e, jsonMode)), + value.value.data.map((e) => simpleValueFromValue(e, simplifyForJson)), ], [ "columns", From a7c289973ae789ded99164e6a50510d6620c92cf Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 30 Mar 2024 08:23:33 -0700 Subject: [PATCH 6/9] Added changeset --- .changeset/ninety-hotels-thank.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/ninety-hotels-thank.md diff --git a/.changeset/ninety-hotels-thank.md b/.changeset/ninety-hotels-thank.md new file mode 100644 index 0000000000..ab8c54918f --- /dev/null +++ b/.changeset/ninety-hotels-thank.md @@ -0,0 +1,6 @@ +--- +"@quri/squiggle-lang": patch +"@quri/squiggle-components": patch +--- + +Added Vega Plot option From 8b90390662bcb8aeba70ce366dd7b9291cc8c193 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 30 Mar 2024 08:28:26 -0700 Subject: [PATCH 7/9] Merged with main --- packages/squiggle-lang/src/fr/plot.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/squiggle-lang/src/fr/plot.ts b/packages/squiggle-lang/src/fr/plot.ts index 54b4540f02..b7d4edceb3 100644 --- a/packages/squiggle-lang/src/fr/plot.ts +++ b/packages/squiggle-lang/src/fr/plot.ts @@ -548,7 +548,6 @@ Plot.scatter({ }), maker.make({ name: "vega", - output: "Plot", examples: [ makeFnExample( `xDist = SampleSet.fromDist(2 to 5) From c2fd7bcec13c3e2a5e401f1a5565003f61927712 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 30 Mar 2024 08:54:23 -0700 Subject: [PATCH 8/9] Add canvas explicitly to website so that it builds --- packages/website/package.json | 1 + pnpm-lock.yaml | 31 +++---------------------------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/packages/website/package.json b/packages/website/package.json index abefce3364..64508c6abc 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -22,6 +22,7 @@ "@quri/versioned-squiggle-components": "workspace:*", "@vercel/analytics": "^1.2.2", "base64-js": "^1.5.1", + "canvas": "^2.11.2", "clsx": "^2.1.0", "next": "^14.1.0", "nextra": "^2.13.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d6a7621fdf..a94b84dee6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -955,6 +955,9 @@ importers: base64-js: specifier: ^1.5.1 version: 1.5.1 + canvas: + specifier: ^2.11.2 + version: 2.11.2 clsx: specifier: ^2.1.0 version: 2.1.0 @@ -4969,7 +4972,6 @@ packages: transitivePeerDependencies: - encoding - supports-color - dev: true /@mdx-js/mdx@2.3.0: resolution: {integrity: sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==} @@ -8645,7 +8647,6 @@ packages: /abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} - dev: true /abstract-leveldown@0.12.4: resolution: {integrity: sha512-TOod9d5RDExo6STLMGa+04HGkl+TlMfbDnTyN93/ETJ9DpQ0DaYLqcMZlbXvdc4W3vVo1Qrl+WhSp8zvDsJ+jA==} @@ -8721,7 +8722,6 @@ packages: debug: 4.3.4 transitivePeerDependencies: - supports-color - dev: true /agent-base@7.1.0: resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} @@ -8810,7 +8810,6 @@ packages: /aproba@2.0.0: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} - dev: true /arch@2.2.0: resolution: {integrity: sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==} @@ -8822,7 +8821,6 @@ packages: dependencies: delegates: 1.0.0 readable-stream: 3.6.2 - dev: true /arg@1.0.0: resolution: {integrity: sha512-Wk7TEzl1KqvTGs/uyhmHO/3XLd3t1UeU4IstvPXVzGPM522cTjqjNZ99esCkcL52sjqjo8e8CTBcWhkxvGzoAw==} @@ -9617,7 +9615,6 @@ packages: transitivePeerDependencies: - encoding - supports-color - dev: true /capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} @@ -9771,7 +9768,6 @@ packages: /chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} - dev: true /ci-info@3.8.0: resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} @@ -9949,7 +9945,6 @@ packages: /color-support@1.1.3: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true - dev: true /colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} @@ -10057,7 +10052,6 @@ packages: /console-control-strings@1.1.0: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} - dev: true /constant-case@3.0.4: resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} @@ -10760,7 +10754,6 @@ packages: engines: {node: '>=8'} dependencies: mimic-response: 2.1.0 - dev: true /decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} @@ -10916,7 +10909,6 @@ packages: /delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} - dev: true /depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} @@ -12327,7 +12319,6 @@ packages: engines: {node: '>= 8'} dependencies: minipass: 3.3.6 - dev: true /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -12379,7 +12370,6 @@ packages: string-width: 4.2.3 strip-ansi: 6.0.1 wide-align: 1.1.5 - dev: true /gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} @@ -12795,7 +12785,6 @@ packages: /has-unicode@2.0.1: resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} - dev: true /has@1.0.3: resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} @@ -13120,7 +13109,6 @@ packages: debug: 4.3.4 transitivePeerDependencies: - supports-color - dev: true /https-proxy-agent@7.0.2: resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==} @@ -14876,7 +14864,6 @@ packages: engines: {node: '>=8'} dependencies: semver: 6.3.1 - dev: true /make-dir@4.0.0: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} @@ -16039,7 +16026,6 @@ packages: /mimic-response@2.1.0: resolution: {integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==} engines: {node: '>=8'} - dev: true /mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} @@ -16107,12 +16093,10 @@ packages: engines: {node: '>=8'} dependencies: yallist: 4.0.0 - dev: true /minipass@5.0.0: resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} engines: {node: '>=8'} - dev: true /minipass@7.0.3: resolution: {integrity: sha512-LhbbwCfz3vsb12j/WkWQPZfKTsgqIe1Nf/ti1pKjYESGLHIVjWU96G9/ljLH4F9mWNVhlQOm0VySdAWzf05dpg==} @@ -16124,7 +16108,6 @@ packages: dependencies: minipass: 3.3.6 yallist: 4.0.0 - dev: true /mixme@0.5.9: resolution: {integrity: sha512-VC5fg6ySUscaWUpI4gxCBTQMH2RdUpNrk+MsbpCYtIvf9SBJdiUey4qE7BXviJsJR4nDQxCZ+3yaYNW3guz/Pw==} @@ -16146,7 +16129,6 @@ packages: resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} engines: {node: '>=10'} hasBin: true - dev: true /mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} @@ -16176,7 +16158,6 @@ packages: /nan@2.17.0: resolution: {integrity: sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==} - dev: true /nano-css@5.6.1(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-T2Mhc//CepkTa3X4pUhKgbEheJHYAxD0VptuqFhDbGMUWVV2m+lkNiW/Ieuj35wrfC8Zm0l7HvssQh7zcEttSw==} @@ -16464,7 +16445,6 @@ packages: hasBin: true dependencies: abbrev: 1.1.1 - dev: true /normalize-package-data@2.5.0: resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} @@ -16522,7 +16502,6 @@ packages: console-control-strings: 1.1.0 gauge: 3.0.2 set-blocking: 2.0.0 - dev: true /nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -18623,7 +18602,6 @@ packages: /set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - dev: true /set-function-length@1.2.0: resolution: {integrity: sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==} @@ -18752,7 +18730,6 @@ packages: decompress-response: 4.2.1 once: 1.4.0 simple-concat: 1.0.1 - dev: true /simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} @@ -19322,7 +19299,6 @@ packages: minizlib: 2.1.2 mkdirp: 1.0.4 yallist: 4.0.0 - dev: true /teeny-request@7.1.1: resolution: {integrity: sha512-iwY6rkW5DDGq8hE2YgNQlKbptYpY5Nn2xecjQiNjOXWbKzPGUfmeUBCSQbbr306d7Z7U2N0TPl+/SwYRfua1Dg==} @@ -21039,7 +21015,6 @@ packages: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} dependencies: string-width: 4.2.3 - dev: true /wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} From c7756631255f6957165074376de163ff163a9cd2 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sat, 30 Mar 2024 09:03:44 -0700 Subject: [PATCH 9/9] Trying to add canva to hub, too --- packages/hub/package.json | 1 + pnpm-lock.yaml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/packages/hub/package.json b/packages/hub/package.json index 979c11c969..6322593a43 100644 --- a/packages/hub/package.json +++ b/packages/hub/package.json @@ -38,6 +38,7 @@ "@quri/versioned-squiggle-components": "workspace:*", "@vercel/analytics": "^1.2.2", "base64-js": "^1.5.1", + "canvas": "^2.11.2", "clsx": "^2.1.0", "d3": "^7.8.5", "date-fns": "^3.3.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a94b84dee6..1c1afe37a0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -345,6 +345,9 @@ importers: base64-js: specifier: ^1.5.1 version: 1.5.1 + canvas: + specifier: ^2.11.2 + version: 2.11.2 clsx: specifier: ^2.1.0 version: 2.1.0