diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index fd5ca35e..8ef540a7 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -71,7 +71,7 @@ export const SquiggleChart: React.FC = React.memo( distributionChartActions, enableLocalSettings = false, }) => { - const result = useSquiggle({ + const { result, bindings } = useSquiggle({ code, environment, // jsImports, @@ -98,15 +98,27 @@ export const SquiggleChart: React.FC = React.memo( }; return ( - +
+ +
+ +
); } ); diff --git a/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx b/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx index 7ae23c1a..4dc6ef98 100644 --- a/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx +++ b/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx @@ -37,13 +37,18 @@ function getChartSettings(x: declaration): FunctionChartSettings { */ const VariableList: React.FC<{ - path: string[]; + value: SqValue; heading: string; children: (settings: MergedItemSettings) => React.ReactNode; -}> = ({ path, heading, children }) => ( - +}> = ({ value, heading, children }) => ( + {(settings) => ( -
+
{children(settings)}
)} @@ -52,54 +57,41 @@ const VariableList: React.FC<{ export interface Props { /** The output of squiggle's run */ - expression: SqValue; - /** Path to the current item, e.g. `['foo', 'bar', '3']` for `foo.bar[3]`; can be empty on the top-level item. */ - path: string[]; + value: SqValue; width?: number; } -export const ExpressionViewer: React.FC = ({ - path, - expression, - width, -}) => { +export const ExpressionViewer: React.FC = ({ value, width }) => { const { getMergedSettings } = useContext(ViewerContext); - if (typeof expression !== "object") { - return ( - - {() => `Unknown expression: ${expression}`} - - ); - } - switch (expression.tag) { + switch (value.tag) { case SqValueTag.Number: return ( - + {() => (
- +
)}
); case SqValueTag.Distribution: { - const distType = expression.value.tag; + const distType = value.value.tag; return ( { - const shape = expression.value.pointSet( - getMergedSettings(path).environment + const shape = value.value.pointSet( + getMergedSettings(value.location).environment ); return ( = ({ {(settings) => { return ( = ({ } case SqValueTag.String: return ( - + {() => ( <> " - {expression.value} + {value.value} " @@ -139,61 +131,61 @@ export const ExpressionViewer: React.FC = ({ ); case SqValueTag.Bool: return ( - - {() => expression.value.toString()} + + {() => value.value.toString()} ); case SqValueTag.Symbol: return ( - + {() => ( <> Undefined Symbol: - {expression.value} + {value.value} )} ); case SqValueTag.Call: return ( - - {() => expression.value} + + {() => value.value} ); case SqValueTag.ArrayString: return ( - - {() => expression.value.map((r) => `"${r}"`).join(", ")} + + {() => value.value.map((r) => `"${r}"`).join(", ")} ); case SqValueTag.Date: return ( - - {() => expression.value.toDateString()} + + {() => value.value.toDateString()} ); case SqValueTag.Void: return ( - + {() => "Void"} ); case SqValueTag.TimeDuration: { return ( - - {() => } + + {() => } ); } case SqValueTag.Lambda: return ( { return ( @@ -202,11 +194,11 @@ export const ExpressionViewer: React.FC = ({ > {(settings) => ( <> -
{`function(${expression.value +
{`function(${value.value .parameters() .join(",")})`}
= ({ case SqValueTag.Declaration: { return ( { return ( ); @@ -252,16 +244,15 @@ export const ExpressionViewer: React.FC = ({ } case SqValueTag.Module: { return ( - + {(_) => - expression.value + value.value .entries() .filter(([key, _]) => !key.match(/^(Math|System)\./)) .map(([key, r]) => ( )) @@ -270,16 +261,16 @@ export const ExpressionViewer: React.FC = ({ ); } case SqValueTag.Record: - const plot = makePlot(expression.value); + const plot = makePlot(value.value); if (plot) { return ( { let disableLogX = plot.distributions.some((x) => { let pointSet = x.distribution.pointSet( - getMergedSettings(path).environment + getMergedSettings(value.location).environment ); return ( pointSet.tag === "Ok" && @@ -288,7 +279,7 @@ export const ExpressionViewer: React.FC = ({ }); return ( = ({ ); } else { return ( - + {(_) => - expression.value + value.value .entries() .map(([key, r]) => ( )) @@ -329,15 +319,14 @@ export const ExpressionViewer: React.FC = ({ } case SqValueTag.Array: return ( - + {(_) => - expression.value + value.value .getValues() .map((r, i) => ( )) @@ -346,13 +335,11 @@ export const ExpressionViewer: React.FC = ({ ); default: { return ( - + {() => (
No display for type: {" "} - - {expression.tag} - + {value.tag}
)}
diff --git a/packages/components/src/components/SquiggleViewer/ItemSettingsMenu.tsx b/packages/components/src/components/SquiggleViewer/ItemSettingsMenu.tsx index 49c2eacc..50f8e5ba 100644 --- a/packages/components/src/components/SquiggleViewer/ItemSettingsMenu.tsx +++ b/packages/components/src/components/SquiggleViewer/ItemSettingsMenu.tsx @@ -4,13 +4,14 @@ import { useForm } from "react-hook-form"; import { yupResolver } from "@hookform/resolvers/yup"; import { Modal } from "../ui/Modal"; import { ViewSettings, viewSettingsSchema } from "../ViewSettings"; -import { Path, pathAsString } from "./utils"; import { ViewerContext } from "./ViewerContext"; import { defaultTickFormat } from "../../lib/distributionSpecBuilder"; import { PlaygroundContext } from "../SquigglePlayground"; +import { SqValue } from "@quri/squiggle-lang"; +import { locationAsString } from "./utils"; type Props = { - path: Path; + value: SqValue; onChange: () => void; disableLogX?: boolean; withFunctionSettings: boolean; @@ -19,7 +20,7 @@ type Props = { const ItemSettingsModal: React.FC< Props & { close: () => void; resetScroll: () => void } > = ({ - path, + value, onChange, disableLogX, withFunctionSettings, @@ -29,7 +30,7 @@ const ItemSettingsModal: React.FC< const { setSettings, getSettings, getMergedSettings } = useContext(ViewerContext); - const mergedSettings = getMergedSettings(path); + const mergedSettings = getMergedSettings(value.location); const { register, watch } = useForm({ resolver: yupResolver(viewSettingsSchema), @@ -53,8 +54,8 @@ const ItemSettingsModal: React.FC< }); useEffect(() => { const subscription = watch((vars) => { - const settings = getSettings(path); // get the latest version - setSettings(path, { + const settings = getSettings(value.location); // get the latest version + setSettings(value.location, { ...settings, distributionPlotSettings: { showSummary: vars.showSummary, @@ -75,7 +76,7 @@ const ItemSettingsModal: React.FC< onChange(); }); return () => subscription.unsubscribe(); - }, [getSettings, setSettings, onChange, path, watch]); + }, [getSettings, setSettings, onChange, value.location, watch]); const { getLeftPanelElement } = useContext(PlaygroundContext); @@ -83,7 +84,7 @@ const ItemSettingsModal: React.FC< Chart settings - {path.length ? ( + {value.location.path.items.length ? ( <> {" for "} - {pathAsString(path)} + {locationAsString(value.location)} {" "} ) : ( @@ -120,7 +121,7 @@ export const ItemSettingsMenu: React.FC = (props) => { if (!enableLocalSettings) { return null; } - const settings = getSettings(props.path); + const settings = getSettings(props.value.location); const resetScroll = () => { if (!ref.current) return; @@ -139,7 +140,7 @@ export const ItemSettingsMenu: React.FC = (props) => { {settings.distributionPlotSettings || settings.chartSettings ? (