Skip to content

Tooltips & Hover ​

Hovering a chart shows a GPU hover layer (crosshair, point markers, highlighted bars) and a DOM tooltip. This page covers the tooltip options, custom tooltip HTML, the hover style, and hover events.

Live example

Basic usage ​

The built-in tooltip appears once interactions are enabled:

ts
import { Charturbo } from 'charturbo';

const sdk = await Charturbo.create(canvas);
sdk.renderLineChart(series, { hover: { mode: 'index', crosshair: true } });
sdk.enableNodeInteractions(canvas, {
  autoRender: true,
  tooltip: {
    sort: 'desc',            // 'none' (default, series order) | 'asc' | 'desc'
    shared: true,            // every series at the hovered x (default)
    pin: 'click',            // click pins the tooltip
    valueFormatter: '$,.2f', // spec, Intl options, or function
  },
});
sdk.render();

Tooltip options ​

enableNodeInteractions options that shape the tooltip:

OptionTypeDefaultDescription
builtInTooltipbooleantrueShow the floating tooltip
tooltipContainerHTMLElementcanvas.parentElement or document.bodyElement the tooltip is mounted in
tooltip.sort'none' | 'asc' | 'desc''none'Row order by value; NaN last
tooltip.sharedbooleantruetrue: every series at the hovered x / category. false: only the item closest to the pointer
tooltip.pin'click' | falsefalseClick a hovered item to pin the tooltip
tooltip.valueFormatterspec, Intl.NumberFormatOptions, or (v) => stringy axis format or locale numberValues in the default tooltip
formatChartTooltip(ctx: ChartTooltipContext) => string—Custom HTML for chart tooltips
formatTooltip(details: NodeDetails) => string—Custom HTML for graph / point-cloud node tooltips
tooltipClassNamestring—Extra class(es); the base class is charturbo-sdk-node-tooltip
tooltipStylePartial<CSSStyleDeclaration>—Inline styles merged over the default style
  • sort and shared are presentation only. The engine hit-test is unchanged, and 'hover' / 'click' events still receive the original order and every item. formatChartTooltip receives the sorted and filtered context.
  • shared: false reduces the rows of line, area, stacked bar, and combo tooltips. The GPU markers stay at every series; for a single marker too, use hover: { mode: 'nearest' }.
  • valueFormatter applies to series values, totals, OHLC, heatmap cells, box statistics, pie values, and scatter y. It applies to the default tooltip only, not to formatChartTooltip. Spec syntax: Number & Date Formats.

Pinning ​

With pin: 'click', clicking a hovered item freezes the tooltip and the engine hover (crosshair, markers) at that point. The pinned element gets data-pinned="true", and pointer moves, leaving the canvas, or a synced cursor do not change it.

It is released by the next click, a pointerdown outside the canvas, Escape (canvas focused), wheel zoom or drag pan, keyboard point navigation, or a new chart. Clicking empty space does not pin. On release, the 'hover' event and onNodeHover receive null.

On touch devices a tap pins the tooltip at that point until the next tap, and a long press scrubs (see Interactions).

WARNING

While pinned, the cursor of a sync group (hoverAtX) still moves the engine markers. Only the tooltip stays fixed.

Custom tooltip HTML ​

ts
import { escapeHtml } from 'charturbo';

sdk.enableNodeInteractions(canvas, {
  formatChartTooltip: (ctx) =>
    `<b>${escapeHtml(ctx.xLabel)}</b>` +
    ctx.items
      .map((it) => `<div style="color:${it.color}">${escapeHtml(it.seriesName)}: ${it.value}</div>`)
      .join(''),
  tooltipClassName: 'my-tooltip',
  tooltipStyle: { background: '#fff', color: '#111' },
});

WARNING

The returned string is set as innerHTML. Wrap every data string (series names, labels, metadata) in the exported escapeHtml. The default tooltip escapes them already.

Main fields of ChartTooltipContext:

FieldDescription
chartType'line', 'bar', 'scatter', 'candlestick', 'heatmap', 'box', 'pie', 'combo', … (area charts report 'line')
indexHovered sample / bar / point index
xLabelFormatted x (line), category label (bar), formatted x (scatter)
xSeries x of the primary sample (line charts with x)
items{ seriesName, value, color, nodeId, percent?, error?, band? } per row
totalStacked bar / area: sum of the visible series
areaModeArea charts: 'overlap' | 'stacked' | 'percent'
pointScatter: data coordinates of the hovered point
ohlcCandlestick: open / high / low / close / volume
cellHeatmap: { row, col, xLabel, yLabel }
slicePie: { label, value, percent, members? }
boxBox plot statistics
detailsNodeDetails of the primary point (closest to the pointer)

Business and hierarchy charts add their own fields (radar, gauge, funnel, waterfall, hierarchy, flow).

Hover style ​

The hover chart option (or setChartHoverStyle after rendering) styles the GPU hover layer. Colors are ColorInput: an [r, g, b, a] tuple in 0..1 or a CSS color string.

OptionTypeDefaultDescription
mode'index' | 'nearest''index''index': every series at the hovered x. 'nearest': the closest point only (the 2.5D view always uses 'nearest')
crosshairbooleantrueVertical guide line on 2D line charts
crosshairColorColorInput[0.58, 0.64, 0.72, 0.55]Crosshair color
crosshairWidthnumber1Crosshair width in CSS px
markerbooleantruePoint markers in the series color
markerRadiusnumber4Marker radius in CSS px, excluding the ring
markerRingColorColorInputchart backgroundRing separating the marker from the line
markerRingWidthnumber2Ring width in CSS px
hitRadiusnumber24 (scatter: 12)'nearest' pick radius in CSS px
barHighlightColorColorInputbar color lightened by 22%Color of the hovered bar
ts
sdk.setChartHoverStyle({ mode: 'nearest', markerRadius: 6 });

// Graph / point-cloud nodes (default: own color brightened, 1.6x radius)
sdk.setNodeHoverStyle({ scale: 1.4, color: [1, 1, 1, 1] });

Hover events ​

ts
sdk.on('hover', ({ chart, node }) => {
  if (!chart) return hideSidePanel(); // pointer left
  showSidePanel(chart.xLabel, chart.items);
});

chart is the same ChartTooltipContext as above, but unsorted and unfiltered. Both 'hover' and onNodeHover need enableNodeInteractions.

Hover from code ​

ts
sdk.hoverAtX(Date.parse('2026-01-01T09:00Z'), { tooltip: true }); // like a pointer resting at that x
sdk.getHoverX();  // data x of the current hover, or null
sdk.hoverAtX(null); // clear
sdk.render();

hoverAtX hovers in index mode (bars: the category at round(x)) without emitting 'hover'. tooltip: true also shows the built-in tooltip. This is what Dashboard Sync uses.

Localized labels ​

Default tooltip values use the chart locale (locale option, then setLocale, then the runtime locale). Built-in field labels such as Open / High / Low / Close / Volume follow the same locale (en, ko, zh-CN; others fall back to English). See Internationalization.

See also ​

MIT License