Skip to content

Commit 808590f

Browse files
authored
Merge pull request #807 from nteract/3.2.1
3.2.1
2 parents 9cc5907 + d14e3e3 commit 808590f

34 files changed

Lines changed: 529 additions & 82 deletions

.clinerules

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
- Every HOC accepts `frameProps` to pass through. TypeScript `strict: true`.
1414

1515
## Common Props (all HOCs)
16-
`title`, `description` (overrides aria-label), `summary` (sr-only note), `width` (600), `height` (400), `responsiveWidth`, `responsiveHeight`, `margin`, `className`, `color` (uniform fill — overrides theme/colorScheme), `enableHover` (true), `tooltip` (boolean | `(datum) => ReactNode` | `{ fields?, title?, format?, style? }`), `showLegend`, `showGrid` (false), `frameProps`, `onObservation`, `chartId`, `loading` (false), `emptyContent`, `legendInteraction` ("none"|"highlight"|"isolate"), `legendPosition` ("right"|"left"|"top"|"bottom"), `emphasis` ("primary"|"secondary"), `annotations` (array), `accessibleTable` (true)
16+
`title`, `description` (overrides aria-label), `summary` (sr-only note), `width` (600), `height` (400), `responsiveWidth`, `responsiveHeight`, `margin`, `className`, `color` (uniform fill — overrides theme/colorScheme), `enableHover` (true), `tooltip` (boolean | `(datum) => ReactNode` | `{ fields?, title?, format?, style? }`), `showLegend`, `showGrid` (false), `frameProps`, `onObservation`, `onClick`, `chartId`, `loading` (false), `emptyContent`, `legendInteraction` ("none"|"highlight"|"isolate"), `legendPosition` ("right"|"left"|"top"|"bottom"), `emphasis` ("primary"|"secondary"), `annotations` (array), `accessibleTable` (true)
17+
18+
`onClick` receives `(datum, { x, y })` — the original datum and pixel coordinates. Works on lines, bars, areas, pie slices, nodes, and geo features.
1719

1820
`onObservation` receives `{ type: "hover"|"hover-end"|"click"|"brush"|"selection", datum?, x?, y?, timestamp, chartType, chartId }`. The `datum` is your original data object.
1921

@@ -43,8 +45,11 @@
4345
**PieChart** — `data`, `categoryAccessor`, `valueAccessor`, `colorBy`, `startAngle`
4446
**DonutChart** — PieChart + `innerRadius` (60), `centerContent` (ReactNode)
4547
**FunnelChart** — `data`, `stepAccessor` ("step"), `valueAccessor` ("value"), `categoryAccessor` (optional), `colorBy`, `connectorOpacity` (0.3), `orientation` ("horizontal"|"vertical"). Horizontal: centered bars with trapezoid connectors. Vertical: bars with diagonal hatch for dropoff. Multi-category: `categoryAccessor="channel"` mirrors (horizontal) or groups (vertical).
48+
**SwimlaneChart** — `data`, `categoryAccessor` ("category"), `subcategoryAccessor` (required), `valueAccessor` ("value"), `colorBy` (defaults to subcategoryAccessor), `colorScheme`, `orientation` ("horizontal"|"vertical"), `barPadding` (40). Renders categorical lanes with items stacked sequentially — unlike StackedBarChart, the same subcategory can appear multiple times in the same lane. Items stack left-to-right (horizontal) or bottom-to-top (vertical) in data order. Wraps StreamOrdinalFrame with `chartType="swimlane"`. Supports push API for streaming.
49+
50+
**LikertChart** — `data`, `categoryAccessor` ("question"), `valueAccessor` ("score", raw mode) or `levelAccessor`+`countAccessor` ("count", pre-aggregated mode), `levels` (required, ordered negative→positive), `orientation` ("horizontal"|"vertical"), `colorScheme`. Horizontal (default): diverging bar chart centered at 0% — negative levels extend left, positive right, neutral (odd count) split 50/50 across centerline. Vertical: stacked 100% bar chart. Supports any scale size (3-point to 7-point+). Raw mode aggregates integer scores automatically (1-based: score 1 → levels[0]). The `levels` array order defines polarity — first half negative, second half positive, center neutral if odd. Supports push API for streaming — accumulates raw data internally and re-aggregates percentages on each push.
4651

47-
All ordinal HOCs support `colorBy` and `colorScheme`. `showCategoryTicks` (default true) hides per-tick labels when false — margins auto-adjust. For distribution charts with `colorBy`, set `showCategoryTicks={false}` since the legend identifies categories.
52+
All ordinal HOCs support `colorBy` and `colorScheme`. `categoryFormat` (`(label: string, index?: number) => string`) customizes individual tick labels (truncation, formatting). `showCategoryTicks` (default true) hides per-tick labels when false — margins auto-adjust. For distribution charts with `colorBy`, set `showCategoryTicks={false}` since the legend identifies categories.
4853

