First Navigable Chart
Let's put everything together!
The Final Result
Try it out:
- Click "Enter navigation area" (or tab and press Enter)
- Use ← and → arrow keys to navigate
- Press Escape to exit
Trouble with Focus Indication
You may have noticed something important: the focus indicator is drawn by Bokeh, not by Data Navigator's rendered element. This is because Bokeh renders to <canvas> — pure pixels with no DOM elements to position over.
The Challenge with Canvas/Pixel Rendering
Most visualization libraries don't expose element coordinates. This means you can't position a DOM focus indicator precisely over a specific bar or point. The workaround is:
- Position the Data Navigator element to cover the entire chart
- Draw the focus indicator programmatically using the visualization library itself
This is why accessibility support from visualization libraries themselves is so important. Ideally, Bokeh (and others) would make charts navigable by default.
The Complete Code
import dataNavigator from 'data-navigator'
// Data for drawing focus outlines
const interactiveData = {
data: [
[[3, 2.75], [0, 0]], // apple
[[3.75, 4], [3, 2.75]] // banana
],
indices: {
fruit: { apple: 0, banana: 1 },
store: { a: 0, b: 1 }
}
}
// 1. Define Structure - all elements cover full chart
const structure = {
nodes: {
_0: {
id: '_0', renderId: '_0',
data: { fruit: 'apple', store: 'a', cost: 3 },
edges: ['_0-_1', 'any-exit'],
semantics: { label: 'fruit: apple. store: a. cost: 3.' },
spatialProperties: { x: 0, y: 0, width: 300, height: 300 }
},
// ... other nodes with same spatialProperties
},
edges: { /* ... */ },
navigationRules: { /* ... */ }
}
// 2. Draw focus indicator by redrawing Bokeh chart
const drawFocusIndicator = (node) => {
const fruitIndex = interactiveData.indices.fruit[node.data.fruit]
const storeIndex = interactiveData.indices.store[node.data.store]
const barData = interactiveData.data[fruitIndex]
// Only outline the focused bar
const line_color = storeIndex === 0
? ['#000000', 'transparent']
: ['transparent', '#000000']
// Redraw chart with outline
drawChart({ top: barData[0], bottom: barData[1], line_color })
}
// 3. On focus event, draw the indicator
element.addEventListener('focus', () => {
drawFocusIndicator(nextNode)
})/* Transparent overlay - doesn't block the chart visually */
.dn-manual-focus-node {
background: transparent;
border: none;
}
/* Browser focus ring still appears around the chart area */
.dn-manual-focus-node:focus {
outline: 3px solid #1e3369;
outline-offset: 2px;
}Key Takeaways
spatialProperties for Focus Indication
Every node needs spatialProperties with x, y, width, height. For canvas-based charts where you can't position over specific elements, cover the entire chart and draw the indicator programmatically.
Render On Demand
We still only render one node at a time, keeping the DOM clean.
Next Steps
Congratulations! You've built your first accessible, navigable chart. Explore the Examples for more patterns, including SVG-based charts where element positioning is possible.