From aab6ac49406fb0116941aa86ae8213998067bad8 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Mon, 9 May 2022 19:21:54 +0000 Subject: [PATCH] Add an optional simple summary table --- .../src/components/DistributionChart.tsx | 87 +++++++++++++------ .../src/components/SquiggleEditor.tsx | 6 +- .../src/components/SquigglePlayground.tsx | 32 ++++--- 3 files changed, 85 insertions(+), 40 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index f1bb9ce0..43702aaf 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -44,7 +44,7 @@ export const DistributionChart: React.FC = ({ shape.value.continuous.some((x) => x.x <= 0) || shape.value.discrete.some((x) => x.x <= 0); let spec = buildVegaSpec(isLogX, isExpY); - let widthProp = width ? width - 20 : size.width - 10; + let widthProp = width ? width : size.width; // Check whether we should disable the checkbox var logCheckbox = ( @@ -65,11 +65,11 @@ export const DistributionChart: React.FC = ({ } var result = ( -
+ @@ -80,7 +80,7 @@ export const DistributionChart: React.FC = ({
)} - + ); } else { var result = ( @@ -95,6 +95,12 @@ export const DistributionChart: React.FC = ({ return sized; }; +type ChartContainerProps = { width: string }; + +let ChartContainer = styled.div` + width: ${(props) => props.width}; +`; + function buildVegaSpec(isLogX: boolean, isExpY: boolean): VisualizationSpec { return { ...chartSpecification, @@ -141,10 +147,33 @@ type SummaryTableProps = { distribution: Distribution; }; -const Table = styled.table``; +const Table = styled.table` + margin-left: auto; + margin-right: auto; + border-collapse: collapse; + text-align: center; + border-style: hidden; +`; + +const TableHead = styled.thead` + border-bottom: 1px solid rgb(141 149 167); +`; + +const TableHeadCell = styled.th` + border-right: 1px solid rgb(141 149 167); + border-left: 1px solid rgb(141 149 167); + padding: 0.3em; +`; + +const TableBody = styled.tbody``; + const Row = styled.tr``; -const Cell = styled.td``; -const TableHeader = styled.th``; + +const Cell = styled.td` + padding: 0.3em; + border-right: 1px solid rgb(141 149 167); + border-left: 1px solid rgb(141 149 167); +`; const SummaryTable: React.FC = ({ distribution, @@ -179,26 +208,30 @@ const SummaryTable: React.FC = ({ return ( - - {"Mean"} - {"5%"} - {"10%"} - {"Q1 (25%)"} - {"Median (50%)"} - {"Q3 (75%)"} - {"90%"} - {"95%"} - - - {unwrapResult(mean)} - {unwrapResult(p5)} - {unwrapResult(p10)} - {unwrapResult(Q1)} - {unwrapResult(median)} - {unwrapResult(Q3)} - {unwrapResult(p90)} - {unwrapResult(p95)} - + + + {"Mean"} + {"5%"} + {"10%"} + {"25%"} + {"50%"} + {"75%"} + {"90%"} + {"95%"} + + + + + {unwrapResult(mean)} + {unwrapResult(p5)} + {unwrapResult(p10)} + {unwrapResult(Q1)} + {unwrapResult(median)} + {unwrapResult(Q3)} + {unwrapResult(p90)} + {unwrapResult(p95)} + +
); }; diff --git a/packages/components/src/components/SquiggleEditor.tsx b/packages/components/src/components/SquiggleEditor.tsx index 572dbd76..2601bc21 100644 --- a/packages/components/src/components/SquiggleEditor.tsx +++ b/packages/components/src/components/SquiggleEditor.tsx @@ -43,7 +43,9 @@ export interface SquiggleEditorProps { /** Whether to show detail about types of the returns, default false */ showTypes?: boolean; /** Whether to give users access to graph controls */ - showControls: boolean; + showControls?: boolean; + /** Whether to show a summary table */ + showSummary?: boolean; } const Input = styled.div` @@ -67,6 +69,7 @@ export let SquiggleEditor: React.FC = ({ jsImports = defaultImports, showTypes = false, showControls = false, + showSummary = false, }: SquiggleEditorProps) => { let [expression, setExpression] = React.useState(initialSquiggleString); return ( @@ -95,6 +98,7 @@ export let SquiggleEditor: React.FC = ({ jsImports={jsImports} showTypes={showTypes} showControls={showControls} + showSummary={showSummary} /> ); diff --git a/packages/components/src/components/SquigglePlayground.tsx b/packages/components/src/components/SquigglePlayground.tsx index 424cff8d..dd2b8ecf 100644 --- a/packages/components/src/components/SquigglePlayground.tsx +++ b/packages/components/src/components/SquigglePlayground.tsx @@ -40,18 +40,11 @@ function FieldFloat(Props: FieldFloatProps) { ); } -interface Props { - initialSquiggleString?: string; - height?: number; - showTypes?: boolean; - showControls?: boolean; -} - -interface Props2 { +interface ShowBoxProps { height: number; } -const ShowBox = styled.div` +const ShowBox = styled.div` border: 1px solid #eee; border-radius: 2px; height: ${(props) => props.height}; @@ -76,12 +69,26 @@ const Row = styled.div` `; const Col = styled.div``; -let SquigglePlayground: FC = ({ +interface PlaygroundProps { + /** The initial squiggle string to put in the playground */ + initialSquiggleString?: string; + /** How many pixels high is the playground */ + height?: number; + /** Whether to show the types of outputs in the playground */ + showTypes?: boolean; + /** Whether to show the log scale controls in the playground */ + showControls?: boolean; + /** Whether to show the summary table in the playground */ + showSummary?: boolean; +} + +let SquigglePlayground: FC = ({ initialSquiggleString = "", height = 300, showTypes = false, showControls = false, -}: Props) => { + showSummary = false, +}: PlaygroundProps) => { let [squiggleString, setSquiggleString] = useState(initialSquiggleString); let [sampleCount, setSampleCount] = useState(1000); let [outputXYPoints, setOutputXYPoints] = useState(1000); @@ -114,6 +121,7 @@ let SquigglePlayground: FC = ({ height={150} showTypes={showTypes} showControls={showControls} + showSummary={showSummary} /> @@ -122,7 +130,7 @@ let SquigglePlayground: FC = ({ ); }; export default SquigglePlayground; -export function renderSquigglePlaygroundToDom(props: Props) { +export function renderSquigglePlaygroundToDom(props: PlaygroundProps) { let parent = document.createElement("div"); ReactDOM.render(, parent); return parent;