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
This commit is contained in:
NunoSempere 2022-06-24 12:12:50 -04:00
parent 4ca6c99205
commit 872204d38e
4 changed files with 65 additions and 7 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;
truncateTo95ci: boolean;
}; };
export type DistributionChartProps = { export type DistributionChartProps = {
@ -44,6 +45,7 @@ export const DistributionChart: React.FC<DistributionChartProps> = ({
showControls, showControls,
logX, logX,
expY, expY,
truncateTo95ci,
}) => { }) => {
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,41 @@ 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 p3wrapped = distribution.inv(0.025);
const p97wrapped = distribution.inv(0.975);
if (p3wrapped.tag == "Error") {
return <ErrorAlert heading="Distribution Calculation Error">
{distributionErrorToString(p3wrapped.value)}
</ErrorAlert>
} else if (p97wrapped.tag == "Error") {
return <ErrorAlert heading="Distribution Calculation Error">
{distributionErrorToString(p97wrapped.value)}
</ErrorAlert>
}
const p3 = p3wrapped.value
const p97 = p97wrapped.value
const truncatedDistributionWrapper = distribution.truncate(p3, p97)
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 +114,11 @@ 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={
truncateTo95ci ?
{ 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}
@ -101,10 +140,10 @@ export const DistributionChart: React.FC<DistributionChartProps> = ({
// Check whether we should disable the checkbox // Check whether we should disable the checkbox
{...(massBelow0 {...(massBelow0
? { ? {
disabled: true, disabled: true,
tooltip: tooltip:
"Your distribution has mass lower than or equal to 0. Log only works on strictly positive values.", "Your distribution has mass lower than or equal to 0. Log only works on strictly positive values.",
} }
: {})} : {})}
/> />
<CheckBox label="Exp Y scale" value={isExpY} onChange={setExpY} /> <CheckBox label="Exp Y scale" value={isExpY} onChange={setExpY} />

View File

@ -41,9 +41,11 @@ 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 */
truncateTo95ci?: boolean;
} }
const defaultOnChange = () => {}; const defaultOnChange = () => { };
const defaultChartSettings = { start: 0, stop: 10, count: 20 }; const defaultChartSettings = { start: 0, stop: 10, count: 20 };
export const SquiggleChart: React.FC<SquiggleChartProps> = ({ export const SquiggleChart: React.FC<SquiggleChartProps> = ({
@ -59,6 +61,7 @@ export const SquiggleChart: React.FC<SquiggleChartProps> = ({
showControls = false, showControls = false,
logX = false, logX = false,
expY = false, expY = false,
truncateTo95ci = false,
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,
truncateTo95ci,
}; };
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 */
truncateTo95ci?: boolean;
} }
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,
truncateTo95ci = false,
}: 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,
truncateTo95ci
}; };
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 */
truncateTo95ci?: 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;
@ -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(),
truncateTo95ci: yup.boolean(),
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,
truncateTo95ci = false,
code: controlledCode, code: controlledCode,
onCodeChange, onCodeChange,
onSettingsChange, onSettingsChange,
@ -233,6 +237,7 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
showControls, showControls,
logX, logX,
expY, expY,
truncateTo95ci,
showSummary, showSummary,
showEditor, showEditor,
leftSizePercent: 50, leftSizePercent: 50,
@ -340,6 +345,11 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
name="expY" name="expY"
label="Show y scale exponentially" label="Show y scale exponentially"
/> />
<Checkbox
register={register}
name="truncateTo95ci"
label="Show 95th percentile confidence interval (useful for thin lognormals)"
/>
<Checkbox <Checkbox
register={register} register={register}
name="showControls" name="showControls"
@ -432,6 +442,7 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
showSummary={vars.showSummary} showSummary={vars.showSummary}
logX={vars.logX} logX={vars.logX}
expY={vars.expY} expY={vars.expY}
truncateTo95ci={vars.truncateTo95ci}
bindings={defaultBindings} bindings={defaultBindings}
jsImports={imports} jsImports={imports}
/> />