4954
## Network Charts (`semiotic/network`)
5055

@@ -89,14 +94,16 @@ Push API: `chartRef.current.push({ time, value })`
8994
**IMPORTANT**: All pushed data must include a time field (default: `"time"`). Set `timeAccessor` if your field differs. Without valid time field, charts render blank.
9095

9196
**RealtimeLineChart** — `timeAccessor` ("time"), `valueAccessor` ("value"), `windowSize` (200), `windowMode`, `stroke`, `strokeWidth`
92-
**RealtimeHistogram** — `binSize` (required), `timeAccessor`, `valueAccessor`, `categoryAccessor`, `colors`
97+
**RealtimeHistogram** — `binSize` (required), `timeAccessor`, `valueAccessor`, `categoryAccessor`, `colors`, `brush` (boolean|"x"|object, defaults to `{ dimension: "x", snap: "bin" }` when `true`), `onBrush`, `linkedBrush` (cross-chart coordination)
9398
**RealtimeSwarmChart** — `timeAccessor`, `valueAccessor`, `categoryAccessor`, `radius`, `opacity`
9499
**RealtimeWaterfallChart** — `timeAccessor`, `valueAccessor`, `positiveColor`, `negativeColor`
95100
**RealtimeHeatmap** — `timeAccessor`, `valueAccessor`, `heatmapXBins`, `heatmapYBins`, `aggregation`
96101
**Streaming Sankey** — `StreamNetworkFrame` with `chartType="sankey"`, `showParticles`, `particleStyle`. Push individual edges: `ref.current.push({ source, target, value })`.
97102

98103
Encoding: `decay`, `pulse`, `transition`, `staleness` — compose freely on all streaming charts.
99104

105+
All Realtime* charts accept `data` props for static mode (no push API needed). RealtimeHistogram brush supports bin-snapping (`snap: "bin"`) and streaming tracking — the brush shrinks as selected bins scroll off and auto-clears when fully evicted. Bin snapping uses actual computed bin boundaries (data-driven), not a uniform grid — works with irregular bin widths. `snapDuring: true` enables continuous snap feedback during drag (not just on release).
106+
100107
### Push API on HOC charts
101108
Most HOC charts support push via `forwardRef`. **Omit** `data`/`nodes`/`edges` — do NOT pass `data={[]}`.
102109
```jsx
@@ -129,6 +136,8 @@ Fallback chain: `pointColor` → element color → `--semiotic-primary` CSS var
129136
**LinkedCharts** — `selections` (resolution: "union"|"intersect"|"crossfilter"), `showLegend`, `legendPosition`, `legendInteraction`, `legendSelectionName`, `legendField`
130137
**CategoryColorProvider** — `colors` (map) or `categories` + `colorScheme`
131138
Chart props: `selection`, `linkedHover`, `linkedBrush`. Hooks: `useSelection`, `useLinkedHover`, `useBrushSelection`, `useFilteredData`
139+
140+
**Linked crosshair** (coordinate-based hover sync): `linkedHover={{ name: "sync", mode: "x-position", xField: "time" }}` broadcasts the hovered X data value. Other charts with the same `linkedHover` name render a synced vertical crosshair at that X position. Each chart shows its own Y values independently. Use for dashboards with multiple time-series at different scales.
132141
**ScatterplotMatrix** — `data`, `fields`, `colorBy`, `cellSize`, `hoverMode`, `brushMode`
133142
**ChartContainer** — `title`, `subtitle`, `height` (400), `width` ("100%"), `status`, `loading`, `error`, `errorBoundary`, `actions` ({ export, fullscreen, copyConfig, dataSummary }), `controls`
134143
**ChartGrid** — `columns` (number|"auto"), `minCellWidth` (300), `gap` (16). `emphasis="primary"` spans two columns.
@@ -180,7 +189,8 @@ const svg = renderOrdinalToStaticSVG({ data, categoryAccessor: "cat", valueAcces
180189
All HOCs accept `annotations` (array). Coordinates use your data field names. Network/orbit use `nodeId`.
181190

182191
**Positioning**: `widget` (React content at data coords — v3 replacement for v2 `htmlAnnotationRules`; props: `content`, `dx`, `dy`, `width`, `height`, `anchor`), `label` (callout with connector), `callout` (circle + label), `text` (plain text), `bracket`
183-
**Reference lines**: `y-threshold` (`value`, `label`, `color`), `x-threshold`, `band` (`y0`, `y1`, `label`, `fill`)
192+
**Reference lines**: `y-threshold` (`value`, `label`, `color`, `labelPosition`: "left"|"center"|"right", `strokeDasharray`), `x-threshold` (`labelPosition`: "top"|"center"|"bottom"), `band` (`y0`, `y1`, `label`, `fill`)
193+
**Ordinal**: `category-highlight` (`category`, `color`, `opacity`, `label`) — highlights a category column/row. Works on BarChart, StackedBarChart, etc. `y-threshold` also works on vertical ordinal charts.
184194
**Enclosures**: `enclose` (circle around `coordinates`), `rect-enclose`, `highlight` (`filter` fn or `field`+`value`)
185195
**Statistical** (XY): `trend` (`method`: linear/polynomial/loess), `envelope`, `anomaly-band`, `forecast`
186196
**Streaming anchors**: `"fixed"` (default), `"latest"` (tracks newest datum), `"sticky"` (freezes when evicted)
@@ -205,13 +215,16 @@ import { ThemeProvider } from "semiotic"
205215
<ThemeProvider theme={{ colors: { primary: "#ff6b6b", categorical: [...] } }}> {/* Custom */}
206216
```
207217

