simplify settings objects (WIP)
This commit is contained in:
parent
4cdf9a6008
commit
a3187b0a15
|
@ -16,27 +16,43 @@ import {
|
||||||
import { NumberShower } from "./NumberShower";
|
import { NumberShower } from "./NumberShower";
|
||||||
import { hasMassBelowZero } from "../lib/distributionUtils";
|
import { hasMassBelowZero } from "../lib/distributionUtils";
|
||||||
|
|
||||||
export type DistributionPlottingSettings = {
|
export type PlotSettings = {
|
||||||
/** Whether to show a summary of means, stdev, percentiles etc */
|
/** Whether to show a summary of means, stdev, percentiles etc */
|
||||||
showSummary: boolean;
|
showSummary: boolean;
|
||||||
actions?: boolean;
|
/** Whether to show vega actions to the user, so they can copy the chart spec */
|
||||||
|
actions: boolean;
|
||||||
} & DistributionChartSpecOptions;
|
} & DistributionChartSpecOptions;
|
||||||
|
|
||||||
|
export const plotSettingsFromPartial = (
|
||||||
|
partial: Partial<PlotSettings>
|
||||||
|
): PlotSettings => {
|
||||||
|
return {
|
||||||
|
showSummary: false,
|
||||||
|
logX: false,
|
||||||
|
expY: false,
|
||||||
|
color: "#739ECC",
|
||||||
|
tickFormat: ".9~s",
|
||||||
|
title: "",
|
||||||
|
actions: false,
|
||||||
|
...partial,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export type DistributionChartProps = {
|
export type DistributionChartProps = {
|
||||||
distribution: Distribution;
|
distribution: Distribution;
|
||||||
width?: number;
|
width?: number;
|
||||||
height: number;
|
height: number;
|
||||||
} & DistributionPlottingSettings;
|
settings: PlotSettings;
|
||||||
|
};
|
||||||
|
|
||||||
export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
|
export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
distribution,
|
distribution,
|
||||||
height,
|
height,
|
||||||
showSummary,
|
|
||||||
width,
|
width,
|
||||||
logX,
|
settings: { showSummary, logX, actions },
|
||||||
actions = false,
|
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const shape = distribution.pointSet();
|
const shape = distribution.pointSet();
|
||||||
const [sized] = useSize((size) => {
|
const [sized] = useSize((size) => {
|
||||||
if (shape.tag === "Error") {
|
if (shape.tag === "Error") {
|
||||||
|
@ -47,7 +63,7 @@ export const DistributionChart: React.FC<DistributionChartProps> = (props) => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const spec = buildVegaSpec(props);
|
const spec = buildVegaSpec(props.settings);
|
||||||
|
|
||||||
let widthProp = width ? width : size.width;
|
let widthProp = width ? width : size.width;
|
||||||
if (widthProp < 20) {
|
if (widthProp < 20) {
|
||||||
|
@ -131,15 +147,15 @@ const SummaryTable: React.FC<SummaryTableProps> = ({ distribution }) => {
|
||||||
<table className="border border-collapse border-slate-400">
|
<table className="border border-collapse border-slate-400">
|
||||||
<thead className="bg-slate-50">
|
<thead className="bg-slate-50">
|
||||||
<tr>
|
<tr>
|
||||||
<TableHeadCell>{"Mean"}</TableHeadCell>
|
<TableHeadCell>Mean</TableHeadCell>
|
||||||
{hasResult(stdev) && <TableHeadCell>{"Stdev"}</TableHeadCell>}
|
{hasResult(stdev) && <TableHeadCell>Stdev</TableHeadCell>}
|
||||||
<TableHeadCell>{"5%"}</TableHeadCell>
|
<TableHeadCell>5%</TableHeadCell>
|
||||||
<TableHeadCell>{"10%"}</TableHeadCell>
|
<TableHeadCell>10%</TableHeadCell>
|
||||||
<TableHeadCell>{"25%"}</TableHeadCell>
|
<TableHeadCell>25%</TableHeadCell>
|
||||||
<TableHeadCell>{"50%"}</TableHeadCell>
|
<TableHeadCell>50%</TableHeadCell>
|
||||||
<TableHeadCell>{"75%"}</TableHeadCell>
|
<TableHeadCell>75%</TableHeadCell>
|
||||||
<TableHeadCell>{"90%"}</TableHeadCell>
|
<TableHeadCell>90%</TableHeadCell>
|
||||||
<TableHeadCell>{"95%"}</TableHeadCell>
|
<TableHeadCell>95%</TableHeadCell>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
|
@ -7,28 +7,42 @@ import {
|
||||||
} from "@quri/squiggle-lang";
|
} 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 { PlotSettings } from "./DistributionChart";
|
||||||
import { ErrorAlert, MessageAlert } from "./Alert";
|
import { ErrorAlert, MessageAlert } from "./Alert";
|
||||||
|
|
||||||
export type FunctionChartSettings = {
|
export type FunctionSettings = {
|
||||||
|
/** Where the function domain starts */
|
||||||
start: number;
|
start: number;
|
||||||
|
/** Where the function domain ends */
|
||||||
stop: number;
|
stop: number;
|
||||||
|
/** The amount of stops sampled */
|
||||||
count: number;
|
count: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface FunctionChartProps {
|
interface FunctionChartProps {
|
||||||
fn: lambdaValue;
|
fn: lambdaValue;
|
||||||
chartSettings: FunctionChartSettings;
|
functionSettings: FunctionSettings;
|
||||||
distributionPlotSettings: DistributionPlottingSettings;
|
plotSettings: PlotSettings;
|
||||||
environment: environment;
|
environment: environment;
|
||||||
height: number;
|
height: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const functionSettingsFromPartial = (
|
||||||
|
partial: Partial<FunctionSettings>
|
||||||
|
): FunctionSettings => {
|
||||||
|
return {
|
||||||
|
start: 0,
|
||||||
|
stop: 10,
|
||||||
|
count: 20,
|
||||||
|
...partial,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const FunctionChart: React.FC<FunctionChartProps> = ({
|
export const FunctionChart: React.FC<FunctionChartProps> = ({
|
||||||
fn,
|
fn,
|
||||||
chartSettings,
|
functionSettings,
|
||||||
environment,
|
environment,
|
||||||
distributionPlotSettings,
|
plotSettings,
|
||||||
height,
|
height,
|
||||||
}) => {
|
}) => {
|
||||||
if (fn.parameters.length > 1) {
|
if (fn.parameters.length > 1) {
|
||||||
|
@ -38,8 +52,8 @@ export const FunctionChart: React.FC<FunctionChartProps> = ({
|
||||||
</MessageAlert>
|
</MessageAlert>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const result1 = runForeign(fn, [chartSettings.start], environment);
|
const result1 = runForeign(fn, [functionSettings.start], environment);
|
||||||
const result2 = runForeign(fn, [chartSettings.stop], environment);
|
const result2 = runForeign(fn, [functionSettings.stop], environment);
|
||||||
const getValidResult = () => {
|
const getValidResult = () => {
|
||||||
if (result1.tag === "Ok") {
|
if (result1.tag === "Ok") {
|
||||||
return result1;
|
return result1;
|
||||||
|
@ -64,17 +78,17 @@ export const FunctionChart: React.FC<FunctionChartProps> = ({
|
||||||
return (
|
return (
|
||||||
<FunctionChart1Dist
|
<FunctionChart1Dist
|
||||||
fn={fn}
|
fn={fn}
|
||||||
chartSettings={chartSettings}
|
chartSettings={functionSettings}
|
||||||
environment={environment}
|
environment={environment}
|
||||||
height={height}
|
height={height}
|
||||||
distributionPlotSettings={distributionPlotSettings}
|
distributionPlotSettings={plotSettings}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case "number":
|
case "number":
|
||||||
return (
|
return (
|
||||||
<FunctionChart1Number
|
<FunctionChart1Number
|
||||||
fn={fn}
|
fn={fn}
|
||||||
chartSettings={chartSettings}
|
chartSettings={functionSettings}
|
||||||
environment={environment}
|
environment={environment}
|
||||||
height={height}
|
height={height}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -13,12 +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 {
|
import { DistributionChart, PlotSettings } from "./DistributionChart";
|
||||||
DistributionChart,
|
|
||||||
DistributionPlottingSettings,
|
|
||||||
} from "./DistributionChart";
|
|
||||||
import { NumberShower } from "./NumberShower";
|
import { NumberShower } from "./NumberShower";
|
||||||
import { ErrorAlert } from "./Alert";
|
import { ErrorAlert } from "./Alert";
|
||||||
|
import { FunctionSettings } from "./FunctionChart";
|
||||||
|
|
||||||
let SquigglePercentilesChart = createClassFromSpec({
|
let SquigglePercentilesChart = createClassFromSpec({
|
||||||
spec: percentilesSpec as Spec,
|
spec: percentilesSpec as Spec,
|
||||||
|
@ -38,16 +36,11 @@ function unwrap<a, b>(x: result<a, b>): a {
|
||||||
throw Error("FAILURE TO UNWRAP");
|
throw Error("FAILURE TO UNWRAP");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export type FunctionChartSettings = {
|
|
||||||
start: number;
|
|
||||||
stop: number;
|
|
||||||
count: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface FunctionChart1DistProps {
|
interface FunctionChart1DistProps {
|
||||||
fn: lambdaValue;
|
fn: lambdaValue;
|
||||||
chartSettings: FunctionChartSettings;
|
chartSettings: FunctionSettings;
|
||||||
distributionPlotSettings: DistributionPlottingSettings;
|
distributionPlotSettings: PlotSettings;
|
||||||
environment: environment;
|
environment: environment;
|
||||||
height: number;
|
height: number;
|
||||||
}
|
}
|
||||||
|
@ -182,7 +175,7 @@ export const FunctionChart1Dist: React.FC<FunctionChart1DistProps> = ({
|
||||||
distribution={mouseItem.value.value}
|
distribution={mouseItem.value.value}
|
||||||
width={400}
|
width={400}
|
||||||
height={50}
|
height={50}
|
||||||
{...distributionPlotSettings}
|
settings={distributionPlotSettings}
|
||||||
/>
|
/>
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@ import {
|
||||||
} from "@quri/squiggle-lang";
|
} from "@quri/squiggle-lang";
|
||||||
import { useSquiggle } from "../lib/hooks";
|
import { useSquiggle } from "../lib/hooks";
|
||||||
import { SquiggleViewer } from "./SquiggleViewer";
|
import { SquiggleViewer } from "./SquiggleViewer";
|
||||||
|
import { FunctionSettings, functionSettingsFromPartial } from "./FunctionChart";
|
||||||
|
import { PlotSettings, plotSettingsFromPartial } from "./DistributionChart";
|
||||||
|
|
||||||
export interface SquiggleChartProps {
|
export interface SquiggleChartProps {
|
||||||
/** The input string for squiggle */
|
/** The input string for squiggle */
|
||||||
|
@ -20,12 +22,8 @@ export interface SquiggleChartProps {
|
||||||
sampleCount?: number;
|
sampleCount?: number;
|
||||||
/** The amount of points returned to draw the distribution */
|
/** The amount of points returned to draw the distribution */
|
||||||
environment?: environment;
|
environment?: environment;
|
||||||
/** If the result is a function, where the function domain starts */
|
plotSettings?: PlotSettings;
|
||||||
diagramStart?: number;
|
functionSettings?: FunctionSettings;
|
||||||
/** If the result is a function, where the function domain ends */
|
|
||||||
diagramStop?: number;
|
|
||||||
/** If the result is a function, the amount of stops sampled */
|
|
||||||
diagramCount?: number;
|
|
||||||
/** When the squiggle code gets reevaluated */
|
/** When the squiggle code gets reevaluated */
|
||||||
onChange?(expr: squiggleExpression | undefined): void;
|
onChange?(expr: squiggleExpression | undefined): void;
|
||||||
/** CSS width of the element */
|
/** CSS width of the element */
|
||||||
|
@ -35,24 +33,6 @@ export interface SquiggleChartProps {
|
||||||
bindings?: bindings;
|
bindings?: bindings;
|
||||||
/** JS imported parameters */
|
/** JS imported parameters */
|
||||||
jsImports?: jsImports;
|
jsImports?: jsImports;
|
||||||
/** Whether to show a summary of the distribution */
|
|
||||||
showSummary?: boolean;
|
|
||||||
/** Set the x scale to be logarithmic by deault */
|
|
||||||
logX?: boolean;
|
|
||||||
/** Set the y scale to be exponential by deault */
|
|
||||||
expY?: boolean;
|
|
||||||
/** How to format numbers on the x axis */
|
|
||||||
tickFormat?: string;
|
|
||||||
/** Title of the graphed distribution */
|
|
||||||
title?: string;
|
|
||||||
/** Color of the graphed distribution */
|
|
||||||
color?: string;
|
|
||||||
/** Specify the lower bound of the x scale */
|
|
||||||
minX?: number;
|
|
||||||
/** Specify the upper bound of the x scale */
|
|
||||||
maxX?: number;
|
|
||||||
/** Whether to show vega actions to the user, so they can copy the chart spec */
|
|
||||||
distributionChartActions?: boolean;
|
|
||||||
enableLocalSettings?: boolean;
|
enableLocalSettings?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,19 +47,9 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = React.memo(
|
||||||
height = 200,
|
height = 200,
|
||||||
bindings = defaultBindings,
|
bindings = defaultBindings,
|
||||||
jsImports = defaultImports,
|
jsImports = defaultImports,
|
||||||
showSummary = false,
|
|
||||||
width,
|
width,
|
||||||
logX = false,
|
functionSettings,
|
||||||
expY = false,
|
plotSettings,
|
||||||
diagramStart = 0,
|
|
||||||
diagramStop = 10,
|
|
||||||
diagramCount = 100,
|
|
||||||
tickFormat,
|
|
||||||
minX,
|
|
||||||
maxX,
|
|
||||||
color,
|
|
||||||
title,
|
|
||||||
distributionChartActions,
|
|
||||||
enableLocalSettings = false,
|
enableLocalSettings = false,
|
||||||
}) => {
|
}) => {
|
||||||
const result = useSquiggle({
|
const result = useSquiggle({
|
||||||
|
@ -91,31 +61,13 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = React.memo(
|
||||||
executionId,
|
executionId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const distributionPlotSettings = {
|
|
||||||
showSummary,
|
|
||||||
logX,
|
|
||||||
expY,
|
|
||||||
format: tickFormat,
|
|
||||||
minX,
|
|
||||||
maxX,
|
|
||||||
color,
|
|
||||||
title,
|
|
||||||
actions: distributionChartActions,
|
|
||||||
};
|
|
||||||
|
|
||||||
const chartSettings = {
|
|
||||||
start: diagramStart,
|
|
||||||
stop: diagramStop,
|
|
||||||
count: diagramCount,
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SquiggleViewer
|
<SquiggleViewer
|
||||||
result={result}
|
result={result}
|
||||||
width={width}
|
width={width}
|
||||||
height={height}
|
height={height}
|
||||||
distributionPlotSettings={distributionPlotSettings}
|
plotSettings={plotSettingsFromPartial(plotSettings || {})}
|
||||||
chartSettings={chartSettings}
|
functionSettings={functionSettingsFromPartial(functionSettings || {})}
|
||||||
environment={environment ?? defaultEnvironment}
|
environment={environment ?? defaultEnvironment}
|
||||||
enableLocalSettings={enableLocalSettings}
|
enableLocalSettings={enableLocalSettings}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -6,7 +6,7 @@ import React, {
|
||||||
useRef,
|
useRef,
|
||||||
useCallback,
|
useCallback,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { useForm, UseFormRegister, useWatch } from "react-hook-form";
|
import { useForm, UseFormRegister } from "react-hook-form";
|
||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
import { useMaybeControlledValue, useRunnerState } from "../lib/hooks";
|
import { useMaybeControlledValue, useRunnerState } from "../lib/hooks";
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
|
@ -36,10 +36,8 @@ import { InputItem } from "./ui/InputItem";
|
||||||
import { Text } from "./ui/Text";
|
import { Text } from "./ui/Text";
|
||||||
import { ViewSettings, viewSettingsSchema } from "./ViewSettings";
|
import { ViewSettings, viewSettingsSchema } from "./ViewSettings";
|
||||||
import { HeadedSection } from "./ui/HeadedSection";
|
import { HeadedSection } from "./ui/HeadedSection";
|
||||||
import {
|
import { plotSettingsFromPartial } from "./DistributionChart";
|
||||||
defaultColor,
|
import { functionSettingsFromPartial } from "./FunctionChart";
|
||||||
defaultTickFormat,
|
|
||||||
} from "../lib/distributionSpecBuilder";
|
|
||||||
|
|
||||||
type PlaygroundProps = SquiggleChartProps & {
|
type PlaygroundProps = SquiggleChartProps & {
|
||||||
/** The initial squiggle string to put in the playground */
|
/** The initial squiggle string to put in the playground */
|
||||||
|
@ -52,24 +50,25 @@ type PlaygroundProps = SquiggleChartProps & {
|
||||||
};
|
};
|
||||||
|
|
||||||
const schema = yup
|
const schema = yup
|
||||||
.object({})
|
.object({
|
||||||
.shape({
|
sampleSettings: yup.object({
|
||||||
sampleCount: yup
|
sampleCount: yup
|
||||||
.number()
|
.number()
|
||||||
.required()
|
.required()
|
||||||
.positive()
|
.positive()
|
||||||
.integer()
|
.integer()
|
||||||
.default(1000)
|
.default(1000)
|
||||||
.min(10)
|
.min(10)
|
||||||
.max(1000000),
|
.max(1000000),
|
||||||
xyPointLength: yup
|
xyPointLength: yup
|
||||||
.number()
|
.number()
|
||||||
.required()
|
.required()
|
||||||
.positive()
|
.positive()
|
||||||
.integer()
|
.integer()
|
||||||
.default(1000)
|
.default(1000)
|
||||||
.min(10)
|
.min(10)
|
||||||
.max(10000),
|
.max(10000),
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
.concat(viewSettingsSchema);
|
.concat(viewSettingsSchema);
|
||||||
|
|
||||||
|
@ -81,7 +80,7 @@ const SamplingSettings: React.FC<{ register: UseFormRegister<FormFields> }> = ({
|
||||||
<div className="space-y-6 p-3 max-w-xl">
|
<div className="space-y-6 p-3 max-w-xl">
|
||||||
<div>
|
<div>
|
||||||
<InputItem
|
<InputItem
|
||||||
name="sampleCount"
|
name="sampleSettings.sampleCount"
|
||||||
type="number"
|
type="number"
|
||||||
label="Sample Count"
|
label="Sample Count"
|
||||||
register={register}
|
register={register}
|
||||||
|
@ -95,7 +94,7 @@ const SamplingSettings: React.FC<{ register: UseFormRegister<FormFields> }> = ({
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<InputItem
|
<InputItem
|
||||||
name="xyPointLength"
|
name="sampleSettings.xyPointLength"
|
||||||
type="number"
|
type="number"
|
||||||
register={register}
|
register={register}
|
||||||
label="Coordinate Count (For PointSet Shapes)"
|
label="Coordinate Count (For PointSet Shapes)"
|
||||||
|
@ -207,15 +206,8 @@ export const PlaygroundContext = React.createContext<PlaygroundContextShape>({
|
||||||
export const SquigglePlayground: FC<PlaygroundProps> = ({
|
export const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
defaultCode = "",
|
defaultCode = "",
|
||||||
height = 500,
|
height = 500,
|
||||||
showSummary = false,
|
plotSettings: initialPlotSettings,
|
||||||
logX = false,
|
functionSettings: initialFunctionSettings,
|
||||||
expY = false,
|
|
||||||
title,
|
|
||||||
minX,
|
|
||||||
maxX,
|
|
||||||
color = defaultColor,
|
|
||||||
tickFormat = defaultTickFormat,
|
|
||||||
distributionChartActions,
|
|
||||||
code: controlledCode,
|
code: controlledCode,
|
||||||
onCodeChange,
|
onCodeChange,
|
||||||
onSettingsChange,
|
onSettingsChange,
|
||||||
|
@ -229,41 +221,40 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
|
|
||||||
const [imports, setImports] = useState({});
|
const [imports, setImports] = useState({});
|
||||||
|
|
||||||
const { register, control } = useForm({
|
const defaultValues = {
|
||||||
resolver: yupResolver(schema),
|
chartHeight: 150,
|
||||||
defaultValues: {
|
showEditor,
|
||||||
|
sampleSettings: {
|
||||||
sampleCount: 1000,
|
sampleCount: 1000,
|
||||||
xyPointLength: 1000,
|
xyPointLength: 1000,
|
||||||
chartHeight: 150,
|
|
||||||
logX,
|
|
||||||
expY,
|
|
||||||
title,
|
|
||||||
minX,
|
|
||||||
maxX,
|
|
||||||
color,
|
|
||||||
tickFormat,
|
|
||||||
distributionChartActions,
|
|
||||||
showSummary,
|
|
||||||
showEditor,
|
|
||||||
diagramStart: 0,
|
|
||||||
diagramStop: 10,
|
|
||||||
diagramCount: 20,
|
|
||||||
},
|
},
|
||||||
});
|
plotSettings: plotSettingsFromPartial(initialPlotSettings || {}),
|
||||||
const vars = useWatch({
|
functionSettings: functionSettingsFromPartial(
|
||||||
control,
|
initialFunctionSettings || {}
|
||||||
});
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
const { register, watch, getValues } = useForm<FormFields>({
|
||||||
|
resolver: yupResolver(schema),
|
||||||
|
defaultValues,
|
||||||
|
});
|
||||||
|
watch();
|
||||||
|
|
||||||
|
const [settings, setSettings] = useState(() => getValues());
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
onSettingsChange?.(vars);
|
const subscription = watch(() => {
|
||||||
}, [vars, onSettingsChange]);
|
setSettings(getValues());
|
||||||
|
onSettingsChange?.(getValues());
|
||||||
|
});
|
||||||
|
return () => subscription.unsubscribe();
|
||||||
|
}, [onSettingsChange, getValues, watch]);
|
||||||
|
|
||||||
const env: environment = useMemo(
|
const env: environment = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
sampleCount: Number(vars.sampleCount),
|
sampleCount: Number(settings.sampleSettings.sampleCount),
|
||||||
xyPointLength: Number(vars.xyPointLength),
|
xyPointLength: Number(settings.sampleSettings.xyPointLength),
|
||||||
}),
|
}),
|
||||||
[vars.sampleCount, vars.xyPointLength]
|
[settings.sampleSettings.sampleCount, settings.sampleSettings.xyPointLength]
|
||||||
);
|
);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -285,7 +276,8 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
code={renderedCode}
|
code={renderedCode}
|
||||||
executionId={executionId}
|
executionId={executionId}
|
||||||
environment={env}
|
environment={env}
|
||||||
{...vars}
|
plotSettings={settings.plotSettings}
|
||||||
|
functionSettings={settings.functionSettings}
|
||||||
bindings={defaultBindings}
|
bindings={defaultBindings}
|
||||||
jsImports={imports}
|
jsImports={imports}
|
||||||
enableLocalSettings={true}
|
enableLocalSettings={true}
|
||||||
|
@ -293,7 +285,7 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const firstTab = vars.showEditor ? (
|
const firstTab = settings.showEditor ? (
|
||||||
<div className="border border-slate-200">
|
<div className="border border-slate-200">
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
value={code}
|
value={code}
|
||||||
|
@ -363,8 +355,8 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<StyledTab.List>
|
<StyledTab.List>
|
||||||
<StyledTab
|
<StyledTab
|
||||||
name={vars.showEditor ? "Code" : "Display"}
|
name={settings.showEditor ? "Code" : "Display"}
|
||||||
icon={vars.showEditor ? CodeIcon : EyeIcon}
|
icon={settings.showEditor ? CodeIcon : EyeIcon}
|
||||||
/>
|
/>
|
||||||
<StyledTab name="Sampling Settings" icon={CogIcon} />
|
<StyledTab name="Sampling Settings" icon={CogIcon} />
|
||||||
<StyledTab name="View Settings" icon={ChartSquareBarIcon} />
|
<StyledTab name="View Settings" icon={ChartSquareBarIcon} />
|
||||||
|
@ -378,7 +370,7 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
|
||||||
onAutorunModeChange={setAutorunMode}
|
onAutorunModeChange={setAutorunMode}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{vars.showEditor ? withEditor : withoutEditor}
|
{settings.showEditor ? withEditor : withoutEditor}
|
||||||
</div>
|
</div>
|
||||||
</StyledTab.Group>
|
</StyledTab.Group>
|
||||||
</PlaygroundContext.Provider>
|
</PlaygroundContext.Provider>
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from "react";
|
||||||
import { squiggleExpression, declaration } from "@quri/squiggle-lang";
|
import { squiggleExpression, declaration } from "@quri/squiggle-lang";
|
||||||
import { NumberShower } from "../NumberShower";
|
import { NumberShower } from "../NumberShower";
|
||||||
import { DistributionChart } from "../DistributionChart";
|
import { DistributionChart } from "../DistributionChart";
|
||||||
import { FunctionChart, FunctionChartSettings } from "../FunctionChart";
|
import { FunctionChart, FunctionSettings } from "../FunctionChart";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { VariableBox } from "./VariableBox";
|
import { VariableBox } from "./VariableBox";
|
||||||
import { ItemSettingsMenu } from "./ItemSettingsMenu";
|
import { ItemSettingsMenu } from "./ItemSettingsMenu";
|
||||||
|
@ -21,7 +21,7 @@ function getRange<a>(x: declaration<a>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getChartSettings<a>(x: declaration<a>): FunctionChartSettings {
|
function getFunctionSettings<a>(x: declaration<a>): FunctionSettings {
|
||||||
const range = getRange(x);
|
const range = getRange(x);
|
||||||
const min = range.floats ? range.floats.min : 0;
|
const min = range.floats ? range.floats.min : 0;
|
||||||
const max = range.floats ? range.floats.max : 10;
|
const max = range.floats ? range.floats.max : 10;
|
||||||
|
@ -96,7 +96,7 @@ export const ExpressionViewer: React.FC<Props> = ({
|
||||||
return (
|
return (
|
||||||
<DistributionChart
|
<DistributionChart
|
||||||
distribution={expression.value}
|
distribution={expression.value}
|
||||||
{...settings.distributionPlotSettings}
|
settings={settings.plotSettings}
|
||||||
height={settings.height}
|
height={settings.height}
|
||||||
width={width}
|
width={width}
|
||||||
/>
|
/>
|
||||||
|
@ -189,8 +189,8 @@ export const ExpressionViewer: React.FC<Props> = ({
|
||||||
)})`}</div>
|
)})`}</div>
|
||||||
<FunctionChart
|
<FunctionChart
|
||||||
fn={expression.value}
|
fn={expression.value}
|
||||||
chartSettings={settings.chartSettings}
|
functionSettings={settings.functionSettings}
|
||||||
distributionPlotSettings={settings.distributionPlotSettings}
|
plotSettings={settings.plotSettings}
|
||||||
height={settings.height}
|
height={settings.height}
|
||||||
environment={{
|
environment={{
|
||||||
sampleCount: settings.environment.sampleCount / 10,
|
sampleCount: settings.environment.sampleCount / 10,
|
||||||
|
@ -219,8 +219,8 @@ export const ExpressionViewer: React.FC<Props> = ({
|
||||||
{(settings) => (
|
{(settings) => (
|
||||||
<FunctionChart
|
<FunctionChart
|
||||||
fn={expression.value.fn}
|
fn={expression.value.fn}
|
||||||
chartSettings={getChartSettings(expression.value)}
|
functionSettings={getFunctionSettings(expression.value)}
|
||||||
distributionPlotSettings={settings.distributionPlotSettings}
|
plotSettings={settings.plotSettings}
|
||||||
height={settings.height}
|
height={settings.height}
|
||||||
environment={{
|
environment={{
|
||||||
sampleCount: settings.environment.sampleCount / 10,
|
sampleCount: settings.environment.sampleCount / 10,
|
||||||
|
|
|
@ -3,13 +3,13 @@ import React, { useContext, useRef, useState, useEffect } from "react";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { yupResolver } from "@hookform/resolvers/yup";
|
import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import { Modal } from "../ui/Modal";
|
import { Modal } from "../ui/Modal";
|
||||||
import { ViewSettings, viewSettingsSchema } from "../ViewSettings";
|
import {
|
||||||
|
ViewSettings,
|
||||||
|
ViewSettingsFormFields,
|
||||||
|
viewSettingsSchema,
|
||||||
|
} from "../ViewSettings";
|
||||||
import { Path, pathAsString } from "./utils";
|
import { Path, pathAsString } from "./utils";
|
||||||
import { ViewerContext } from "./ViewerContext";
|
import { ViewerContext } from "./ViewerContext";
|
||||||
import {
|
|
||||||
defaultColor,
|
|
||||||
defaultTickFormat,
|
|
||||||
} from "../../lib/distributionSpecBuilder";
|
|
||||||
import { PlaygroundContext } from "../SquigglePlayground";
|
import { PlaygroundContext } from "../SquigglePlayground";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -34,48 +34,25 @@ const ItemSettingsModal: React.FC<
|
||||||
|
|
||||||
const mergedSettings = getMergedSettings(path);
|
const mergedSettings = getMergedSettings(path);
|
||||||
|
|
||||||
const { register, watch } = useForm({
|
const { register, watch } = useForm<ViewSettingsFormFields>({
|
||||||
resolver: yupResolver(viewSettingsSchema),
|
resolver: yupResolver(viewSettingsSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
// this is a mess and should be fixed
|
|
||||||
showEditor: true, // doesn't matter
|
showEditor: true, // doesn't matter
|
||||||
chartHeight: mergedSettings.height,
|
chartHeight: mergedSettings.height,
|
||||||
showSummary: mergedSettings.distributionPlotSettings.showSummary,
|
plotSettings: mergedSettings.plotSettings,
|
||||||
logX: mergedSettings.distributionPlotSettings.logX,
|
functionSettings: mergedSettings.functionSettings,
|
||||||
expY: mergedSettings.distributionPlotSettings.expY,
|
|
||||||
tickFormat:
|
|
||||||
mergedSettings.distributionPlotSettings.format || defaultTickFormat,
|
|
||||||
title: mergedSettings.distributionPlotSettings.title,
|
|
||||||
color: mergedSettings.distributionPlotSettings.color || defaultColor,
|
|
||||||
minX: mergedSettings.distributionPlotSettings.minX,
|
|
||||||
maxX: mergedSettings.distributionPlotSettings.maxX,
|
|
||||||
distributionChartActions: mergedSettings.distributionPlotSettings.actions,
|
|
||||||
diagramStart: mergedSettings.chartSettings.start,
|
|
||||||
diagramStop: mergedSettings.chartSettings.stop,
|
|
||||||
diagramCount: mergedSettings.chartSettings.count,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const subscription = watch((vars) => {
|
const subscription = watch((vars) => {
|
||||||
const settings = getSettings(path); // get the latest version
|
const settings = getSettings(path); // get the latest version
|
||||||
setSettings(path, {
|
setSettings(path, {
|
||||||
...settings,
|
...settings,
|
||||||
distributionPlotSettings: {
|
// vars should be defined and react-hook-form is too conservative with its types so these `?.` are ok... hopefully.
|
||||||
showSummary: vars.showSummary,
|
// This might cause a bug in the future. I don't really understand why react-hook-form needs to return partials here.
|
||||||
logX: vars.logX,
|
plotSettings: vars?.plotSettings,
|
||||||
expY: vars.expY,
|
functionSettings: vars?.functionSettings,
|
||||||
format: vars.tickFormat,
|
|
||||||
title: vars.title,
|
|
||||||
color: vars.color,
|
|
||||||
minX: vars.minX,
|
|
||||||
maxX: vars.maxX,
|
|
||||||
actions: vars.distributionChartActions,
|
|
||||||
},
|
|
||||||
chartSettings: {
|
|
||||||
start: vars.diagramStart,
|
|
||||||
stop: vars.diagramStop,
|
|
||||||
count: vars.diagramCount,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
onChange();
|
onChange();
|
||||||
});
|
});
|
||||||
|
@ -141,13 +118,13 @@ export const ItemSettingsMenu: React.FC<Props> = (props) => {
|
||||||
className="h-5 w-5 cursor-pointer text-slate-400 hover:text-slate-500"
|
className="h-5 w-5 cursor-pointer text-slate-400 hover:text-slate-500"
|
||||||
onClick={() => setIsOpen(!isOpen)}
|
onClick={() => setIsOpen(!isOpen)}
|
||||||
/>
|
/>
|
||||||
{settings.distributionPlotSettings || settings.chartSettings ? (
|
{settings.plotSettings || settings.functionSettings ? (
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSettings(props.path, {
|
setSettings(props.path, {
|
||||||
...settings,
|
...settings,
|
||||||
distributionPlotSettings: undefined,
|
plotSettings: undefined,
|
||||||
chartSettings: undefined,
|
functionSettings: undefined,
|
||||||
});
|
});
|
||||||
props.onChange();
|
props.onChange();
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { defaultEnvironment } from "@quri/squiggle-lang";
|
import { defaultEnvironment } from "@quri/squiggle-lang";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { plotSettingsFromPartial } from "../DistributionChart";
|
||||||
|
import { functionSettingsFromPartial } from "../FunctionChart";
|
||||||
import { LocalItemSettings, MergedItemSettings, Path } from "./utils";
|
import { LocalItemSettings, MergedItemSettings, Path } from "./utils";
|
||||||
|
|
||||||
type ViewerContextShape = {
|
type ViewerContextShape = {
|
||||||
|
@ -17,16 +19,8 @@ export const ViewerContext = React.createContext<ViewerContextShape>({
|
||||||
getMergedSettings: () => ({
|
getMergedSettings: () => ({
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
// copy-pasted from SquiggleChart
|
// copy-pasted from SquiggleChart
|
||||||
chartSettings: {
|
plotSettings: plotSettingsFromPartial({}),
|
||||||
start: 0,
|
functionSettings: functionSettingsFromPartial({}),
|
||||||
stop: 10,
|
|
||||||
count: 100,
|
|
||||||
},
|
|
||||||
distributionPlotSettings: {
|
|
||||||
showSummary: false,
|
|
||||||
logX: false,
|
|
||||||
expY: false,
|
|
||||||
},
|
|
||||||
environment: defaultEnvironment,
|
environment: defaultEnvironment,
|
||||||
height: 150,
|
height: 150,
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React, { useCallback, useRef } from "react";
|
import React, { useCallback, useRef } from "react";
|
||||||
import { environment } from "@quri/squiggle-lang";
|
import { environment } from "@quri/squiggle-lang";
|
||||||
import { DistributionPlottingSettings } from "../DistributionChart";
|
import { PlotSettings } from "../DistributionChart";
|
||||||
import { FunctionChartSettings } from "../FunctionChart";
|
import { FunctionSettings } from "../FunctionChart";
|
||||||
import { ExpressionViewer } from "./ExpressionViewer";
|
import { ExpressionViewer } from "./ExpressionViewer";
|
||||||
import { ViewerContext } from "./ViewerContext";
|
import { ViewerContext } from "./ViewerContext";
|
||||||
import {
|
import {
|
||||||
|
@ -18,9 +18,8 @@ type Props = {
|
||||||
result: ReturnType<typeof useSquiggle>;
|
result: ReturnType<typeof useSquiggle>;
|
||||||
width?: number;
|
width?: number;
|
||||||
height: number;
|
height: number;
|
||||||
distributionPlotSettings: DistributionPlottingSettings;
|
plotSettings: PlotSettings;
|
||||||
/** Settings for displaying functions */
|
functionSettings: FunctionSettings;
|
||||||
chartSettings: FunctionChartSettings;
|
|
||||||
/** Environment for further function executions */
|
/** Environment for further function executions */
|
||||||
environment: environment;
|
environment: environment;
|
||||||
enableLocalSettings?: boolean;
|
enableLocalSettings?: boolean;
|
||||||
|
@ -36,8 +35,8 @@ export const SquiggleViewer: React.FC<Props> = ({
|
||||||
result,
|
result,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
distributionPlotSettings,
|
plotSettings,
|
||||||
chartSettings,
|
functionSettings,
|
||||||
environment,
|
environment,
|
||||||
enableLocalSettings = false,
|
enableLocalSettings = false,
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -62,13 +61,13 @@ export const SquiggleViewer: React.FC<Props> = ({
|
||||||
(path: Path) => {
|
(path: Path) => {
|
||||||
const localSettings = getSettings(path);
|
const localSettings = getSettings(path);
|
||||||
const result: MergedItemSettings = {
|
const result: MergedItemSettings = {
|
||||||
distributionPlotSettings: {
|
plotSettings: {
|
||||||
...distributionPlotSettings,
|
...plotSettings,
|
||||||
...(localSettings.distributionPlotSettings || {}),
|
...(localSettings.plotSettings || {}),
|
||||||
},
|
},
|
||||||
chartSettings: {
|
functionSettings: {
|
||||||
...chartSettings,
|
...functionSettings,
|
||||||
...(localSettings.chartSettings || {}),
|
...(localSettings.functionSettings || {}),
|
||||||
},
|
},
|
||||||
environment: {
|
environment: {
|
||||||
...environment,
|
...environment,
|
||||||
|
@ -78,7 +77,7 @@ export const SquiggleViewer: React.FC<Props> = ({
|
||||||
};
|
};
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
[distributionPlotSettings, chartSettings, environment, height, getSettings]
|
[plotSettings, functionSettings, environment, height, getSettings]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
import { DistributionPlottingSettings } from "../DistributionChart";
|
import { PlotSettings } from "../DistributionChart";
|
||||||
import { FunctionChartSettings } from "../FunctionChart";
|
import { FunctionSettings } from "../FunctionChart";
|
||||||
import { environment } from "@quri/squiggle-lang";
|
import { environment } from "@quri/squiggle-lang";
|
||||||
|
|
||||||
export type LocalItemSettings = {
|
export type LocalItemSettings = {
|
||||||
collapsed: boolean;
|
collapsed: boolean;
|
||||||
distributionPlotSettings?: Partial<DistributionPlottingSettings>;
|
plotSettings?: Partial<PlotSettings>;
|
||||||
chartSettings?: Partial<FunctionChartSettings>;
|
functionSettings?: Partial<FunctionSettings>;
|
||||||
height?: number;
|
height?: number;
|
||||||
environment?: Partial<environment>;
|
environment?: Partial<environment>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MergedItemSettings = {
|
export type MergedItemSettings = {
|
||||||
distributionPlotSettings: DistributionPlottingSettings;
|
plotSettings: PlotSettings;
|
||||||
chartSettings: FunctionChartSettings;
|
functionSettings: FunctionSettings;
|
||||||
height: number;
|
height: number;
|
||||||
environment: environment;
|
environment: environment;
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,36 +5,36 @@ import { InputItem } from "./ui/InputItem";
|
||||||
import { Checkbox } from "./ui/Checkbox";
|
import { Checkbox } from "./ui/Checkbox";
|
||||||
import { HeadedSection } from "./ui/HeadedSection";
|
import { HeadedSection } from "./ui/HeadedSection";
|
||||||
import { Text } from "./ui/Text";
|
import { Text } from "./ui/Text";
|
||||||
import {
|
|
||||||
defaultColor,
|
|
||||||
defaultTickFormat,
|
|
||||||
} from "../lib/distributionSpecBuilder";
|
|
||||||
|
|
||||||
export const viewSettingsSchema = yup.object({}).shape({
|
export const viewSettingsSchema = yup.object({}).shape({
|
||||||
chartHeight: yup.number().required().positive().integer().default(350),
|
chartHeight: yup.number().required().positive().integer().default(350),
|
||||||
showSummary: yup.boolean().required(),
|
|
||||||
showEditor: yup.boolean().required(),
|
showEditor: yup.boolean().required(),
|
||||||
logX: yup.boolean().required(),
|
plotSettings: yup.object({
|
||||||
expY: yup.boolean().required(),
|
showSummary: yup.boolean().required(),
|
||||||
tickFormat: yup.string().default(defaultTickFormat),
|
logX: yup.boolean().required(),
|
||||||
title: yup.string(),
|
expY: yup.boolean().required(),
|
||||||
color: yup.string().default(defaultColor).required(),
|
tickFormat: yup.string().required(),
|
||||||
minX: yup.number(),
|
title: yup.string().default(""),
|
||||||
maxX: yup.number(),
|
color: yup.string().required(),
|
||||||
distributionChartActions: yup.boolean(),
|
minX: yup.number(),
|
||||||
diagramStart: yup.number().required().positive().integer().default(0).min(0),
|
maxX: yup.number(),
|
||||||
diagramStop: yup.number().required().positive().integer().default(10).min(0),
|
actions: yup.boolean().required(),
|
||||||
diagramCount: yup.number().required().positive().integer().default(20).min(2),
|
}),
|
||||||
|
functionSettings: yup.object({
|
||||||
|
start: yup.number().required().positive().integer().default(0).min(0),
|
||||||
|
stop: yup.number().required().positive().integer().default(10).min(0),
|
||||||
|
count: yup.number().required().positive().integer().default(20).min(2),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
type FormFields = yup.InferType<typeof viewSettingsSchema>;
|
export type ViewSettingsFormFields = yup.InferType<typeof viewSettingsSchema>;
|
||||||
|
|
||||||
// This component is used in two places: for global settings in SquigglePlayground, and for item-specific settings in modal dialogs.
|
// This component is used in two places: for global settings in SquigglePlayground, and for item-specific settings in modal dialogs.
|
||||||
export const ViewSettings: React.FC<{
|
export const ViewSettings: React.FC<{
|
||||||
withShowEditorSetting?: boolean;
|
withShowEditorSetting?: boolean;
|
||||||
withFunctionSettings?: boolean;
|
withFunctionSettings?: boolean;
|
||||||
disableLogXSetting?: boolean;
|
disableLogXSetting?: boolean;
|
||||||
register: UseFormRegister<FormFields>;
|
register: UseFormRegister<ViewSettingsFormFields>;
|
||||||
}> = ({
|
}> = ({
|
||||||
withShowEditorSetting = true,
|
withShowEditorSetting = true,
|
||||||
withFunctionSettings = true,
|
withFunctionSettings = true,
|
||||||
|
@ -66,7 +66,7 @@ export const ViewSettings: React.FC<{
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
register={register}
|
register={register}
|
||||||
name="logX"
|
name="plotSettings.logX"
|
||||||
label="Show x scale logarithmically"
|
label="Show x scale logarithmically"
|
||||||
disabled={disableLogXSetting}
|
disabled={disableLogXSetting}
|
||||||
tooltip={
|
tooltip={
|
||||||
|
@ -77,45 +77,45 @@ export const ViewSettings: React.FC<{
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
register={register}
|
register={register}
|
||||||
name="expY"
|
name="plotSettings.expY"
|
||||||
label="Show y scale exponentially"
|
label="Show y scale exponentially"
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
register={register}
|
register={register}
|
||||||
name="distributionChartActions"
|
name="plotSettings.actions"
|
||||||
label="Show vega chart controls"
|
label="Show vega chart controls"
|
||||||
/>
|
/>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
register={register}
|
register={register}
|
||||||
name="showSummary"
|
name="plotSettings.showSummary"
|
||||||
label="Show summary statistics"
|
label="Show summary statistics"
|
||||||
/>
|
/>
|
||||||
<InputItem
|
<InputItem
|
||||||
name="minX"
|
name="plotSettings.minX"
|
||||||
type="number"
|
type="number"
|
||||||
register={register}
|
register={register}
|
||||||
label="Min X Value"
|
label="Min X Value"
|
||||||
/>
|
/>
|
||||||
<InputItem
|
<InputItem
|
||||||
name="maxX"
|
name="plotSettings.maxX"
|
||||||
type="number"
|
type="number"
|
||||||
register={register}
|
register={register}
|
||||||
label="Max X Value"
|
label="Max X Value"
|
||||||
/>
|
/>
|
||||||
<InputItem
|
<InputItem
|
||||||
name="title"
|
name="plotSettings.title"
|
||||||
type="text"
|
type="text"
|
||||||
register={register}
|
register={register}
|
||||||
label="Title"
|
label="Title"
|
||||||
/>
|
/>
|
||||||
<InputItem
|
<InputItem
|
||||||
name="tickFormat"
|
name="plotSettings.tickFormat"
|
||||||
type="text"
|
type="text"
|
||||||
register={register}
|
register={register}
|
||||||
label="Tick Format"
|
label="Tick Format"
|
||||||
/>
|
/>
|
||||||
<InputItem
|
<InputItem
|
||||||
name="color"
|
name="plotSettings.color"
|
||||||
type="color"
|
type="color"
|
||||||
register={register}
|
register={register}
|
||||||
label="Color"
|
label="Color"
|
||||||
|
@ -137,19 +137,19 @@ export const ViewSettings: React.FC<{
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<InputItem
|
<InputItem
|
||||||
type="number"
|
type="number"
|
||||||
name="diagramStart"
|
name="functionSettings.start"
|
||||||
register={register}
|
register={register}
|
||||||
label="Min X Value"
|
label="Min X Value"
|
||||||
/>
|
/>
|
||||||
<InputItem
|
<InputItem
|
||||||
type="number"
|
type="number"
|
||||||
name="diagramStop"
|
name="functionSettings.stop"
|
||||||
register={register}
|
register={register}
|
||||||
label="Max X Value"
|
label="Max X Value"
|
||||||
/>
|
/>
|
||||||
<InputItem
|
<InputItem
|
||||||
type="number"
|
type="number"
|
||||||
name="diagramCount"
|
name="functionSettings.count"
|
||||||
register={register}
|
register={register}
|
||||||
label="Points between X min and X max to sample"
|
label="Points between X min and X max to sample"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -2,20 +2,20 @@ import { VisualizationSpec } from "react-vega";
|
||||||
import type { LogScale, LinearScale, PowScale } from "vega";
|
import type { LogScale, LinearScale, PowScale } from "vega";
|
||||||
|
|
||||||
export type DistributionChartSpecOptions = {
|
export type DistributionChartSpecOptions = {
|
||||||
/** Set the x scale to be logarithmic by deault */
|
/** Set the x scale to be logarithmic by default */
|
||||||
logX: boolean;
|
logX: boolean;
|
||||||
/** Set the y scale to be exponential by deault */
|
/** Set the y scale to be exponential by default */
|
||||||
expY: boolean;
|
expY: boolean;
|
||||||
/** The minimum x coordinate shown on the chart */
|
/** The minimum x coordinate shown on the chart */
|
||||||
minX?: number;
|
minX?: number;
|
||||||
/** The maximum x coordinate shown on the chart */
|
/** The maximum x coordinate shown on the chart */
|
||||||
maxX?: number;
|
maxX?: number;
|
||||||
/** The color of the chart */
|
/** The color of the chart */
|
||||||
color?: string;
|
color: string;
|
||||||
/** The title of the chart */
|
/** The title of the chart */
|
||||||
title?: string;
|
title: string;
|
||||||
/** The formatting of the ticks */
|
/** How to format numbers on the x axis */
|
||||||
format?: string;
|
tickFormat: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export let linearXScale: LinearScale = {
|
export let linearXScale: LinearScale = {
|
||||||
|
@ -100,21 +100,10 @@ export let expYScale: PowScale = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultTickFormat = ".9~s";
|
|
||||||
export const defaultColor = "#739ECC";
|
|
||||||
|
|
||||||
export function buildVegaSpec(
|
export function buildVegaSpec(
|
||||||
specOptions: DistributionChartSpecOptions
|
specOptions: DistributionChartSpecOptions
|
||||||
): VisualizationSpec {
|
): VisualizationSpec {
|
||||||
let {
|
let { tickFormat, color, title, minX, maxX, logX, expY } = specOptions;
|
||||||
format = defaultTickFormat,
|
|
||||||
color = defaultColor,
|
|
||||||
title,
|
|
||||||
minX,
|
|
||||||
maxX,
|
|
||||||
logX,
|
|
||||||
expY,
|
|
||||||
} = specOptions;
|
|
||||||
|
|
||||||
let xScale = logX ? logXScale : linearXScale;
|
let xScale = logX ? logXScale : linearXScale;
|
||||||
if (minX !== undefined && Number.isFinite(minX)) {
|
if (minX !== undefined && Number.isFinite(minX)) {
|
||||||
|
@ -150,7 +139,7 @@ export function buildVegaSpec(
|
||||||
tickOpacity: 0.0,
|
tickOpacity: 0.0,
|
||||||
domainColor: "#fff",
|
domainColor: "#fff",
|
||||||
domainOpacity: 0.0,
|
domainOpacity: 0.0,
|
||||||
format: format,
|
format: tickFormat,
|
||||||
tickCount: 10,
|
tickCount: 10,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
Loading…
Reference in New Issue
Block a user