Compare commits

...

3 Commits

Author SHA1 Message Date
ab3cb82f98 feat: Ask for % confidence interval, not for toggle. 2022-06-24 12:38:47 -04:00
be8edcba13 fix: run yarn format 2022-06-24 12:22:16 -04:00
872204d38e feat: Add toggle to display 95th % confidece interval
Toggle propagated to all elements,
and as such this commit might serve as a template
for how to do a similar thing in the future
2022-06-24 12:14:17 -04:00
4 changed files with 77 additions and 2 deletions

View File

@ -28,6 +28,7 @@ export type DistributionPlottingSettings = {
logX: boolean; logX: boolean;
/** Set the y scale to be exponential by deault */ /** Set the y scale to be exponential by deault */
expY: boolean; expY: boolean;
truncateToNthci: number;
}; };
export type DistributionChartProps = { export type DistributionChartProps = {
@ -44,6 +45,7 @@ export const DistributionChart: React.FC<DistributionChartProps> = ({
showControls, showControls,
logX, logX,
expY, expY,
truncateToNthci,
}) => { }) => {
const [isLogX, setLogX] = React.useState(logX); const [isLogX, setLogX] = React.useState(logX);
const [isExpY, setExpY] = React.useState(expY); const [isExpY, setExpY] = React.useState(expY);
@ -51,8 +53,54 @@ export const DistributionChart: React.FC<DistributionChartProps> = ({
React.useEffect(() => setLogX(logX), [logX]); React.useEffect(() => setLogX(logX), [logX]);
React.useEffect(() => setExpY(expY), [expY]); React.useEffect(() => setExpY(expY), [expY]);
const shape = distribution.pointSet();
const [sized] = useSize((size) => { const [sized] = useSize((size) => {
const delta = truncateToNthci / 100 / 2;
if (truncateToNthci <= 0 || truncateToNthci > 100) {
return (
<ErrorAlert heading="Confidence interval error">
{"Confidence interval must be between 0 and 100"}
</ErrorAlert>
);
}
const pMinwrapped = distribution.inv(0.5 - delta);
const pMaxwrapped = distribution.inv(0.5 + delta);
if (pMinwrapped.tag == "Error") {
return (
<ErrorAlert heading="Distribution Calculation Error">
{distributionErrorToString(pMinwrapped.value)}
</ErrorAlert>
);
} else if (pMaxwrapped.tag == "Error") {
return (
<ErrorAlert heading="Distribution Calculation Error">
{distributionErrorToString(pMaxwrapped.value)}
</ErrorAlert>
);
}
const pMin = pMinwrapped.value;
const pMax = pMaxwrapped.value;
const truncatedDistributionWrapper = distribution.truncate(pMin, pMax);
if (truncatedDistributionWrapper.tag == "Error") {
return (
<ErrorAlert heading="Distribution Truncation For Display Error">
{distributionErrorToString(truncatedDistributionWrapper.value)}
</ErrorAlert>
);
}
const truncatedDistribution = truncatedDistributionWrapper.value;
const shape = distribution.pointSet();
const shapeTruncated = truncatedDistribution.pointSet(); // distribution.pointSet();
if (shapeTruncated.tag === "Error") {
return (
<ErrorAlert heading="Distribution Error">
{distributionErrorToString(shapeTruncated.value)}
</ErrorAlert>
);
}
if (shape.tag === "Error") { if (shape.tag === "Error") {
return ( return (
<ErrorAlert heading="Distribution Error"> <ErrorAlert heading="Distribution Error">
@ -79,7 +127,14 @@ export const DistributionChart: React.FC<DistributionChartProps> = ({
{!(isLogX && massBelow0) ? ( {!(isLogX && massBelow0) ? (
<Vega <Vega
spec={spec} spec={spec}
data={{ con: shape.value.continuous, dis: shape.value.discrete }} data={
truncateToNthci != 100
? {
con: shapeTruncated.value.continuous,
dis: shapeTruncated.value.discrete,
}
: { con: shape.value.continuous, dis: shape.value.discrete }
}
width={widthProp - 10} width={widthProp - 10}
height={height} height={height}
actions={false} actions={false}

View File

@ -41,6 +41,8 @@ export interface SquiggleChartProps {
logX?: boolean; logX?: boolean;
/** Set the y scale to be exponential by deault */ /** Set the y scale to be exponential by deault */
expY?: boolean; expY?: boolean;
/** Display 94% interval; useful for thin lognormals */
truncateToNthci?: number;
} }
const defaultOnChange = () => {}; const defaultOnChange = () => {};
@ -59,6 +61,7 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = ({
showControls = false, showControls = false,
logX = false, logX = false,
expY = false, expY = false,
truncateToNthci = 100,
chartSettings = defaultChartSettings, chartSettings = defaultChartSettings,
}) => { }) => {
const { result } = useSquiggle({ const { result } = useSquiggle({
@ -78,6 +81,7 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = ({
showSummary, showSummary,
logX, logX,
expY, expY,
truncateToNthci,
}; };
return ( return (

View File

@ -58,6 +58,8 @@ export interface SquiggleEditorProps {
logX?: boolean; logX?: boolean;
/** Whether to exp the y coordinate on distribution charts */ /** Whether to exp the y coordinate on distribution charts */
expY?: boolean; expY?: boolean;
/** Display 94% interval; useful for thin lognormals */
truncateToNthci?: number;
} }
export const SquiggleEditor: React.FC<SquiggleEditorProps> = ({ export const SquiggleEditor: React.FC<SquiggleEditorProps> = ({
@ -75,6 +77,7 @@ export const SquiggleEditor: React.FC<SquiggleEditorProps> = ({
showSummary = false, showSummary = false,
logX = false, logX = false,
expY = false, expY = false,
truncateToNthci = 100,
}: SquiggleEditorProps) => { }: SquiggleEditorProps) => {
const [code, setCode] = useState(initialSquiggleString); const [code, setCode] = useState(initialSquiggleString);
React.useEffect( React.useEffect(
@ -101,6 +104,7 @@ export const SquiggleEditor: React.FC<SquiggleEditorProps> = ({
showSummary, showSummary,
logX, logX,
expY, expY,
truncateToNthci,
}; };
return ( return (

View File

@ -36,6 +36,8 @@ interface PlaygroundProps {
logX?: boolean; logX?: boolean;
/** Whether to exp the y coordinate on distribution charts */ /** Whether to exp the y coordinate on distribution charts */
expY?: boolean; expY?: boolean;
/** Display 94% interval; useful for thin lognormals */
truncateToNthci?: number;
/** 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;
@ -78,6 +80,7 @@ const schema = yup
showEditor: yup.boolean(), showEditor: yup.boolean(),
logX: yup.boolean(), logX: yup.boolean(),
expY: yup.boolean(), expY: yup.boolean(),
truncateToNthci: yup.number().required().min(0).max(100).default(100),
showSettingsPage: yup.boolean().default(false), showSettingsPage: yup.boolean().default(false),
diagramStart: yup diagramStart: yup
.number() .number()
@ -212,6 +215,7 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
showSummary = false, showSummary = false,
logX = false, logX = false,
expY = false, expY = false,
truncateToNthci = 100,
code: controlledCode, code: controlledCode,
onCodeChange, onCodeChange,
onSettingsChange, onSettingsChange,
@ -233,6 +237,7 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
showControls, showControls,
logX, logX,
expY, expY,
truncateToNthci,
showSummary, showSummary,
showEditor, showEditor,
leftSizePercent: 50, leftSizePercent: 50,
@ -340,6 +345,12 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
name="expY" name="expY"
label="Show y scale exponentially" label="Show y scale exponentially"
/> />
<InputItem
name="truncateToNthci"
type="number"
register={register}
label="Show nth percentile confidence interval (useful for thin lognormals)"
/>
<Checkbox <Checkbox
register={register} register={register}
name="showControls" name="showControls"
@ -432,6 +443,7 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
showSummary={vars.showSummary} showSummary={vars.showSummary}
logX={vars.logX} logX={vars.logX}
expY={vars.expY} expY={vars.expY}
truncateToNthci={vars.truncateToNthci}
bindings={defaultBindings} bindings={defaultBindings}
jsImports={imports} jsImports={imports}
/> />