Added storybook stories for most SquiggleChart Types
This commit is contained in:
parent
20f93539ad
commit
012a1e4793
|
@ -11,7 +11,6 @@
|
||||||
"@types/lodash": "^4.14.181",
|
"@types/lodash": "^4.14.181",
|
||||||
"@types/node": "^17.0.24",
|
"@types/node": "^17.0.24",
|
||||||
"@types/react": "^18.0.3",
|
"@types/react": "^18.0.3",
|
||||||
"@types/styled-components": "^5.1.25",
|
|
||||||
"@types/react-dom": "^18.0.1",
|
"@types/react-dom": "^18.0.1",
|
||||||
"antd": "^4.19.3",
|
"antd": "^4.19.3",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
|
|
|
@ -12,6 +12,105 @@ import { DistributionChart } from "./DistributionChart";
|
||||||
import { ErrorBox } from "./ErrorBox";
|
import { ErrorBox } from "./ErrorBox";
|
||||||
import useSize from "@react-hook/size";
|
import useSize from "@react-hook/size";
|
||||||
|
|
||||||
|
const variableBox = {
|
||||||
|
Component: styled.div`
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
border-radius: 2px;
|
||||||
|
margin-bottom: 0.4em;
|
||||||
|
`,
|
||||||
|
Heading: styled.div`
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding-left: 0.8em;
|
||||||
|
padding-right: 0.8em;
|
||||||
|
padding-top: 0.1em;
|
||||||
|
`,
|
||||||
|
Body: styled.div`
|
||||||
|
padding: 0.4em 0.8em;
|
||||||
|
`,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const VariableBox: React.FC<{
|
||||||
|
heading: string;
|
||||||
|
children: React.ReactNode;
|
||||||
|
}> = ({ heading = "Error", children }) => {
|
||||||
|
return (
|
||||||
|
<variableBox.Component>
|
||||||
|
<variableBox.Heading>
|
||||||
|
<h3>{heading}</h3>
|
||||||
|
</variableBox.Heading>
|
||||||
|
<variableBox.Body>{children}</variableBox.Body>
|
||||||
|
</variableBox.Component>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface SquiggleItemProps {
|
||||||
|
/** The input string for squiggle */
|
||||||
|
expression: squiggleExpression;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const SquiggleItem: React.FC<SquiggleItemProps> = ({
|
||||||
|
expression,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
}: SquiggleItemProps) => {
|
||||||
|
if (expression.tag === "number") {
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Number">
|
||||||
|
<NumberShower precision={3} number={expression.value} />
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
} else if (expression.tag === "distribution") {
|
||||||
|
let distType = expression.value.type();
|
||||||
|
return (
|
||||||
|
<VariableBox heading={`Distribution (${distType})`}>
|
||||||
|
{distType === "Symbolic" ? (
|
||||||
|
<>
|
||||||
|
<div>{expression.value.toString()}</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
<DistributionChart
|
||||||
|
distribution={expression.value}
|
||||||
|
height={height}
|
||||||
|
width={width}
|
||||||
|
/>
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
} else if (expression.tag === "string") {
|
||||||
|
return (
|
||||||
|
<VariableBox heading="String">{`"${expression.value}"`}</VariableBox>
|
||||||
|
);
|
||||||
|
} else if (expression.tag === "boolean") {
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Boolean">
|
||||||
|
{expression.value == true ? "True" : "False"}
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
} else if (expression.tag === "symbol") {
|
||||||
|
return <VariableBox heading="Symbol">{expression.value}</VariableBox>;
|
||||||
|
} else if (expression.tag === "call") {
|
||||||
|
return <VariableBox heading="Call">{expression.value}</VariableBox>;
|
||||||
|
} else if (expression.tag === "array") {
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Array">
|
||||||
|
{expression.value.map((r) => (
|
||||||
|
<SquiggleItem expression={r} width={width - 20} height={50} />
|
||||||
|
))}
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<ErrorBox heading="No Viewer">
|
||||||
|
{"We don't currently have a viewer for record types."}
|
||||||
|
</ErrorBox>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export interface SquiggleChartProps {
|
export interface SquiggleChartProps {
|
||||||
/** The input string for squiggle */
|
/** The input string for squiggle */
|
||||||
squiggleString?: string;
|
squiggleString?: string;
|
||||||
|
@ -36,105 +135,6 @@ export interface SquiggleChartProps {
|
||||||
height?: number;
|
height?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SquiggleItemProps {
|
|
||||||
/** The input string for squiggle */
|
|
||||||
expression: squiggleExpression;
|
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ShowBox = styled.div`
|
|
||||||
background: white;
|
|
||||||
border: 1px solid #eee;
|
|
||||||
border-radius: 2px;
|
|
||||||
margin-bottom: 0.4em;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const ShowBoxHeading = styled.div`
|
|
||||||
border-bottom: 1px solid #eee;
|
|
||||||
padding-left: 0.8em;
|
|
||||||
padding-right: 0.8em;
|
|
||||||
padding-top: 0.1em;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const ShowBoxPadding = styled.div`
|
|
||||||
padding: 0.4em 0.8em;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const Box: React.FC<{
|
|
||||||
heading: string;
|
|
||||||
children: React.ReactNode;
|
|
||||||
}> = ({ heading = "Error", children }) => {
|
|
||||||
return (
|
|
||||||
<ShowBox>
|
|
||||||
<ShowBoxHeading>
|
|
||||||
<h3>{heading}</h3>
|
|
||||||
</ShowBoxHeading>
|
|
||||||
<ShowBoxPadding>{children}</ShowBoxPadding>
|
|
||||||
</ShowBox>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const SquiggleItem: React.FC<SquiggleItemProps> = ({
|
|
||||||
expression,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
}: SquiggleItemProps) => {
|
|
||||||
if (expression.tag === "number") {
|
|
||||||
return (
|
|
||||||
<Box heading="Number">
|
|
||||||
<NumberShower precision={3} number={expression.value} />
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
} else if (expression.tag === "distribution") {
|
|
||||||
let distType = expression.value.type();
|
|
||||||
return (
|
|
||||||
<Box heading={`Distribution (${distType})`}>
|
|
||||||
{distType === "Symbolic" ? (
|
|
||||||
<>
|
|
||||||
<div>{expression.value.toString()}</div>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
<DistributionChart
|
|
||||||
distribution={expression.value}
|
|
||||||
height={height}
|
|
||||||
width={width}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
} else if (expression.tag === "string") {
|
|
||||||
return <Box heading="String">{`"${expression.value}"`}</Box>;
|
|
||||||
} else if (expression.tag === "boolean") {
|
|
||||||
return (
|
|
||||||
<Box heading="Boolean">
|
|
||||||
({expression.value == true ? "True" : "False"})
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
} else if (expression.tag === "symbol") {
|
|
||||||
return <Box heading="Symbol">({expression.value})</Box>;
|
|
||||||
} else if (expression.tag === "call") {
|
|
||||||
return <Box heading="Call">({expression.value})</Box>;
|
|
||||||
} else if (expression.tag === "array") {
|
|
||||||
return (
|
|
||||||
<Box heading="Array">
|
|
||||||
<div>
|
|
||||||
{expression.value.map((r) => (
|
|
||||||
<SquiggleItem expression={r} width={width - 20} height={50} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<ErrorBox heading="No Viewer">
|
|
||||||
{"We don't currently have a viewer for record types."}
|
|
||||||
</ErrorBox>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const SquiggleChart: React.FC<SquiggleChartProps> = ({
|
export const SquiggleChart: React.FC<SquiggleChartProps> = ({
|
||||||
squiggleString = "",
|
squiggleString = "",
|
||||||
sampleCount = 1000,
|
sampleCount = 1000,
|
||||||
|
|
|
@ -45,14 +45,13 @@ interface Props2 {
|
||||||
const ShowBox = styled.div<Props2>`
|
const ShowBox = styled.div<Props2>`
|
||||||
border: 1px solid #eee;
|
border: 1px solid #eee;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
height: ${props => props.height};
|
height: ${(props) => props.height};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const MyComponent = styled.div`
|
const MyComponent = styled.div`
|
||||||
color: ${props => props.theme.colors.main};
|
color: ${(props) => props.theme.colors.main};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
||||||
interface TitleProps {
|
interface TitleProps {
|
||||||
readonly maxHeight: number;
|
readonly maxHeight: number;
|
||||||
}
|
}
|
||||||
|
@ -63,10 +62,13 @@ const Display = styled.div<TitleProps>`
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
max-height: ${props => props.maxHeight}px;
|
max-height: ${(props) => props.maxHeight}px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
let SquigglePlayground: FC<Props> = ({ initialSquiggleString = "", height = 300 }: Props) => {
|
let SquigglePlayground: FC<Props> = ({
|
||||||
|
initialSquiggleString = "",
|
||||||
|
height = 300,
|
||||||
|
}: Props) => {
|
||||||
let [squiggleString, setSquiggleString] = useState(initialSquiggleString);
|
let [squiggleString, setSquiggleString] = useState(initialSquiggleString);
|
||||||
let [sampleCount, setSampleCount] = useState(1000);
|
let [sampleCount, setSampleCount] = useState(1000);
|
||||||
let [outputXYPoints, setOutputXYPoints] = useState(1000);
|
let [outputXYPoints, setOutputXYPoints] = useState(1000);
|
||||||
|
@ -87,7 +89,7 @@ let SquigglePlayground: FC<Props> = ({ initialSquiggleString = "", height = 300
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={12}>
|
<Col span={12}>
|
||||||
<Display maxHeight={height-3}>
|
<Display maxHeight={height - 3}>
|
||||||
<SquiggleChart
|
<SquiggleChart
|
||||||
squiggleString={squiggleString}
|
squiggleString={squiggleString}
|
||||||
sampleCount={sampleCount}
|
sampleCount={sampleCount}
|
||||||
|
|
|
@ -8,7 +8,7 @@ export const Template = SquiggleChart;
|
||||||
We have to hardcode a width here, because otherwise some interaction with
|
We have to hardcode a width here, because otherwise some interaction with
|
||||||
Storybook creates an infinite loop with the internal width
|
Storybook creates an infinite loop with the internal width
|
||||||
*/
|
*/
|
||||||
const width = 500;
|
const width = 600;
|
||||||
|
|
||||||
# Squiggle Chart
|
# Squiggle Chart
|
||||||
|
|
||||||
|
@ -23,11 +23,11 @@ could be continuous, discrete or mixed.
|
||||||
|
|
||||||
## Distributions
|
## Distributions
|
||||||
|
|
||||||
### Continuous Distributions
|
### Continuous Distributions (Symbolic)
|
||||||
|
|
||||||
<Canvas>
|
<Canvas>
|
||||||
<Story
|
<Story
|
||||||
name="Normal"
|
name="Continuous Symbolic"
|
||||||
args={{
|
args={{
|
||||||
squiggleString: "normal(5,2)",
|
squiggleString: "normal(5,2)",
|
||||||
width,
|
width,
|
||||||
|
@ -37,6 +37,34 @@ could be continuous, discrete or mixed.
|
||||||
</Story>
|
</Story>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
|
||||||
|
### Continuous Distributions (PointSet)
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story
|
||||||
|
name="Continuous Pointset"
|
||||||
|
args={{
|
||||||
|
squiggleString: "toPointSet(normal(5,2))",
|
||||||
|
width,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{Template.bind({})}
|
||||||
|
</Story>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
### Continuous Distributions (SampleSet)
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story
|
||||||
|
name="Continuous SampleSet"
|
||||||
|
args={{
|
||||||
|
squiggleString: "toSampleSet(normal(5,2), 1000)",
|
||||||
|
width,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{Template.bind({})}
|
||||||
|
</Story>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
### Discrete Distributions
|
### Discrete Distributions
|
||||||
|
|
||||||
<Canvas>
|
<Canvas>
|
||||||
|
@ -83,17 +111,13 @@ to allow large and small numbers being printed cleanly.
|
||||||
</Story>
|
</Story>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
|
||||||
## Functions
|
## Arrays
|
||||||
|
|
||||||
Full functions can be returned. These plot out the results of distributions between a set of x-coordinates.
|
|
||||||
|
|
||||||
The default is show 10 points between 0 and 10.
|
|
||||||
|
|
||||||
<Canvas>
|
<Canvas>
|
||||||
<Story
|
<Story
|
||||||
name="Function"
|
name="Array"
|
||||||
args={{
|
args={{
|
||||||
squiggleString: "f(x) = normal(x^2,(x+.1)^1.8)\nf",
|
squiggleString: "[normal(5,2), normal(10,1), normal(40,2), 400000]",
|
||||||
width,
|
width,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -115,4 +139,46 @@ The default is show 10 points between 0 and 10.
|
||||||
</Story>
|
</Story>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
|
||||||
|
## Booleans
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story
|
||||||
|
name="Boolean"
|
||||||
|
args={{
|
||||||
|
squiggleString: "3 == 3",
|
||||||
|
width,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{Template.bind({})}
|
||||||
|
</Story>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
## Records
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story
|
||||||
|
name="Record"
|
||||||
|
args={{
|
||||||
|
squiggleString: "{foo: 35 to 50, bar: [1,2,3]}",
|
||||||
|
width,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{Template.bind({})}
|
||||||
|
</Story>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
|
## Strings
|
||||||
|
|
||||||
|
<Canvas>
|
||||||
|
<Story
|
||||||
|
name="String"
|
||||||
|
args={{
|
||||||
|
squiggleString: '"Lucky day!"',
|
||||||
|
width,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{Template.bind({})}
|
||||||
|
</Story>
|
||||||
|
</Canvas>
|
||||||
|
|
||||||
<Props of={SquiggleChart} />
|
<Props of={SquiggleChart} />
|
||||||
|
|
Loading…
Reference in New Issue
Block a user