Merge branch 'develop' into fix-595

This commit is contained in:
Sam Nolan 2022-06-23 07:31:38 +00:00
commit 627211495e
17 changed files with 810 additions and 832 deletions

View File

@ -19,25 +19,38 @@ import {
} from "./DistributionVegaScales"; } from "./DistributionVegaScales";
import { NumberShower } from "./NumberShower"; import { NumberShower } from "./NumberShower";
type DistributionChartProps = { export type DistributionPlottingSettings = {
distribution: Distribution;
width?: number;
height: number;
/** Whether to show a summary of means, stdev, percentiles etc */ /** Whether to show a summary of means, stdev, percentiles etc */
showSummary: boolean; showSummary: boolean;
/** Whether to show the user graph controls (scale etc) */ /** Whether to show the user graph controls (scale etc) */
showControls?: boolean; showControls: boolean;
/** Set the x scale to be logarithmic by deault */
logX: boolean;
/** Set the y scale to be exponential by deault */
expY: boolean;
}; };
export type DistributionChartProps = {
distribution: Distribution;
width?: number;
height: number;
} & DistributionPlottingSettings;
export const DistributionChart: React.FC<DistributionChartProps> = ({ export const DistributionChart: React.FC<DistributionChartProps> = ({
distribution, distribution,
height, height,
showSummary, showSummary,
width, width,
showControls = false, showControls,
logX,
expY,
}) => { }) => {
const [isLogX, setLogX] = React.useState(false); const [isLogX, setLogX] = React.useState(logX);
const [isExpY, setExpY] = React.useState(false); const [isExpY, setExpY] = React.useState(expY);
React.useEffect(() => setLogX(logX), [logX]);
React.useEffect(() => setExpY(expY), [expY]);
const shape = distribution.pointSet(); const shape = distribution.pointSet();
const [sized] = useSize((size) => { const [sized] = useSize((size) => {
if (shape.tag === "Error") { if (shape.tag === "Error") {
@ -63,13 +76,19 @@ export const DistributionChart: React.FC<DistributionChartProps> = ({
return ( return (
<div style={{ width: widthProp }}> <div style={{ width: widthProp }}>
<Vega {!(isLogX && massBelow0) ? (
spec={spec} <Vega
data={{ con: shape.value.continuous, dis: shape.value.discrete }} spec={spec}
width={widthProp - 10} data={{ con: shape.value.continuous, dis: shape.value.discrete }}
height={height} width={widthProp - 10}
actions={false} height={height}
/> actions={false}
/>
) : (
<ErrorAlert heading="Log Domain Error">
Cannot graph distribution with negative values on logarithmic scale.
</ErrorAlert>
)}
<div className="flex justify-center"> <div className="flex justify-center">
{showSummary && <SummaryTable distribution={distribution} />} {showSummary && <SummaryTable distribution={distribution} />}
</div> </div>
@ -126,7 +145,7 @@ export const CheckBox: React.FC<CheckBoxProps> = ({
<span title={tooltip}> <span title={tooltip}>
<input <input
type="checkbox" type="checkbox"
value={value + ""} checked={value}
onChange={() => onChange(!value)} onChange={() => onChange(!value)}
disabled={disabled} disabled={disabled}
className="form-checkbox" className="form-checkbox"

View File

@ -2,6 +2,7 @@ import * as React from "react";
import { lambdaValue, environment, runForeign } from "@quri/squiggle-lang"; import { lambdaValue, environment, runForeign } from "@quri/squiggle-lang";
import { FunctionChart1Dist } from "./FunctionChart1Dist"; import { FunctionChart1Dist } from "./FunctionChart1Dist";
import { FunctionChart1Number } from "./FunctionChart1Number"; import { FunctionChart1Number } from "./FunctionChart1Number";
import { DistributionPlottingSettings } from "./DistributionChart";
import { ErrorAlert, MessageAlert } from "./Alert"; import { ErrorAlert, MessageAlert } from "./Alert";
export type FunctionChartSettings = { export type FunctionChartSettings = {
@ -13,6 +14,7 @@ export type FunctionChartSettings = {
interface FunctionChartProps { interface FunctionChartProps {
fn: lambdaValue; fn: lambdaValue;
chartSettings: FunctionChartSettings; chartSettings: FunctionChartSettings;
distributionPlotSettings: DistributionPlottingSettings;
environment: environment; environment: environment;
height: number; height: number;
} }
@ -21,6 +23,7 @@ export const FunctionChart: React.FC<FunctionChartProps> = ({
fn, fn,
chartSettings, chartSettings,
environment, environment,
distributionPlotSettings,
height, height,
}) => { }) => {
if (fn.parameters.length > 1) { if (fn.parameters.length > 1) {
@ -53,6 +56,7 @@ export const FunctionChart: React.FC<FunctionChartProps> = ({
chartSettings={chartSettings} chartSettings={chartSettings}
environment={environment} environment={environment}
height={height} height={height}
distributionPlotSettings={distributionPlotSettings}
/> />
); );
case "number": case "number":

View File

@ -13,7 +13,10 @@ import {
} from "@quri/squiggle-lang"; } from "@quri/squiggle-lang";
import { createClassFromSpec } from "react-vega"; import { createClassFromSpec } from "react-vega";
import * as percentilesSpec from "../vega-specs/spec-percentiles.json"; import * as percentilesSpec from "../vega-specs/spec-percentiles.json";
import { DistributionChart } from "./DistributionChart"; import {
DistributionChart,
DistributionPlottingSettings,
} from "./DistributionChart";
import { NumberShower } from "./NumberShower"; import { NumberShower } from "./NumberShower";
import { ErrorAlert } from "./Alert"; import { ErrorAlert } from "./Alert";
@ -44,6 +47,7 @@ export type FunctionChartSettings = {
interface FunctionChart1DistProps { interface FunctionChart1DistProps {
fn: lambdaValue; fn: lambdaValue;
chartSettings: FunctionChartSettings; chartSettings: FunctionChartSettings;
distributionPlotSettings: DistributionPlottingSettings;
environment: environment; environment: environment;
height: number; height: number;
} }
@ -150,6 +154,7 @@ export const FunctionChart1Dist: React.FC<FunctionChart1DistProps> = ({
fn, fn,
chartSettings, chartSettings,
environment, environment,
distributionPlotSettings,
height, height,
}) => { }) => {
let [mouseOverlay, setMouseOverlay] = React.useState(0); let [mouseOverlay, setMouseOverlay] = React.useState(0);
@ -175,7 +180,7 @@ export const FunctionChart1Dist: React.FC<FunctionChart1DistProps> = ({
distribution={mouseItem.value.value} distribution={mouseItem.value.value}
width={400} width={400}
height={50} height={50}
showSummary={false} {...distributionPlotSettings}
/> />
) : null; ) : null;

View File

@ -37,6 +37,10 @@ export interface SquiggleChartProps {
showTypes?: boolean; showTypes?: boolean;
/** Whether to show graph controls (scale etc)*/ /** Whether to show graph controls (scale etc)*/
showControls?: boolean; showControls?: boolean;
/** Set the x scale to be logarithmic by deault */
logX?: boolean;
/** Set the y scale to be exponential by deault */
expY?: boolean;
} }
const defaultOnChange = () => {}; const defaultOnChange = () => {};
@ -53,6 +57,8 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = ({
width, width,
showTypes = false, showTypes = false,
showControls = false, showControls = false,
logX = false,
expY = false,
chartSettings = defaultChartSettings, chartSettings = defaultChartSettings,
}) => { }) => {
const { result } = useSquiggle({ const { result } = useSquiggle({
@ -67,14 +73,20 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = ({
return <SquiggleErrorAlert error={result.value} />; return <SquiggleErrorAlert error={result.value} />;
} }
let distributionPlotSettings = {
showControls,
showSummary,
logX,
expY,
};
return ( return (
<SquiggleItem <SquiggleItem
expression={result.value} expression={result.value}
width={width} width={width}
height={height} height={height}
showSummary={showSummary} distributionPlotSettings={distributionPlotSettings}
showTypes={showTypes} showTypes={showTypes}
showControls={showControls}
chartSettings={chartSettings} chartSettings={chartSettings}
environment={environment ?? defaultEnvironment} environment={environment ?? defaultEnvironment}
/> />

View File

@ -54,6 +54,10 @@ export interface SquiggleEditorProps {
showControls?: boolean; showControls?: boolean;
/** Whether to show a summary table */ /** Whether to show a summary table */
showSummary?: boolean; showSummary?: boolean;
/** Whether to log the x coordinate on distribution charts */
logX?: boolean;
/** Whether to exp the y coordinate on distribution charts */
expY?: boolean;
} }
export const SquiggleEditor: React.FC<SquiggleEditorProps> = ({ export const SquiggleEditor: React.FC<SquiggleEditorProps> = ({
@ -69,8 +73,14 @@ export const SquiggleEditor: React.FC<SquiggleEditorProps> = ({
showTypes = false, showTypes = false,
showControls = false, showControls = false,
showSummary = false, showSummary = false,
logX = false,
expY = false,
}: SquiggleEditorProps) => { }: SquiggleEditorProps) => {
const [code, setCode] = useState(initialSquiggleString); const [code, setCode] = useState(initialSquiggleString);
React.useEffect(
() => setCode(initialSquiggleString),
[initialSquiggleString]
);
const { result, observableRef } = useSquiggle({ const { result, observableRef } = useSquiggle({
code, code,
@ -86,6 +96,13 @@ export const SquiggleEditor: React.FC<SquiggleEditorProps> = ({
count: diagramCount, count: diagramCount,
}; };
const distributionPlotSettings = {
showControls,
showSummary,
logX,
expY,
};
return ( return (
<div ref={observableRef}> <div ref={observableRef}>
<SquiggleContainer> <SquiggleContainer>
@ -95,9 +112,8 @@ export const SquiggleEditor: React.FC<SquiggleEditorProps> = ({
expression={result.value} expression={result.value}
width={width} width={width}
height={200} height={200}
showSummary={showSummary} distributionPlotSettings={distributionPlotSettings}
showTypes={showTypes} showTypes={showTypes}
showControls={showControls}
chartSettings={chartSettings} chartSettings={chartSettings}
environment={environment ?? defaultEnvironment} environment={environment ?? defaultEnvironment}
/> />
@ -136,6 +152,10 @@ export const SquigglePartial: React.FC<SquigglePartialProps> = ({
jsImports = defaultImports, jsImports = defaultImports,
}: SquigglePartialProps) => { }: SquigglePartialProps) => {
const [code, setCode] = useState(initialSquiggleString); const [code, setCode] = useState(initialSquiggleString);
React.useEffect(
() => setCode(initialSquiggleString),
[initialSquiggleString]
);
const { result, observableRef } = useSquigglePartial({ const { result, observableRef } = useSquigglePartial({
code, code,

View File

@ -5,7 +5,10 @@ import {
declaration, declaration,
} from "@quri/squiggle-lang"; } from "@quri/squiggle-lang";
import { NumberShower } from "./NumberShower"; import { NumberShower } from "./NumberShower";
import { DistributionChart } from "./DistributionChart"; import {
DistributionChart,
DistributionPlottingSettings,
} from "./DistributionChart";
import { FunctionChart, FunctionChartSettings } from "./FunctionChart"; import { FunctionChart, FunctionChartSettings } from "./FunctionChart";
function getRange<a>(x: declaration<a>) { function getRange<a>(x: declaration<a>) {
@ -61,12 +64,9 @@ export interface SquiggleItemProps {
expression: squiggleExpression; expression: squiggleExpression;
width?: number; width?: number;
height: number; height: number;
/** Whether to show a summary of statistics for distributions */ distributionPlotSettings: DistributionPlottingSettings;
showSummary: boolean;
/** Whether to show type information */ /** Whether to show type information */
showTypes: boolean; showTypes: boolean;
/** Whether to show users graph controls (scale etc) */
showControls: boolean;
/** Settings for displaying functions */ /** Settings for displaying functions */
chartSettings: FunctionChartSettings; chartSettings: FunctionChartSettings;
/** Environment for further function executions */ /** Environment for further function executions */
@ -77,9 +77,8 @@ export const SquiggleItem: React.FC<SquiggleItemProps> = ({
expression, expression,
width, width,
height, height,
showSummary, distributionPlotSettings,
showTypes = false, showTypes = false,
showControls = false,
chartSettings, chartSettings,
environment, environment,
}) => { }) => {
@ -104,10 +103,9 @@ export const SquiggleItem: React.FC<SquiggleItemProps> = ({
) : null} ) : null}
<DistributionChart <DistributionChart
distribution={expression.value} distribution={expression.value}
{...distributionPlotSettings}
height={height} height={height}
width={width} width={width}
showSummary={showSummary}
showControls={showControls}
/> />
</VariableBox> </VariableBox>
); );
@ -155,11 +153,10 @@ export const SquiggleItem: React.FC<SquiggleItemProps> = ({
expression={r} expression={r}
width={width !== undefined ? width - 20 : width} width={width !== undefined ? width - 20 : width}
height={50} height={50}
distributionPlotSettings={distributionPlotSettings}
showTypes={showTypes} showTypes={showTypes}
showControls={showControls}
chartSettings={chartSettings} chartSettings={chartSettings}
environment={environment} environment={environment}
showSummary={showSummary}
/> />
</div> </div>
</div> </div>
@ -181,8 +178,7 @@ export const SquiggleItem: React.FC<SquiggleItemProps> = ({
width={width !== undefined ? width - 20 : width} width={width !== undefined ? width - 20 : width}
height={height / 3} height={height / 3}
showTypes={showTypes} showTypes={showTypes}
showSummary={showSummary} distributionPlotSettings={distributionPlotSettings}
showControls={showControls}
chartSettings={chartSettings} chartSettings={chartSettings}
environment={environment} environment={environment}
/> />
@ -220,6 +216,7 @@ export const SquiggleItem: React.FC<SquiggleItemProps> = ({
<FunctionChart <FunctionChart
fn={expression.value} fn={expression.value}
chartSettings={chartSettings} chartSettings={chartSettings}
distributionPlotSettings={distributionPlotSettings}
height={height} height={height}
environment={{ environment={{
sampleCount: environment.sampleCount / 10, sampleCount: environment.sampleCount / 10,
@ -234,6 +231,7 @@ export const SquiggleItem: React.FC<SquiggleItemProps> = ({
<FunctionChart <FunctionChart
fn={expression.value.fn} fn={expression.value.fn}
chartSettings={getChartSettings(expression.value)} chartSettings={getChartSettings(expression.value)}
distributionPlotSettings={distributionPlotSettings}
height={height} height={height}
environment={{ environment={{
sampleCount: environment.sampleCount / 10, sampleCount: environment.sampleCount / 10,

View File

@ -1,4 +1,4 @@
import React, { FC, Fragment, useState } from "react"; import React, { FC, Fragment, useState, useEffect } from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import { Path, useForm, UseFormRegister, useWatch } from "react-hook-form"; import { Path, useForm, UseFormRegister, useWatch } from "react-hook-form";
import * as yup from "yup"; import * as yup from "yup";
@ -32,9 +32,14 @@ interface PlaygroundProps {
showControls?: boolean; showControls?: boolean;
/** Whether to show the summary table in the playground */ /** Whether to show the summary table in the playground */
showSummary?: boolean; showSummary?: boolean;
/** Whether to log the x coordinate on distribution charts */
logX?: boolean;
/** Whether to exp the y coordinate on distribution charts */
expY?: boolean;
/** If code is set, component becomes controlled */ /** If code is set, component becomes controlled */
code?: string; code?: string;
onCodeChange?(expr: string): void; onCodeChange?(expr: string): void;
onSettingsChange?(settings: any): void;
/** Should we show the editor? */ /** Should we show the editor? */
showEditor?: boolean; showEditor?: boolean;
} }
@ -71,6 +76,8 @@ const schema = yup
showControls: yup.boolean(), showControls: yup.boolean(),
showSummary: yup.boolean(), showSummary: yup.boolean(),
showEditor: yup.boolean(), showEditor: yup.boolean(),
logX: yup.boolean(),
expY: yup.boolean(),
showSettingsPage: yup.boolean().default(false), showSettingsPage: yup.boolean().default(false),
diagramStart: yup diagramStart: yup
.number() .number()
@ -203,8 +210,11 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
showTypes = false, showTypes = false,
showControls = false, showControls = false,
showSummary = false, showSummary = false,
logX = false,
expY = false,
code: controlledCode, code: controlledCode,
onCodeChange, onCodeChange,
onSettingsChange,
showEditor = true, showEditor = true,
}) => { }) => {
const [uncontrolledCode, setUncontrolledCode] = useState( const [uncontrolledCode, setUncontrolledCode] = useState(
@ -219,10 +229,12 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
sampleCount: 1000, sampleCount: 1000,
xyPointLength: 1000, xyPointLength: 1000,
chartHeight: 150, chartHeight: 150,
showTypes: showTypes, showTypes,
showControls: showControls, showControls,
showSummary: showSummary, logX,
showEditor: showEditor, expY,
showSummary,
showEditor,
leftSizePercent: 50, leftSizePercent: 50,
showSettingsPage: false, showSettingsPage: false,
diagramStart: 0, diagramStart: 0,
@ -233,6 +245,11 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
const vars = useWatch({ const vars = useWatch({
control, control,
}); });
useEffect(() => {
onSettingsChange?.(vars);
}, [vars, onSettingsChange]);
const chartSettings = { const chartSettings = {
start: Number(vars.diagramStart), start: Number(vars.diagramStart),
stop: Number(vars.diagramStop), stop: Number(vars.diagramStop),
@ -313,6 +330,16 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
<div className="pt-8"> <div className="pt-8">
<HeadedSection title="Distribution Display Settings"> <HeadedSection title="Distribution Display Settings">
<div className="space-y-2"> <div className="space-y-2">
<Checkbox
register={register}
name="logX"
label="Show x scale logarithmically"
/>
<Checkbox
register={register}
name="expY"
label="Show y scale exponentially"
/>
<Checkbox <Checkbox
register={register} register={register}
name="showControls" name="showControls"
@ -403,6 +430,8 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
showTypes={vars.showTypes} showTypes={vars.showTypes}
showControls={vars.showControls} showControls={vars.showControls}
showSummary={vars.showSummary} showSummary={vars.showSummary}
logX={vars.logX}
expY={vars.expY}
bindings={defaultBindings} bindings={defaultBindings}
jsImports={imports} jsImports={imports}
/> />

View File

@ -5,7 +5,7 @@ import { testRun } from "./TestHelpers";
describe("cumulative density function of a normal distribution", () => { describe("cumulative density function of a normal distribution", () => {
test("at 3 stdevs to the right of the mean is near 1", () => { test("at 3 stdevs to the right of the mean is near 1", () => {
fc.assert( fc.assert(
fc.property(fc.float(), fc.float({ min: 1e-7 }), (mean, stdev) => { fc.property(fc.integer(), fc.integer({ min: 1 }), (mean, stdev) => {
let threeStdevsAboveMean = mean + 3 * stdev; let threeStdevsAboveMean = mean + 3 * stdev;
let squiggleString = `cdf(normal(${mean}, ${stdev}), ${threeStdevsAboveMean})`; let squiggleString = `cdf(normal(${mean}, ${stdev}), ${threeStdevsAboveMean})`;
let squiggleResult = testRun(squiggleString); let squiggleResult = testRun(squiggleString);
@ -16,7 +16,7 @@ describe("cumulative density function of a normal distribution", () => {
test("at 3 stdevs to the left of the mean is near 0", () => { test("at 3 stdevs to the left of the mean is near 0", () => {
fc.assert( fc.assert(
fc.property(fc.float(), fc.float({ min: 1e-7 }), (mean, stdev) => { fc.property(fc.integer(), fc.integer({ min: 1 }), (mean, stdev) => {
let threeStdevsBelowMean = mean - 3 * stdev; let threeStdevsBelowMean = mean - 3 * stdev;
let squiggleString = `cdf(normal(${mean}, ${stdev}), ${threeStdevsBelowMean})`; let squiggleString = `cdf(normal(${mean}, ${stdev}), ${threeStdevsBelowMean})`;
let squiggleResult = testRun(squiggleString); let squiggleResult = testRun(squiggleString);

View File

@ -4,13 +4,16 @@ import * as fc from "fast-check";
// Beware: float64Array makes it appear in an infinite loop. // Beware: float64Array makes it appear in an infinite loop.
let arrayGen = () => let arrayGen = () =>
fc.float32Array({ fc
minLength: 10, .float32Array({
maxLength: 10000, minLength: 10,
noDefaultInfinity: true, maxLength: 10000,
noNaN: true, noDefaultInfinity: true,
}); noNaN: true,
})
.filter(
(xs_) => Math.min(...Array.from(xs_)) != Math.max(...Array.from(xs_))
);
describe("cumulative density function", () => { describe("cumulative density function", () => {
let n = 10000; let n = 10000;
@ -119,11 +122,7 @@ describe("cumulative density function", () => {
{ sampleCount: n, xyPointLength: 100 } { sampleCount: n, xyPointLength: 100 }
); );
let cdfValue = dist.cdf(x).value; let cdfValue = dist.cdf(x).value;
if (x < Math.min(...xs)) { expect(cdfValue).toBeGreaterThanOrEqual(0);
expect(cdfValue).toEqual(0);
} else {
expect(cdfValue).toBeGreaterThan(0);
}
}) })
); );
}); });

View File

@ -5,15 +5,11 @@ import * as fc from "fast-check";
describe("Scalar manipulation is well-modeled by javascript math", () => { describe("Scalar manipulation is well-modeled by javascript math", () => {
test("in the case of natural logarithms", () => { test("in the case of natural logarithms", () => {
fc.assert( fc.assert(
fc.property(fc.float(), (x) => { fc.property(fc.integer(), (x) => {
let squiggleString = `log(${x})`; let squiggleString = `log(${x})`;
let squiggleResult = testRun(squiggleString); let squiggleResult = testRun(squiggleString);
if (x == 0) { if (x == 0) {
expect(squiggleResult.value).toEqual(-Infinity); expect(squiggleResult.value).toEqual(-Infinity);
} else if (x < 0) {
expect(squiggleResult.value).toEqual(
"somemessage (confused why a test case hasn't pointed out to me that this message is bogus)"
);
} else { } else {
expect(squiggleResult.value).toEqual(Math.log(x)); expect(squiggleResult.value).toEqual(Math.log(x));
} }
@ -23,7 +19,7 @@ describe("Scalar manipulation is well-modeled by javascript math", () => {
test("in the case of addition (with assignment)", () => { test("in the case of addition (with assignment)", () => {
fc.assert( fc.assert(
fc.property(fc.float(), fc.float(), fc.float(), (x, y, z) => { fc.property(fc.integer(), fc.integer(), fc.integer(), (x, y, z) => {
let squiggleString = `x = ${x}; y = ${y}; z = ${z}; x + y + z`; let squiggleString = `x = ${x}; y = ${y}; z = ${z}; x + y + z`;
let squiggleResult = testRun(squiggleString); let squiggleResult = testRun(squiggleString);
expect(squiggleResult.value).toBeCloseTo(x + y + z); expect(squiggleResult.value).toBeCloseTo(x + y + z);

View File

@ -1,11 +1,10 @@
import { errorValueToString } from "../../src/js/index";
import { testRun } from "./TestHelpers"; import { testRun } from "./TestHelpers";
import * as fc from "fast-check"; import * as fc from "fast-check";
describe("Symbolic mean", () => { describe("Symbolic mean", () => {
test("mean(triangular(x,y,z))", () => { test("mean(triangular(x,y,z))", () => {
fc.assert( fc.assert(
fc.property(fc.float(), fc.float(), fc.float(), (x, y, z) => { fc.property(fc.integer(), fc.integer(), fc.integer(), (x, y, z) => {
if (!(x < y && y < z)) { if (!(x < y && y < z)) {
try { try {
let squiggleResult = testRun(`mean(triangular(${x},${y},${z}))`); let squiggleResult = testRun(`mean(triangular(${x},${y},${z}))`);

View File

@ -19,7 +19,7 @@ do
fi fi
done done
files=`ls src/rescript/**/**/*.resi src/rescript/**/*.resi` # src/rescript/*/resi files=`ls src/rescript/**/*.resi` # src/rescript/*/resi
for file in $files for file in $files
do do
current=`cat $file` current=`cat $file`

View File

@ -51,7 +51,7 @@
"bisect_ppx": "^2.7.1", "bisect_ppx": "^2.7.1",
"chalk": "^5.0.1", "chalk": "^5.0.1",
"codecov": "^3.8.3", "codecov": "^3.8.3",
"fast-check": "^2.25.0", "fast-check": "^3.0.0",
"gentype": "^4.4.0", "gentype": "^4.4.0",
"jest": "^27.5.1", "jest": "^27.5.1",
"moduleserve": "^0.9.1", "moduleserve": "^0.9.1",

View File

@ -6,11 +6,13 @@ This website is built using [Docusaurus 2](https://docusaurus.io/), a modern sta
We assume you ran `yarn` at monorepo level. We assume you ran `yarn` at monorepo level.
The website depends on `squiggle-lang`, which you have to build manually. The website depends on `squiggle-lang` and `components`, which you have to build manually.
```sh ```sh
cd ../squiggle-lang cd ../squiggle-lang
yarn build yarn build
cd ../components
yarn build
``` ```
Generate static content, to the `build` directory. Generate static content, to the `build` directory.

View File

@ -15,8 +15,10 @@
"@docusaurus/core": "2.0.0-beta.21", "@docusaurus/core": "2.0.0-beta.21",
"@docusaurus/preset-classic": "2.0.0-beta.21", "@docusaurus/preset-classic": "2.0.0-beta.21",
"@quri/squiggle-components": "^0.2.20", "@quri/squiggle-components": "^0.2.20",
"base64-js": "^1.5.1",
"clsx": "^1.1.1", "clsx": "^1.1.1",
"hast-util-is-element": "2.1.2", "hast-util-is-element": "2.1.2",
"pako": "^2.0.4",
"prism-react-renderer": "^1.3.3", "prism-react-renderer": "^1.3.3",
"react": "^18.1.0", "react": "^18.1.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",

View File

@ -1,8 +1,52 @@
import { deflate, inflate } from "pako";
import { toByteArray, fromByteArray } from "base64-js";
import React from "react"; import React from "react";
import Layout from "@theme/Layout"; import Layout from "@theme/Layout";
import { SquigglePlayground } from "../components/SquigglePlayground"; import { SquigglePlayground } from "../components/SquigglePlayground";
const HASH_PREFIX = "#code=";
function getHashData() {
if (typeof window === "undefined") {
return {};
}
const hash = window.location.hash;
if (!hash.startsWith(HASH_PREFIX)) {
return {};
}
try {
const compressed = toByteArray(
decodeURIComponent(hash.slice(HASH_PREFIX.length))
);
const text = inflate(compressed, { to: "string" });
return JSON.parse(text);
} catch (err) {
console.error(err);
return {};
}
}
function setHashData(data) {
const text = JSON.stringify({ ...getHashData(), ...data });
const compressed = deflate(text, { level: 9 });
window.history.replaceState(
undefined,
"",
HASH_PREFIX + encodeURIComponent(fromByteArray(compressed))
);
}
export default function PlaygroundPage() { export default function PlaygroundPage() {
const playgroundProps = {
initialSquiggleString: "normal(0,1)",
height: 700,
showTypes: true,
...getHashData(),
onCodeChange: (code) => setHashData({ initialSquiggleString: code }),
onSettingsChange: (settings) => {
const { showTypes, showControls, showSummary, showEditor } = settings;
setHashData({ showTypes, showControls, showSummary, showEditor });
},
};
return ( return (
<Layout title="Playground" description="Squiggle Playground"> <Layout title="Playground" description="Squiggle Playground">
<div <div
@ -10,11 +54,7 @@ export default function PlaygroundPage() {
maxWidth: 2000, maxWidth: 2000,
}} }}
> >
<SquigglePlayground <SquigglePlayground {...playgroundProps} />
initialSquiggleString="normal(0,1)"
height={700}
showTypes={true}
/>
</div> </div>
</Layout> </Layout>
); );

1377
yarn.lock

File diff suppressed because it is too large Load Diff