import { StreamXYFrame } from "semiotic" const frameProps = { /* --- Data --- */ data: [{ month: 1, pct: 100, lineGroup: "Curve A_actual", forecast: undefined }, { month: 2, pct: 30, lineGroup: "Curve A_actual", forecast: undefined }, ... ], chartType: "line", groupAccessor: "lineGroup", /* --- Size --- */ size: [700,400], margin: { left: 80, bottom: 50, right: 10, top: 40 }, /* --- Process --- */ xAccessor: "month", yAccessor: "pct", yExtent: [0,100], xExtent: [0,20], boundsAccessor: d => d.uncertainty || 0, /* --- Customize --- */ lineStyle: (d) => { const baseStyles = { stroke: "#E0488B", strokeWidth: 3 } if (!d.forecast) { return baseStyles } else if (d.forecast === "mean") { return { ...baseStyles, strokeDasharray: "5" } } else { return { stroke: "none", strokeWidth: 0 } } }, boundsStyle: { fill: "#E0488B", fillOpacity: 0.15, stroke: "none" }, title: "Uncertainty Visualization (Time Series)", showAxes: true, xLabel: "Months", yLabel: "Decay (%)", yFormat: (d12) => `${d12}%`, /* --- Interact --- */ enableHover: true, /* --- Annotate --- */ tooltipContent: d => { const datum = d.data || {} const isForecast = datum.forecast === "mean" return ( <div style={{ border: `thin solid ${"#E0488B"}`, backgroundColor: "var(--surface-1, #f8f9fa)", color: "var(--text-primary, #1a1a2e)", width: "100px", textAlign: "center", padding: "10px" }} > {isForecast && ( <div style={{ color: "#E0488B", fontWeight: "bold", marginBottom: "5px" }}> * mean forecast * </div> )} <div>{`Month: ${datum.month}`}</div> <div>{`Decay: ${datum.pct}%`}</div> </div> ) } } export default () => { return <StreamXYFrame {...frameProps} /> }