Semiotic provides layout components for arranging multiple charts into dashboards, primary+context views, and coordinated displays. These compose naturally withLinkedCharts for cross-highlighting andresponsiveWidth for fluid sizing.
ChartGrid
ChartGrid arranges child charts in a responsive CSS Grid that reflows based on available space. Set columns for a fixed column count, or use "auto" (default) to auto-fill based on minCellWidth.
JSX
import { LinkedCharts, ChartGrid, LineChart, BarChart, Treemap } from "semiotic" <LinkedCharts> <ChartGrid columns={3} gap={16}> <LineChart data={lineData} xAccessor="month" yAccessor="revenue" lineBy="region" colorBy="region" responsiveWidth height={250} linkedHover={{ name: "hl", fields: ["region"] }} selection={{ name: "hl" }} /> <BarChart data={barData} categoryAccessor="region" valueAccessor="total" colorBy="region" responsiveWidth height={250} /> </ChartGrid> // Auto-fill: reflows to 1 column on narrow screens <ChartGrid minCellWidth={350} gap={24}> <LineChart ... responsiveWidth /> <BarChart ... responsiveWidth /> <Scatterplot ... responsiveWidth /> </ChartGrid>
Visual Hierarchy with Emphasis
Following Carbon Design guidelines, the most important chart in a dashboard should have the highest contrast and occupy the largest area. Setemphasis="primary" on a chart inside a ChartGridto have it span two columns, creating a natural F-pattern reading layout.
JSX
import { ChartGrid, LineChart, BarChart, Scatterplot } from "semiotic" <ChartGrid columns={2}> {/* Primary chart spans both columns */} <LineChart data={timeSeries} emphasis="primary" responsiveWidth height={300} /> {/* Secondary charts fill the second row */} <BarChart data={totals} responsiveWidth height={250} /> <Scatterplot data={scatter} responsiveWidth height={250} /> </ChartGrid>
ContextLayout
ContextLayout places a primary chart alongside a fixed-size context panel. The context chart usesmode="context" for compact rendering (no axes or labels). Use this to pair a time series with a structural overview like a treemap or network diagram.
JSX
import { ContextLayout, LineChart, Treemap } from "semiotic" <ContextLayout context={ <Treemap data={hierarchy} childrenAccessor="children" valueAccessor="value" colorByDepth responsiveWidth height={250} mode="context" /> } position="right" contextSize={250} > <LineChart data={timeSeries} xAccessor="month" yAccessor="revenue" lineBy="region" colorBy="region" responsiveWidth height={250} /> </ContextLayout> // Position options: "right" | "left" | "top" | "bottom"
CategoryColorProvider
Wrap charts in a CategoryColorProvider to ensure the same category value always gets the same color, regardless of which subset of categories each chart displays. Without this, each chart computes its own color scale independently, so "North" might be blue in one chart and orange in another.
JSX
import { CategoryColorProvider, ChartGrid, LineChart, BarChart } from "semiotic" // Explicit color assignments <CategoryColorProvider colors={{ North: "#e41a1c", South: "#377eb8", East: "#4daf4a", West: "#984ea3", }}> <ChartGrid columns={2}> <LineChart data={d1} colorBy="region" responsiveWidth /> <BarChart data={d2} colorBy="region" responsiveWidth /> </ChartGrid> </CategoryColorProvider> // Or auto-assign from a list + scheme <CategoryColorProvider categories={["North", "South", "East", "West"]} colorScheme="tableau10" > ...charts... </CategoryColorProvider>
Putting It All Together
Combine CategoryColorProvider, ChartGrid,ContextLayout, and LinkedCharts for a coordinated dashboard where colors are consistent and hover cross-highlights across all charts:
JSX
import { CategoryColorProvider, ChartGrid, ContextLayout, LinkedCharts, LineChart, BarChart, Treemap } from "semiotic" <CategoryColorProvider colors={{ North: "#e41a1c", South: "#377eb8" }}> <LinkedCharts> <ContextLayout context={ <Treemap data={hierarchy} mode="context" responsiveWidth linkedHover={{ name: "hl", fields: ["region"] }} selection={{ name: "hl" }} /> } > <ChartGrid columns={2}> <LineChart data={sales} colorBy="region" responsiveWidth linkedHover={{ name: "hl", fields: ["region"] }} selection={{ name: "hl" }} /> <BarChart data={totals} colorBy="region" responsiveWidth selection={{ name: "hl" }} /> </ChartGrid> </ContextLayout> </LinkedCharts> </CategoryColorProvider>
Props Reference
ChartGrid
| Prop | Type | Default | Description |
|---|
columns | number | "auto" | "auto" | Fixed column count or auto-fill based on minCellWidth |
minCellWidth | number | 300 | Minimum cell width for auto columns (px) |
gap | number | 16 | Gap between cells (px) |
ContextLayout
| Prop | Type | Default | Description |
|---|
context | ReactNode | required | Context chart(s) displayed alongside the primary |
position | "right" | "left" | "top" | "bottom" | "right" | Position of the context panel |
contextSize | number | 250 | Size of the context panel (px) |
gap | number | 12 | Gap between panels (px) |
CategoryColorProvider
| Prop | Type | Default | Description |
|---|
colors | Record<string, string> | — | Explicit category→color map |
categories | string[] | — | Category values to auto-assign colors |
colorScheme | string | string[] | "category10" | Scheme for auto-assignment |
- Responsive — responsiveWidth and responsiveHeight props
- Linked Charts — cross-highlighting and coordinated views
- Theming — ThemeProvider for global dark/light mode
- Chart Modes — primary, context, and sparkline rendering modes