208-
Presets: `light`, `dark`, `high-contrast`, `pastels`, `pastels-dark`, `bi-tool`, `bi-tool-dark`, `italian`, `italian-dark`, `tufte`, `tufte-dark`, `journalist`, `journalist-dark`, `playful`, `playful-dark`.
218+
**Color resolution priority** (when `colorBy` is set): explicit `colorScheme` prop > ThemeProvider `colors.categorical` > `"category10"` fallback. This means ThemeProvider categorical colors automatically apply to all charts — no need to pass `colorScheme` on every component.
219+
220+
Presets: `light`, `dark`, `high-contrast`, `pastels`, `pastels-dark`, `bi-tool`, `bi-tool-dark`, `italian`, `italian-dark`, `tufte`, `tufte-dark`, `journalist`, `journalist-dark`, `playful`, `playful-dark`, `carbon`, `carbon-dark`.
209221

210222
Serialization (`semiotic/themes`): `themeToCSS(theme, selector)`, `themeToTokens(theme)`, `resolveThemePreset(name)`.
211223
Color-blind palette: `import { COLOR_BLIND_SAFE_CATEGORICAL } from "semiotic"` (8-color Wong 2011).
224+
IBM Carbon palette: `import { CARBON_CATEGORICAL_14, CARBON_ALERT } from "semiotic"` (14-color categorical + 4 alert colors).
212225

213226
**`semiotic/utils`** (~137KB, ~10% of full bundle) — Lightweight entry point for utilities without any chart components:
214-
- **Theme**: `ThemeProvider`, `useTheme`, `LIGHT_THEME`, `DARK_THEME`, `HIGH_CONTRAST_THEME`, `COLOR_BLIND_SAFE_CATEGORICAL`, `themeToCSS`, `themeToTokens`, `resolveThemePreset`, `THEME_PRESETS`
227+
- **Theme**: `ThemeProvider`, `useTheme`, `LIGHT_THEME`, `DARK_THEME`, `HIGH_CONTRAST_THEME`, `COLOR_BLIND_SAFE_CATEGORICAL`, `CARBON_CATEGORICAL_14`, `CARBON_ALERT`, `themeToCSS`, `themeToTokens`, `resolveThemePreset`, `THEME_PRESETS`
215228
- **Format**: `adaptiveTimeTicks`, `smartTickFormat`
216229
- **Color**: `darkenColor`, `lightenColor`
217230
- **Patterns**: `createHatchPattern`
@@ -266,6 +279,7 @@ Charts render with `role="group"` (outer interactive wrapper, keyboard/focus) an
266279
## Known Pitfalls
267280

268281
- **Tooltip datum shape**: HOC tooltip functions get raw data. Frame `tooltipContent` gets wrapped data — use `d.data`.
282+
- **Tooltip positioning**: Tooltips auto-flip when near container edges (right→left, bottom→top). Custom `tooltip` content should not add its own background — the wrapper provides `--semiotic-tooltip-bg`, `--semiotic-tooltip-text`, etc. Override wrapper styles via CSS custom properties, not inline styles.
269283
- **Legend positioning**: "bottom" auto-expands margin ~80px. For narrow charts (<400px), prefer "bottom" or "top".
270284
- **MultiAxisLineChart legend**: Always use `legendPosition="bottom"` (or `"top"`) — the right-hand axis occupies the space where a right-side legend would go.
271285
- **Log scale**: Clamps domain min to 1e-6 (log(0) undefined).

0 commit comments

Comments
 (0)