diff --git a/packages/components/package.json b/packages/components/package.json index 67b2eeb5..3b594bc5 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -3,18 +3,21 @@ "version": "0.2.20", "license": "MIT", "dependencies": { + "@hookform/resolvers": "^2.8.10", "@quri/squiggle-lang": "^0.2.8", "@react-hook/size": "^2.1.2", "lodash": "^4.17.21", "react": "^18.1.0", "react-ace": "^10.1.0", "react-dom": "^18.1.0", + "react-hook-form": "^7.31.2", "react-use": "^17.4.0", "react-vega": "^7.5.1", "styled-components": "^5.3.5", "vega": "^5.22.1", "vega-embed": "^6.20.6", - "vega-lite": "^5.2.0" + "vega-lite": "^5.2.0", + "yup": "^0.32.11" }, "devDependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.17.12", diff --git a/packages/components/src/components/FunctionChart.tsx b/packages/components/src/components/FunctionChart.tsx index 242bf719..bb5a9e24 100644 --- a/packages/components/src/components/FunctionChart.tsx +++ b/packages/components/src/components/FunctionChart.tsx @@ -1,40 +1,9 @@ import * as React from "react"; -import _ from "lodash"; -import type { Spec } from "vega"; -import { - Distribution, - result, - lambdaValue, - environment, - runForeign, - squiggleExpression, - errorValue, - errorValueToString, -} from "@quri/squiggle-lang"; -import { createClassFromSpec } from "react-vega"; -import * as percentilesSpec from "../vega-specs/spec-percentiles.json"; -import { DistributionChart } from "./DistributionChart"; -import { NumberShower } from "./NumberShower"; +import { lambdaValue, environment, runForeign } from "@quri/squiggle-lang"; +import { FunctionChart1Dist } from "./FunctionChart1Dist"; +import { FunctionChart1Number } from "./FunctionChart1Number"; import { ErrorBox } from "./ErrorBox"; -let SquigglePercentilesChart = createClassFromSpec({ - spec: percentilesSpec as Spec, -}); - -const _rangeByCount = (start: number, stop: number, count: number) => { - const step = (stop - start) / (count - 1); - const items = _.range(start, stop, step); - const result = items.concat([stop]); - return result; -}; - -function unwrap(x: result): a { - if (x.tag === "Ok") { - return x.value; - } else { - throw Error("FAILURE TO UNWRAP"); - } -} export type FunctionChartSettings = { start: number; stop: number; @@ -45,167 +14,61 @@ interface FunctionChartProps { fn: lambdaValue; chartSettings: FunctionChartSettings; environment: environment; + height: number; } -type percentiles = { - x: number; - p1: number; - p5: number; - p10: number; - p20: number; - p30: number; - p40: number; - p50: number; - p60: number; - p70: number; - p80: number; - p90: number; - p95: number; - p99: number; -}[]; - -type errors = _.Dictionary< - { - x: number; - value: string; - }[] ->; - -type point = { x: number; value: result }; - -let getPercentiles = ({ chartSettings, fn, environment }) => { - let chartPointsToRender = _rangeByCount( - chartSettings.start, - chartSettings.stop, - chartSettings.count - ); - - let chartPointsData: point[] = chartPointsToRender.map((x) => { - let result = runForeign(fn, [x], environment); - if (result.tag === "Ok") { - if (result.value.tag == "distribution") { - return { x, value: { tag: "Ok", value: result.value.value } }; - } else { - return { - x, - value: { - tag: "Error", - value: - "Cannot currently render functions that don't return distributions", - }, - }; - } - } else { - return { - x, - value: { tag: "Error", value: errorValueToString(result.value) }, - }; - } - }); - - let initialPartition: [ - { x: number; value: Distribution }[], - { x: number; value: string }[] - ] = [[], []]; - - let [functionImage, errors] = chartPointsData.reduce((acc, current) => { - if (current.value.tag === "Ok") { - acc[0].push({ x: current.x, value: current.value.value }); - } else { - acc[1].push({ x: current.x, value: current.value.value }); - } - return acc; - }, initialPartition); - - let groupedErrors: errors = _.groupBy(errors, (x) => x.value); - - let percentiles: percentiles = functionImage.map(({ x, value }) => { - // We convert it to to a pointSet distribution first, so that in case its a sample set - // distribution, it doesn't internally convert it to a pointSet distribution for every - // single inv() call. - let toPointSet: Distribution = unwrap(value.toPointSet()); - return { - x: x, - p1: unwrap(toPointSet.inv(0.01)), - p5: unwrap(toPointSet.inv(0.05)), - p10: unwrap(toPointSet.inv(0.1)), - p20: unwrap(toPointSet.inv(0.2)), - p30: unwrap(toPointSet.inv(0.3)), - p40: unwrap(toPointSet.inv(0.4)), - p50: unwrap(toPointSet.inv(0.5)), - p60: unwrap(toPointSet.inv(0.6)), - p70: unwrap(toPointSet.inv(0.7)), - p80: unwrap(toPointSet.inv(0.8)), - p90: unwrap(toPointSet.inv(0.9)), - p95: unwrap(toPointSet.inv(0.95)), - p99: unwrap(toPointSet.inv(0.99)), - }; - }); - - return { percentiles, errors: groupedErrors }; -}; - export const FunctionChart: React.FC = ({ fn, chartSettings, environment, + height, }: FunctionChartProps) => { - let [mouseOverlay, setMouseOverlay] = React.useState(0); - function handleHover(_name: string, value: unknown) { - setMouseOverlay(value as number); - } - function handleOut() { - setMouseOverlay(NaN); - } - const signalListeners = { mousemove: handleHover, mouseout: handleOut }; - let mouseItem: result = !!mouseOverlay - ? runForeign(fn, [mouseOverlay], environment) - : { - tag: "Error", - value: { - tag: "REExpectedType", - value: "Hover x-coordinate returned NaN. Expected a number.", - }, - }; - let showChart = - mouseItem.tag === "Ok" && mouseItem.value.tag == "distribution" ? ( - - ) : ( - <> - ); + let result1 = runForeign(fn, [chartSettings.start], environment); + let result2 = runForeign(fn, [chartSettings.stop], environment); + let getValidResult = () => { + if (result1.tag === "Ok") { + return result1; + } else if (result2.tag === "Ok") { + return result2; + } else { + return result1; + } + }; + let validResult = getValidResult(); + let resultType = validResult.tag === "Ok" ? validResult.value.tag : "Error"; - let getPercentilesMemoized = React.useMemo( - () => getPercentiles({ chartSettings, fn, environment }), - [environment, fn] - ); - - return ( - <> - - {showChart} - {_.entries(getPercentilesMemoized.errors).map( - ([errorName, errorPoints]) => ( - - Values:{" "} - {errorPoints - .map((r, i) => ) - .reduce((a, b) => ( - <> - {a}, {b} - - ))} + let component = () => { + switch (resultType) { + case "distribution": + return ( + + ); + case "number": + return ( + + ); + case "Error": + return ( + The function failed to be run + ); + default: + return ( + + There is no function visualization for this type of function - ) - )} - - ); + ); + } + }; + + return component(); }; diff --git a/packages/components/src/components/FunctionChart1Dist.tsx b/packages/components/src/components/FunctionChart1Dist.tsx new file mode 100644 index 00000000..836bcdd5 --- /dev/null +++ b/packages/components/src/components/FunctionChart1Dist.tsx @@ -0,0 +1,214 @@ +import * as React from "react"; +import _ from "lodash"; +import type { Spec } from "vega"; +import { + Distribution, + result, + lambdaValue, + environment, + runForeign, + squiggleExpression, + errorValue, + errorValueToString, +} from "@quri/squiggle-lang"; +import { createClassFromSpec } from "react-vega"; +import * as percentilesSpec from "../vega-specs/spec-percentiles.json"; +import { DistributionChart } from "./DistributionChart"; +import { NumberShower } from "./NumberShower"; +import { ErrorBox } from "./ErrorBox"; + +let SquigglePercentilesChart = createClassFromSpec({ + spec: percentilesSpec as Spec, +}); + +const _rangeByCount = (start: number, stop: number, count: number) => { + const step = (stop - start) / (count - 1); + const items = _.range(start, stop, step); + const result = items.concat([stop]); + return result; +}; + +function unwrap(x: result): a { + if (x.tag === "Ok") { + return x.value; + } else { + throw Error("FAILURE TO UNWRAP"); + } +} +export type FunctionChartSettings = { + start: number; + stop: number; + count: number; +}; + +interface FunctionChart1DistProps { + fn: lambdaValue; + chartSettings: FunctionChartSettings; + environment: environment; + height: number; +} + +type percentiles = { + x: number; + p1: number; + p5: number; + p10: number; + p20: number; + p30: number; + p40: number; + p50: number; + p60: number; + p70: number; + p80: number; + p90: number; + p95: number; + p99: number; +}[]; + +type errors = _.Dictionary< + { + x: number; + value: string; + }[] +>; + +type point = { x: number; value: result }; + +let getPercentiles = ({ chartSettings, fn, environment }) => { + let chartPointsToRender = _rangeByCount( + chartSettings.start, + chartSettings.stop, + chartSettings.count + ); + + let chartPointsData: point[] = chartPointsToRender.map((x) => { + let result = runForeign(fn, [x], environment); + if (result.tag === "Ok") { + if (result.value.tag == "distribution") { + return { x, value: { tag: "Ok", value: result.value.value } }; + } else { + return { + x, + value: { + tag: "Error", + value: + "Cannot currently render functions that don't return distributions", + }, + }; + } + } else { + return { + x, + value: { tag: "Error", value: errorValueToString(result.value) }, + }; + } + }); + + let initialPartition: [ + { x: number; value: Distribution }[], + { x: number; value: string }[] + ] = [[], []]; + + let [functionImage, errors] = chartPointsData.reduce((acc, current) => { + if (current.value.tag === "Ok") { + acc[0].push({ x: current.x, value: current.value.value }); + } else { + acc[1].push({ x: current.x, value: current.value.value }); + } + return acc; + }, initialPartition); + + let groupedErrors: errors = _.groupBy(errors, (x) => x.value); + + let percentiles: percentiles = functionImage.map(({ x, value }) => { + // We convert it to to a pointSet distribution first, so that in case its a sample set + // distribution, it doesn't internally convert it to a pointSet distribution for every + // single inv() call. + let toPointSet: Distribution = unwrap(value.toPointSet()); + return { + x: x, + p1: unwrap(toPointSet.inv(0.01)), + p5: unwrap(toPointSet.inv(0.05)), + p10: unwrap(toPointSet.inv(0.1)), + p20: unwrap(toPointSet.inv(0.2)), + p30: unwrap(toPointSet.inv(0.3)), + p40: unwrap(toPointSet.inv(0.4)), + p50: unwrap(toPointSet.inv(0.5)), + p60: unwrap(toPointSet.inv(0.6)), + p70: unwrap(toPointSet.inv(0.7)), + p80: unwrap(toPointSet.inv(0.8)), + p90: unwrap(toPointSet.inv(0.9)), + p95: unwrap(toPointSet.inv(0.95)), + p99: unwrap(toPointSet.inv(0.99)), + }; + }); + + return { percentiles, errors: groupedErrors }; +}; + +export const FunctionChart1Dist: React.FC = ({ + fn, + chartSettings, + environment, + height, +}: FunctionChart1DistProps) => { + let [mouseOverlay, setMouseOverlay] = React.useState(0); + function handleHover(_name: string, value: unknown) { + setMouseOverlay(value as number); + } + function handleOut() { + setMouseOverlay(NaN); + } + const signalListeners = { mousemove: handleHover, mouseout: handleOut }; + let mouseItem: result = !!mouseOverlay + ? runForeign(fn, [mouseOverlay], environment) + : { + tag: "Error", + value: { + tag: "REExpectedType", + value: "Hover x-coordinate returned NaN. Expected a number.", + }, + }; + let showChart = + mouseItem.tag === "Ok" && mouseItem.value.tag == "distribution" ? ( + + ) : ( + <> + ); + + let getPercentilesMemoized = React.useMemo( + () => getPercentiles({ chartSettings, fn, environment }), + [environment, fn] + ); + + return ( + <> + + {showChart} + {_.entries(getPercentilesMemoized.errors).map( + ([errorName, errorPoints]) => ( + + Values:{" "} + {errorPoints + .map((r, i) => ) + .reduce((a, b) => ( + <> + {a}, {b} + + ))} + + ) + )} + + ); +}; diff --git a/packages/components/src/components/FunctionChart1Number.tsx b/packages/components/src/components/FunctionChart1Number.tsx new file mode 100644 index 00000000..9d2feca7 --- /dev/null +++ b/packages/components/src/components/FunctionChart1Number.tsx @@ -0,0 +1,119 @@ +import * as React from "react"; +import _ from "lodash"; +import type { Spec } from "vega"; +import { + result, + lambdaValue, + environment, + runForeign, + errorValueToString, +} from "@quri/squiggle-lang"; +import { createClassFromSpec } from "react-vega"; +import * as lineChartSpec from "../vega-specs/spec-line-chart.json"; +import { ErrorBox } from "./ErrorBox"; + +let SquiggleLineChart = createClassFromSpec({ + spec: lineChartSpec as Spec, +}); + +const _rangeByCount = (start: number, stop: number, count: number) => { + const step = (stop - start) / (count - 1); + const items = _.range(start, stop, step); + const result = items.concat([stop]); + return result; +}; + +export type FunctionChartSettings = { + start: number; + stop: number; + count: number; +}; + +interface FunctionChart1NumberProps { + fn: lambdaValue; + chartSettings: FunctionChartSettings; + environment: environment; + height: number; +} + +type point = { x: number; value: result }; + +let getFunctionImage = ({ chartSettings, fn, environment }) => { + //We adjust the count, because the count is made for distributions, which are much more expensive to estimate + let adjustedCount = chartSettings.count * 20; + + let chartPointsToRender = _rangeByCount( + chartSettings.start, + chartSettings.stop, + adjustedCount + ); + + let chartPointsData: point[] = chartPointsToRender.map((x) => { + let result = runForeign(fn, [x], environment); + if (result.tag === "Ok") { + if (result.value.tag == "number") { + return { x, value: { tag: "Ok", value: result.value.value } }; + } else { + return { + x, + value: { + tag: "Error", + value: "This component expected number outputs", + }, + }; + } + } else { + return { + x, + value: { tag: "Error", value: errorValueToString(result.value) }, + }; + } + }); + + let initialPartition: [ + { x: number; value: number }[], + { x: number; value: string }[] + ] = [[], []]; + + let [functionImage, errors] = chartPointsData.reduce((acc, current) => { + if (current.value.tag === "Ok") { + acc[0].push({ x: current.x, value: current.value.value }); + } else { + acc[1].push({ x: current.x, value: current.value.value }); + } + return acc; + }, initialPartition); + + return { errors, functionImage }; +}; + +export const FunctionChart1Number: React.FC = ({ + fn, + chartSettings, + environment, + height, +}: FunctionChart1NumberProps) => { + let getFunctionImageMemoized = React.useMemo( + () => getFunctionImage({ chartSettings, fn, environment }), + [environment, fn] + ); + + let data = getFunctionImageMemoized.functionImage.map(({ x, value }) => ({ + x, + y: value, + })); + return ( + <> + + {getFunctionImageMemoized.errors.map(({ x, value }) => ( + + Error at point ${x} + + ))} + + ); +}; diff --git a/packages/components/src/components/JsonEditor.tsx b/packages/components/src/components/JsonEditor.tsx new file mode 100644 index 00000000..c81debf4 --- /dev/null +++ b/packages/components/src/components/JsonEditor.tsx @@ -0,0 +1,51 @@ +import _ from "lodash"; +import React, { FC } from "react"; +import AceEditor from "react-ace"; + +import "ace-builds/src-noconflict/mode-json"; +import "ace-builds/src-noconflict/theme-github"; + +interface CodeEditorProps { + value: string; + onChange: (value: string) => void; + oneLine?: boolean; + width?: number; + height: number; + showGutter?: boolean; +} + +export let JsonEditor: FC = ({ + value, + onChange, + oneLine = false, + showGutter = false, + height, +}: CodeEditorProps) => { + let lineCount = value.split("\n").length; + let id = _.uniqueId(); + return ( + + ); +}; + +export default JsonEditor; diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index bb166682..f33ccb84 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -196,7 +196,7 @@ const SquiggleItem: React.FC = ({ = ({ = ({ = ({ squiggleString = "", environment, onChange = () => {}, - height = 60, + height = 200, bindings = defaultBindings, jsImports = defaultImports, showSummary = false, diff --git a/packages/components/src/components/SquigglePlayground.tsx b/packages/components/src/components/SquigglePlayground.tsx index f403a4ce..921a3282 100644 --- a/packages/components/src/components/SquigglePlayground.tsx +++ b/packages/components/src/components/SquigglePlayground.tsx @@ -3,12 +3,12 @@ import React, { FC, ReactElement, useState } from "react"; import ReactDOM from "react-dom"; import { SquiggleChart } from "./SquiggleChart"; import CodeEditor from "./CodeEditor"; +import JsonEditor from "./JsonEditor"; import styled from "styled-components"; -import { - defaultBindings, - environment, - defaultImports, -} from "@quri/squiggle-lang"; +import { useForm, useWatch } from "react-hook-form"; +import * as yup from "yup"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { defaultBindings, environment } from "@quri/squiggle-lang"; interface FieldFloatProps { label: string; @@ -68,9 +68,14 @@ const Display = styled.div` max-height: ${(props) => props.maxHeight}px; `; -const Row = styled.div` +interface RowProps { + readonly leftPercentage: number; +} + +const Row = styled.div` display: grid; - grid-template-columns: 50% 50%; + grid-template-columns: ${(p) => p.leftPercentage}% ${(p) => + 100 - p.leftPercentage}%; `; const Col = styled.div``; @@ -87,17 +92,64 @@ interface PlaygroundProps { showSummary?: boolean; } +const schema = yup + .object() + .shape({ + sampleCount: yup + .number() + .required() + .positive() + .integer() + .default(1000) + .min(10) + .max(1000000), + xyPointLength: yup + .number() + .required() + .positive() + .integer() + .default(1000) + .min(10) + .max(10000), + chartHeight: yup.number().required().positive().integer().default(350), + leftSizePercent: yup + .number() + .required() + .positive() + .integer() + .min(10) + .max(100) + .default(50), + showTypes: yup.boolean(), + showControls: yup.boolean(), + showSummary: yup.boolean(), + showSettingsPage: yup.boolean().default(false), + }) + .required(); + +type InputProps = { + label: string; + children: ReactElement; +}; + +const InputItem: React.FC = ({ label, children }) => ( +
+ + {children} +
+); + let SquigglePlayground: FC = ({ initialSquiggleString = "", - height = 300, + height = 500, showTypes = false, showControls = false, showSummary = false, }: PlaygroundProps) => { let [squiggleString, setSquiggleString] = useState(initialSquiggleString); - let [sampleCount, setSampleCount] = useState(1000); - let [outputXYPoints, setOutputXYPoints] = useState(1000); - let [pointDistLength, setPointDistLength] = useState(1000); + let [importString, setImportString] = useState("{}"); + let [imports, setImports] = useState({}); + let [importsAreValid, setImportsAreValid] = useState(true); let [diagramStart, setDiagramStart] = useState(0); let [diagramStop, setDiagramStop] = useState(10); let [diagramCount, setDiagramCount] = useState(20); @@ -106,21 +158,95 @@ let SquigglePlayground: FC = ({ stop: diagramStop, count: diagramCount, }; + const { + register, + formState: { errors }, + control, + } = useForm({ + resolver: yupResolver(schema), + defaultValues: { + sampleCount: 1000, + xyPointLength: 1000, + chartHeight: 150, + showTypes: showTypes, + showControls: showControls, + showSummary: showSummary, + leftSizePercent: 50, + showSettingsPage: false, + }, + }); + const vars = useWatch({ + control, + }); let env: environment = { - sampleCount: sampleCount, - xyPointLength: outputXYPoints, + sampleCount: Number(vars.sampleCount), + xyPointLength: Number(vars.xyPointLength), + }; + let getChangeJson = (r: string) => { + setImportString(r); + try { + setImports(JSON.parse(r)); + setImportsAreValid(true); + } catch (e) { + setImportsAreValid(false); + } }; return ( - + + - + {vars.showSettingsPage ? ( + <> + + + + + + + + + + + + + + + + + + + + + + + <> + + {importsAreValid ? "Valid" : "Invalid"} + + + + ) : ( + + )} @@ -128,12 +254,12 @@ let SquigglePlayground: FC = ({ squiggleString={squiggleString} environment={env} chartSettings={chartSettings} - height={150} - showTypes={showTypes} - showControls={showControls} + height={vars.chartHeight} + showTypes={vars.showTypes} + showControls={vars.showControls} bindings={defaultBindings} - jsImports={defaultImports} - showSummary={showSummary} + jsImports={imports} + showSummary={vars.showSummary} /> diff --git a/packages/components/src/stories/SquiggleChart.stories.mdx b/packages/components/src/stories/SquiggleChart.stories.mdx index 9ad98ef0..bce22c1c 100644 --- a/packages/components/src/stories/SquiggleChart.stories.mdx +++ b/packages/components/src/stories/SquiggleChart.stories.mdx @@ -153,11 +153,11 @@ to allow large and small numbers being printed cleanly. -## Functions +## Functions (Distribution Output) +## Functions (Number Output) + + + + {Template.bind({})} + + + ## Records diff --git a/packages/components/src/stories/SquigglePlayground.stories.mdx b/packages/components/src/stories/SquigglePlayground.stories.mdx index 89ac5444..67bd0367 100644 --- a/packages/components/src/stories/SquigglePlayground.stories.mdx +++ b/packages/components/src/stories/SquigglePlayground.stories.mdx @@ -16,7 +16,7 @@ including sampling settings, in squiggle. name="Normal" args={{ initialSquiggleString: "normal(5,2)", - height: 500, + height: 800, }} > {Template.bind({})} diff --git a/packages/components/src/vega-specs/spec-distributions.json b/packages/components/src/vega-specs/spec-distributions.json index 74559a03..29ca4e1d 100644 --- a/packages/components/src/vega-specs/spec-distributions.json +++ b/packages/components/src/vega-specs/spec-distributions.json @@ -82,6 +82,9 @@ "y2": { "scale": "yscale", "value": 0 + }, + "fill": { + "value": "#2f65a7" } } } diff --git a/packages/components/src/vega-specs/spec-line-chart.json b/packages/components/src/vega-specs/spec-line-chart.json new file mode 100644 index 00000000..117d9543 --- /dev/null +++ b/packages/components/src/vega-specs/spec-line-chart.json @@ -0,0 +1,88 @@ +{ + "$schema": "https://vega.github.io/schema/vega/v5.json", + "width": 500, + "height": 200, + "padding": 5, + "data": [ + { + "name": "facet", + "values": [], + "format": { + "type": "json", + "parse": { + "timestamp": "date" + } + } + } + ], + "scales": [ + { + "name": "x", + "type": "linear", + "nice": true, + "domain": { + "data": "facet", + "field": "x" + }, + "range": "width" + }, + { + "name": "y", + "type": "linear", + "range": "height", + "nice": true, + "zero": true, + "domain": { + "data": "facet", + "field": "y" + } + } + ], + "signals": [ + { + "name": "mousemove", + "on": [{ "events": "mousemove", "update": "invert('x', x())" }] + }, + { + "name": "mouseout", + "on": [{ "events": "mouseout", "update": "invert('x', x())" }] + } + ], + "axes": [ + { + "orient": "bottom", + "scale": "x", + "grid": false, + "labelColor": "#727d93", + "tickColor": "#fff", + "tickOpacity": 0.0, + "domainColor": "#727d93", + "domainOpacity": 0.1, + "tickCount": 5 + }, + { + "orient": "left", + "scale": "y", + "grid": false, + "labelColor": "#727d93", + "tickColor": "#fff", + "tickOpacity": 0.0, + "domainColor": "#727d93", + "domainOpacity": 0.1, + "tickCount": 5 + } + ], + "marks": [ + { + "type": "line", + "from": { "data": "facet" }, + "encode": { + "enter": { + "x": { "scale": "x", "field": "x" }, + "y": { "scale": "y", "field": "y" }, + "strokeWidth": { "value": 2 } + } + } + } + ] +} diff --git a/packages/components/tsconfig.json b/packages/components/tsconfig.json index c8d799d5..38d28704 100644 --- a/packages/components/tsconfig.json +++ b/packages/components/tsconfig.json @@ -20,7 +20,8 @@ }, "files": [ "src/vega-specs/spec-distributions.json", - "src/vega-specs/spec-percentiles.json" + "src/vega-specs/spec-percentiles.json", + "src/vega-specs/spec-line-chart.json" ], "target": "ES6", "include": ["src/**/*", "src/*"], diff --git a/yarn.lock b/yarn.lock index 39329f75..680465a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1245,6 +1245,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.15.4": + version "7.18.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4" + integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.12.7", "@babel/template@^7.16.7", "@babel/template@^7.3.3": version "7.16.7" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" @@ -1839,6 +1846,11 @@ dependencies: "@hapi/hoek" "^9.0.0" +"@hookform/resolvers@^2.8.10": + version "2.8.10" + resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-2.8.10.tgz#b66d7a7848b1b1dd5b976a73fff36bb366666e7d" + integrity sha512-DDFtNlugsbwAhCJHYp3NcN5LvJrwSsCLPi41Wo5O8UAIbUFnBfY/jW+zKnlX57BZ4jE0j/g6R9rB3JlO89ad0g== + "@humanwhocodes/config-array@^0.9.2": version "0.9.5" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.9.5.tgz#2cbaf9a89460da24b5ca6531b8bbfc23e1df50c7" @@ -4163,7 +4175,7 @@ resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.11.1.tgz#34de04477dcf79e2ef6c8d23b41a3d81f9ebeaf5" integrity sha512-DUlIj2nk0YnJdlWgsFuVKcX27MLW0KbKmGVoUHmFr+74FYYNUDAaj9ZqTADvsbE8rfxuVmSFc7KczYn5Y09ozg== -"@types/lodash@^4.14.167", "@types/lodash@^4.14.182": +"@types/lodash@^4.14.167", "@types/lodash@^4.14.175", "@types/lodash@^4.14.182": version "4.14.182" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2" integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q== @@ -4298,10 +4310,10 @@ dependencies: "@types/react" "*" -"@types/react@*", "@types/react@^18.0.1", "@types/react@^18.0.9": - version "18.0.9" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.9.tgz#d6712a38bd6cd83469603e7359511126f122e878" - integrity sha512-9bjbg1hJHUm4De19L1cHiW0Jvx3geel6Qczhjd0qY5VKVE2X5+x77YxAepuCwVh4vrgZJdgEJw48zrhRIeF4Nw== +"@types/react@*", "@types/react@17.0.43", "@types/react@^18.0.9": + version "17.0.43" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.43.tgz#4adc142887dd4a2601ce730bc56c3436fdb07a55" + integrity sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -11601,6 +11613,11 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash-es@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + lodash.assignin@^4.0.9: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" @@ -12290,6 +12307,11 @@ nano-css@^5.3.1: stacktrace-js "^2.0.2" stylis "^4.0.6" +nanoclone@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4" + integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA== + nanoid@^3.3.1, nanoid@^3.3.3: version "3.3.4" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" @@ -13998,6 +14020,11 @@ prop-types@^15.0.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" +property-expr@^2.0.4: + version "2.0.5" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.5.tgz#278bdb15308ae16af3e3b9640024524f4dc02cb4" + integrity sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA== + property-information@^5.0.0, property-information@^5.3.0: version "5.6.0" resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" @@ -14328,6 +14355,11 @@ react-helmet-async@*, react-helmet-async@^1.3.0: react-fast-compare "^3.2.0" shallowequal "^1.1.0" +react-hook-form@^7.31.2: + version "7.31.2" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.31.2.tgz#efb7ac469810954488b7cf40be4e5017122c6e5e" + integrity sha512-oPudn3YuyzWg//IsT9z2cMEjWocAgHWX/bmueDT8cmsYQnGY5h7/njjvMDfLVv3mbdhYBjslTRnII2MIT7eNCA== + react-inspector@^5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.1.tgz#58476c78fde05d5055646ed8ec02030af42953c8" @@ -14525,7 +14557,7 @@ react-vega@^7.5.1: prop-types "^15.8.1" vega-embed "^6.5.1" -react@^18.0.0, react@^18.1.0: +react@^18.1.0: version "18.1.0" resolved "https://registry.yarnpkg.com/react/-/react-18.1.0.tgz#6f8620382decb17fdc5cc223a115e2adbf104890" integrity sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ== @@ -16559,6 +16591,11 @@ topojson-client@^3.1.0: dependencies: commander "2" +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha1-riF2gXXRVZ1IvvNUILL0li8JwzA= + totalist@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" @@ -18440,6 +18477,19 @@ yocto-queue@^0.1.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yup@^0.32.11: + version "0.32.11" + resolved "https://registry.yarnpkg.com/yup/-/yup-0.32.11.tgz#d67fb83eefa4698607982e63f7ca4c5ed3cf18c5" + integrity sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg== + dependencies: + "@babel/runtime" "^7.15.4" + "@types/lodash" "^4.14.175" + lodash "^4.17.21" + lodash-es "^4.17.21" + nanoclone "^0.2.1" + property-expr "^2.0.4" + toposort "^2.0.2" + zwitch@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920"