Concepts
Interaction & readouts
Charts are explorable by pointer and keyboard out of the box. You can listen to the item under the pointer or focus, react to a selection, and replace the built-in readout.
Try it
Hover, or focus the chart with Tab and use the arrow keys. This readout is a custom template: tooltip_template("{datum.hour} h · {value} hits").
| hour | hits |
|---|---|
| 00 | 18 |
| 02 | 14 |
| 04 | 11 |
| 06 | 16 |
| 08 | 34 |
| 10 | 58 |
| 12 | 71 |
| 14 | 66 |
| 16 | 74 |
| 18 | 88 |
| 20 | 62 |
| 22 | 41 |
Events
| React | Vue | Angular | Reflex | |
|---|---|---|---|---|
| Item under pointer/focus | onActiveChange | @active-change | (activeChange) | on_active_change |
| Selection (click, Enter, Space) | onSelect | @select | (select) | on_select |
| Drill-down (treemap, sunburst) | onRootChange | @root-change | (rootChange) | on_root_change |
| Custom readout | tooltip={fn} | #tooltip slot | ng-template spTooltip | tooltip_template() |
The item is { seriesKey, index, datum, value, point: { x, y } }, and the active item is null when it leaves.
In your code
import { useState } from 'react';
import { LineChart } from '@silverpoint/react/line-chart';
export function Explorer({ data }: { data: { hour: string; hits: number }[] }) {
const [active, setActive] = useState<string>('—');
return (
<>
<LineChart
data={data}
xKey="hour"
valueKey="hits"
title="Hits per hour"
onActiveChange={(item) => setActive(item ? `${item.datum.hour}: ${item.value}` : '—')}
onSelect={(item) => console.log('selected', item.datum)}
tooltip={(item) => <strong>{item.value} hits</strong>}
/>
<p>Under the pointer: {active}</p>
</>
);
}<script setup lang="ts">
import { ref } from 'vue';
import { SpLineChart } from '@silverpoint/vue/line-chart';
import type { ActiveItem } from '@silverpoint/vue';
defineProps<{ data: { hour: string; hits: number }[] }>();
const active = ref<ActiveItem | null>(null);
</script>
<template>
<SpLineChart
:data="data"
x-key="hour"
value-key="hits"
title="Hits per hour"
@active-change="active = $event"
@select="(item) => console.log('selected', item.datum)"
>
<template #tooltip="{ active: item }">
<strong>{{ item.value }} hits</strong>
</template>
</SpLineChart>
<p>Under the pointer: {{ active ? `${active.datum.hour}: ${active.value}` : '—' }}</p>
</template>import { Component, input, signal } from '@angular/core';
import { SpTooltip } from '@silverpoint/angular';
import { SpLineChart } from '@silverpoint/angular/line-chart';
type Row = { hour: string; hits: number };
@Component({
selector: 'app-explorer',
imports: [SpLineChart, SpTooltip],
template: `
<sp-line-chart
[data]="data()"
xKey="hour"
valueKey="hits"
title="Hits per hour"
(activeChange)="active.set($event ? $event.datum['hour'] + ': ' + $event.value : '—')"
(select)="selected($event.datum)"
>
<ng-template spTooltip let-item>
<strong>{{ item.value }} hits</strong>
</ng-template>
</sp-line-chart>
<p>Under the pointer: {{ active() }}</p>
`,
})
export class Explorer {
readonly data = input.required<Row[]>();
protected readonly active = signal('—');
protected selected(datum: unknown) {
console.log('selected', datum);
}
}import reflex as rx
from reflex_silverpoint_react import line_chart, tooltip_template
class State(rx.State):
active: str = "—"
@rx.event
def on_active(self, item: dict | None):
self.active = "—" if item is None else f"{item['datum']['hour']}: {item['value']}"
@rx.event
def on_select(self, item: dict):
print("selected", item["datum"])
line_chart(
data=DATA,
x_key="hour",
value_key="hits",
on_active_change=State.on_active,
on_select=State.on_select,
tooltip=tooltip_template("{datum.hour} h · {value} hits"),
)