Add an optional simple summary table

This commit is contained in:
Sam Nolan 2022-05-09 19:21:54 +00:00
parent 19ebc322ad
commit aab6ac4940
3 changed files with 85 additions and 40 deletions

View File

@ -44,7 +44,7 @@ export const DistributionChart: React.FC<DistributionChartProps> = ({
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<DistributionChartProps> = ({
}
var result = (
<div>
<ChartContainer width={widthProp + "px"}>
<Vega
spec={spec}
data={{ con: shape.value.continuous, dis: shape.value.discrete }}
width={widthProp}
width={widthProp - 10}
height={height}
actions={false}
/>
@ -80,7 +80,7 @@ export const DistributionChart: React.FC<DistributionChartProps> = ({
<CheckBox label="Exp Y scale" value={isExpY} onChange={setExpY} />
</div>
)}
</div>
</ChartContainer>
);
} else {
var result = (
@ -95,6 +95,12 @@ export const DistributionChart: React.FC<DistributionChartProps> = ({
return sized;
};
type ChartContainerProps = { width: string };
let ChartContainer = styled.div<ChartContainerProps>`
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<SummaryTableProps> = ({
distribution,
@ -179,16 +208,19 @@ const SummaryTable: React.FC<SummaryTableProps> = ({
return (
<Table>
<TableHead>
<Row>
<TableHeader>{"Mean"}</TableHeader>
<TableHeader>{"5%"}</TableHeader>
<TableHeader>{"10%"}</TableHeader>
<TableHeader>{"Q1 (25%)"}</TableHeader>
<TableHeader>{"Median (50%)"}</TableHeader>
<TableHeader>{"Q3 (75%)"}</TableHeader>
<TableHeader>{"90%"}</TableHeader>
<TableHeader>{"95%"}</TableHeader>
<TableHeadCell>{"Mean"}</TableHeadCell>
<TableHeadCell>{"5%"}</TableHeadCell>
<TableHeadCell>{"10%"}</TableHeadCell>
<TableHeadCell>{"25%"}</TableHeadCell>
<TableHeadCell>{"50%"}</TableHeadCell>
<TableHeadCell>{"75%"}</TableHeadCell>
<TableHeadCell>{"90%"}</TableHeadCell>
<TableHeadCell>{"95%"}</TableHeadCell>
</Row>
</TableHead>
<TableBody>
<Row>
<Cell>{unwrapResult(mean)}</Cell>
<Cell>{unwrapResult(p5)}</Cell>
@ -199,6 +231,7 @@ const SummaryTable: React.FC<SummaryTableProps> = ({
<Cell>{unwrapResult(p90)}</Cell>
<Cell>{unwrapResult(p95)}</Cell>
</Row>
</TableBody>
</Table>
);
};

View File

@ -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<SquiggleEditorProps> = ({
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<SquiggleEditorProps> = ({
jsImports={jsImports}
showTypes={showTypes}
showControls={showControls}
showSummary={showSummary}
/>
</div>
);

View File

@ -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<Props2>`
const ShowBox = styled.div<ShowBoxProps>`
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<Props> = ({
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<PlaygroundProps> = ({
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<Props> = ({
height={150}
showTypes={showTypes}
showControls={showControls}
showSummary={showSummary}
/>
</Display>
</Col>
@ -122,7 +130,7 @@ let SquigglePlayground: FC<Props> = ({
);
};
export default SquigglePlayground;
export function renderSquigglePlaygroundToDom(props: Props) {
export function renderSquigglePlaygroundToDom(props: PlaygroundProps) {
let parent = document.createElement("div");
ReactDOM.render(<SquigglePlayground {...props} />, parent);
return parent;