Interaction and state
A chart can track selected records, the record under the pointer, and the visible range of each axis. You can let Sectile manage these values or bind them to application state.
Deployment frequency and stability
Compare the relationship between two values as individual points.
- Hovered datum
- None
- Selected datum
- None
<script setup lang="ts">
import {
ChartScatter, ChartAxisView, ChartCartesian, ChartNavigation,
ChartPanControl, ChartPlot, ChartRenderer, ChartResetView, ChartRoot,
ChartViewControls, ChartXAxis, ChartYAxis, ChartZoomControl,
} from '@sectile/vue/chart'
const services = [
{ id: 'api', deploys: 18, stability: 82 },
{ id: 'worker', deploys: 28, stability: 66 },
{ id: 'web', deploys: 42, stability: 74 },
{ id: 'billing', deploys: 51, stability: 48 },
]
const datumLabels = new Map(services.map(service => [service.id, service.id]))
const dom = {
renderer: 'auto',
accessibilityLabel: 'Deployment frequency and stability',
getAccessibleDatumLabel: (id: string | number) => datumLabels.get(String(id)) ?? String(id),
} as const
</script>
<template>
<ChartRoot :dom="dom" class="chart">
<ChartCartesian>
<ChartXAxis id="x" scale="linear" field="deploys" label="Monthly deployments">
<ChartAxisView :minimum-span="1" />
</ChartXAxis>
<ChartYAxis id="y" scale="linear" field="stability" label="Stability" unit="%" />
<ChartScatter id="service-health" :data="services" x-axis="x" y-axis="y" label="Services" />
<ChartNavigation keyboard />
<ChartViewControls axis="x">
<ChartPanControl direction="backward">Previous</ChartPanControl>
<ChartZoomControl direction="in">Zoom in</ChartZoomControl>
<ChartZoomControl direction="out">Zoom out</ChartZoomControl>
<ChartResetView>Reset</ChartResetView>
</ChartViewControls>
</ChartCartesian>
<ChartPlot><ChartRenderer /></ChartPlot>
</ChartRoot>
</template>
<style scoped>
.chart {
position: relative;
height: 24rem;
}
.chart :deep([data-part='plot']),
.chart :deep(canvas) {
width: 100%;
height: 100%;
}
</style>Enable a visible range before adding controls
To pan or zoom an axis, first add a view capability for that axis. It defines how far the user may zoom and what should happen when data changes. Browser and keyboard controls are then enabled separately.
const controller = createChartController({
definition,
viewCapabilities: [{
axisID: 'date',
minimumSpan: 86_400_000,
update: 'follow-end',
}],
})
const chart = createDOMChart({
root,
canvas,
controller,
navigation: {
wheel: 'native',
keyboard: true,
},
})wheel: 'native' is the default, so scrolling over the chart still scrolls the page. Choose wheel panning or zooming only when users will expect the chart to capture that input. Drag and pinch also require visible buttons or another single-pointer control that performs the same action.
| Input method | Recommended use |
|---|---|
| Visible pan, zoom, and reset buttons | Good default for discovery and accessibility |
| Keyboard | Focused chart navigation |
| Drag pan | Dense Cartesian exploration with visible alternatives |
| Modified wheel zoom | Desktop analysis tools; choose the modifier explicitly |
| Pinch | Touch exploration with visible alternatives |
| Radial navigation | Not applicable to pie and donut |
Trigger the same action from application code
controller.dispatch({
type: 'zoom-axis-view',
axisID: 'date',
factor: 1.5,
anchor: 0.75,
phase: 'settled',
})factor: 1.5 makes the current range 1.5 times smaller, while anchor: 0.75 keeps the point three quarters across the range in place. Numeric and temporal axes store visible minimum and maximum values. Categorical axes store the first and last visible category. The visible range therefore remains valid after resize.
Control state from the application
Selection, cursor, active record, and all visible axis ranges can be controlled by the application. When a controlled value would change, Sectile emits a command and waits for the owner to pass the new value back. In Vue, use v-model, v-model:cursor, v-model:active-datum, and v-model:view.
A shared view value keeps several charts with matching axis IDs on the same range. When data changes, update: 'preserve' keeps the current range, reset returns to the new full range, and follow-end keeps a live time window attached to the newest values.
If a selected or active record disappears after an update, Sectile removes its ID from the interaction state. Call controller.dispose() when an application-created controller is no longer used.
