Every Semiotic chart handles empty data and loading states out of the box. These states work at two levels: directly on individual chart components, and at theChartContainer level for dashboard cards.
Empty State
When data is an empty array, charts with an empty state displays a centered "No data available" message. Customize this with the emptyContent prop, or suppress it entirely withemptyContent={false}. Network charts validate required graph or hierarchy input first; invalid input displays a diagnostic instead.
Empty and loading placeholders use the chart's resolved dimensions, including its mode defaults when width or height is omitted. With responsiveWidth, the box follows its container's width; responsiveHeight requires a parent with a defined height. Content is centered, and custom content stretches across the available width. A custom frame can use height: "100%"to fill the box. Pass data={[]} for an empty chart; omitted data selects push mode on charts that support it.
Sizing a wrapper's placeholder
Import resolveChartSize from semiotic/utilsor semiotic/utils/core when your wrapper owns the placeholder. It reads the same defaults as the chart and applies explicit dimensions, mode, and responsive rules. No React mount is needed. For responsive axes, pass the measured host content box ascontainerSize; without a measurement the result is the chart's initial fallback size.
TSX
import { resolveChartSize } from "semiotic/utils" const chartProps = { mode: "context", responsiveWidth: true } as const const size = resolveChartSize("CandlestickChart", { ...chartProps, containerSize: { width: measuredWidth } }) return rows.length ? ( <CandlestickChart {...chartProps} data={rows} /> ) : ( <div style={{ ...size, display: "grid", placeItems: "center" }}> No observations </div> )
The result describes the plotting viewport. MinimapChart includes its overview; ScatterplotMatrix uses its fields and cell geometry and excludes titles or legends above the grid. BigNumber preserves its own modes and CSS dimensions: inline content has automatic dimensions (undefined) that require DOM measurement for pixel bounds. External CSS and accessible tables can add space outside a viewport.
Custom Content
No sales data
Try adjusting the date range
Suppressed
LineChart
LineChart: No data provided. Pass a non-empty array to the data prop.
JSX
// Default empty state — "No data available" <LineChart data={[]} /> // Custom empty content <BarChart data={[]} categoryAccessor="category" valueAccessor="value" emptyContent={<div>No sales data for this period</div>} /> // Suppress empty state entirely <LineChart data={[]} emptyContent={false} />
Loading State
Set loading={true} on any chart to show a pulsing skeleton placeholder. This works at both the chart level and theChartContainer level.
JSX
// Chart-level loading — skeleton rendered by the chart itself <LineChart data={null} loading={isLoading} /> // Container-level loading — skeleton replaces entire children <ChartContainer title="CPU Load" loading={isLoading}> <LineChart data={data} xAccessor="x" yAccessor="y" /> </ChartContainer> // Choose based on your data-fetching pattern: // • Chart-level: each chart loads independently // • Container-level: single fetch for the whole dashboard card
Custom Loading UI (loadingContent)
The default skeleton is a stack of pulsing bars. For branded loading states, progress text, or a spinner, pass aloadingContent ReactNode — it renders in place of the skeleton, wrapped in the same sized container so the chart slot stays reserved. Pass loadingContent={false}to suppress the loading UI entirely (an outer wrapper's loading state takes over).
JSX
// Branded loading text <LineChart data={null} loading={isLoading} loadingContent={<div>Fetching analytics…</div>} /> // Spinner instead of the skeleton <BarChart data={null} loading={isLoading} loadingContent={<MySpinner />} /> // Let the parent component handle loading entirely <LineChart loading={isLoading} loadingContent={false} />
Error State
ChartContainer provides error display and error boundary support. Set error to show a message, or errorBoundary to catch render crashes.
Failed to fetch data from API.
JSX
// Error message <ChartContainer title="CPU Load" error="Failed to fetch data from API."> <LineChart data={data} xAccessor="x" yAccessor="y" /> </ChartContainer> // Error boundary — catches render crashes <ChartContainer title="CPU Load" errorBoundary> <LineChart data={data} xAccessor="x" yAccessor="y" /> </ChartContainer>
- Chart Container — production shell with title, toolbar, export, and status
- Chart Modes — primary, context, and sparkline rendering modes