Path Highlighting and Interaction
When a user hovers a node or edge, ApexSankey can highlight the entire connected flow path and dim everything else. This makes it easy to trace where a flow comes from and where it goes in a dense diagram.
Connected-path highlighting
highlightConnectedPath is enabled by default. On hover, the connected upstream and downstream flows stay at full opacity while unrelated elements fade to dimOpacity.
| Option | Type | Default | Description |
|---|---|---|---|
highlightConnectedPath | boolean | true | Highlight the connected flow path when hovering a node or edge |
dimOpacity | number | 0.15 | Opacity applied to unrelated (dimmed) elements while highlighting is active |
const sankey = new ApexSankey(document.getElementById('chart'), {
highlightConnectedPath: true,
dimOpacity: 0.2,
})
sankey.render(data)
Disabling highlighting
Set highlightConnectedPath: false for a static diagram where hover has no effect:
const sankey = new ApexSankey(el, {
highlightConnectedPath: false,
})
Tuning the dim level
Lower dimOpacity values make the highlighted path stand out more sharply against the dimmed background; higher values keep more context visible:
const sankey = new ApexSankey(el, {
highlightConnectedPath: true,
dimOpacity: 0.08, // strong contrast — unrelated flows nearly vanish
})
Node click callback
onNodeClick fires when the user clicks a node. It receives a SankeyNode object describing the clicked node.
const sankey = new ApexSankey(el, {
onNodeClick: (node) => {
console.log('Clicked node:', node)
console.log('Node data:', node.data) // { id, title, color, ... }
console.log('Flow value:', node.value) // total value through the node
},
})
sankey.render(data)
SankeyNode fields
| Field | Type | Description |
|---|---|---|
data | NodeData | null | The node's user data: { id, title, color, direction, forceY } |
value | number | Total flow value passing through the node |
rank | number | Column index (0-based) of the node in the layout |
x, y | number | Computed position of the node |
dy | number | Computed height of the node rectangle |
direction | string | Flow direction for the node |
spaceAbove, spaceBelow | number | Whitespace above/below the node |
Building a drill-down interaction
Combine onNodeClick with your own state to drive a detail panel or filter:
const sankey = new ApexSankey(el, {
highlightConnectedPath: true,
dimOpacity: 0.15,
onNodeClick: (node) => {
const id = node.data?.id
if (!id) return
showDetailPanel(id, node.value)
},
})
sankey.render(data)
function showDetailPanel(id, value) {
document.getElementById('panel').innerHTML = `
<h3>${id}</h3>
<p>Total flow: ${value}</p>
`
}
React example
In React, use the top-level onNodeClick prop (not options.onNodeClick, which the wrapper omits):
import { useState } from 'react'
import { ApexSankey } from 'react-apexsankey'
import type { SankeyNode } from 'react-apexsankey'
export default function InteractiveSankey() {
const [selected, setSelected] = useState<string | null>(null)
return (
<div>
{selected && <p>Selected: {selected}</p>}
<ApexSankey
data={data}
options={{ highlightConnectedPath: true, dimOpacity: 0.15 }}
onNodeClick={(node: SankeyNode) => setSelected(node.data?.id ?? null)}
/>
</div>
)
}
Vue example
<template>
<div>
<p v-if="selected">Selected: {{ selected }}</p>
<ApexSankey :data="data" :options="options" @nodeClick="onNodeClick" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import ApexSankey from 'vue-apexsankey'
const selected = ref<string | null>(null)
const options = { highlightConnectedPath: true, dimOpacity: 0.15 }
const onNodeClick = (node) => {
selected.value = node.data?.id ?? null
}
</script>