Vue ApexSankey
Installation
npm install vue-apexsankey apexsankey @svgdotjs/svg.js
Or with yarn:
yarn add vue-apexsankey apexsankey @svgdotjs/svg.js
Demo
View Demo Project created using Vue-ApexSankey
Loading ApexSankey
Important: You must load ApexSankey before using the Vue component. Choose one of the following methods:
Option 1: ES Module Import (Recommended)
Import ApexSankey at your app's entry point to register it globally:
// main.ts
import "apexsankey";
import { createApp } from "vue";
import App from "./App.vue";
createApp(App).mount("#app");
Option 2: CDN Script Tags
Add the scripts to your index.html before your app bundle:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/@svgdotjs/svg.js"></script>
<script src="https://cdn.jsdelivr.net/npm/apexsankey/apexsankey.min.js"></script>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
Quick Start
<script setup lang="ts">
import ApexSankey from "vue-apexsankey";
import type { GraphData, SankeyOptions } from "vue-apexsankey";
const data: GraphData = {
nodes: [
{ id: "oil", title: "Oil" },
{ id: "gas", title: "Natural Gas" },
{ id: "coal", title: "Coal" },
{ id: "fossil", title: "Fossil Fuels" },
{ id: "energy", title: "Energy" },
],
edges: [
{ source: "oil", target: "fossil", value: 15 },
{ source: "gas", target: "fossil", value: 20 },
{ source: "coal", target: "fossil", value: 25 },
{ source: "fossil", target: "energy", value: 60 },
],
};
const options: Partial<SankeyOptions> = {
width: 800,
height: 600,
nodeWidth: 20,
};
</script>
<template>
<ApexSankey :data="data" :options="options" />
</template>
License Setup
If you have a commercial license, set it once at app initialization before rendering any charts:
// main.ts
import "apexsankey";
import { createApp } from "vue";
import { setApexSankeyLicense } from "vue-apexsankey";
import App from "./App.vue";
// set license before mounting app
setApexSankeyLicense("your-license-key-here");
createApp(App).mount("#app");
Using Template Refs
Access the underlying SankeyGraph instance via template refs:
<script setup lang="ts">
import { ref, onMounted } from "vue";
import ApexSankey from "vue-apexsankey";
import type { GraphData } from "vue-apexsankey";
const chartRef = ref<InstanceType<typeof ApexSankey> | null>(null);
const data: GraphData = {
nodes: [
{ id: "a", title: "A" },
{ id: "b", title: "B" },
],
edges: [{ source: "a", target: "b", value: 10 }],
};
onMounted(() => {
if (chartRef.value?.graph) {
console.log("Graph instance:", chartRef.value.graph);
console.log("Max rank:", chartRef.value.graph.maxRank);
}
});
</script>
<template>
<ApexSankey ref="chartRef" :data="data" />
</template>
Reactivity
The component automatically updates when props change:
<script setup lang="ts">
import { ref } from "vue";
import ApexSankey from "vue-apexsankey";
import type { GraphData, SankeyOptions } from "vue-apexsankey";
const data = ref<GraphData>({
nodes: [
{ id: "a", title: "A" },
{ id: "b", title: "B" },
],
edges: [{ source: "a", target: "b", value: 10 }],
});
const options = ref<Partial<SankeyOptions>>({
nodeWidth: 20,
});
function updateData() {
// chart will automatically re-render
data.value = {
...data.value,
edges: [{ source: "a", target: "b", value: 50 }],
};
}
function updateOptions() {
// chart will recreate with new options
options.value = {
...options.value,
nodeWidth: 30,
};
}
</script>
<template>
<div>
<ApexSankey :data="data" :options="options" />
<button @click="updateData">Update Data</button>
<button @click="updateOptions">Update Options</button>
</div>
</template>
Props
| Prop | Type | Required | Description |
|---|---|---|---|
data | GraphData | Yes | Sankey diagram data (nodes and edges) |
options | | No | Configuration options for the diagram |
Data Format
Nodes
interface Node {
id: string; // unique identifier
title: string; // display label
color?: string; // optional custom color
}
Edges
interface Edge {
source: string; // source node id
target: string; // target node id
value: number; // edge weight/size
type?: string; // tells parallel edges between the same two nodes apart
color?: string; // optional custom color
}
Complete Data Structure
interface GraphData {
nodes: Node[];
edges: Edge[];
options?: {
order?: string[][][]; // custom node ordering
alignLinkTypes?: boolean; // align links by type
};
}
Options
| Option | Type | Default | Description |
|---|---|---|---|
width | number | string | 800 | Width of graph container |
height | number | string | 800 | Height of graph container |
canvasStyle | string | "" | CSS styles for canvas root container |
spacing | number | 100 | Spacing from top and left of graph container |
nodeWidth | number | 20 | Width of graph nodes |
nodeBorderWidth | number | 1 | Border width of nodes in pixels |
nodeBorderColor | string | "" | Border color of nodes |
onNodeClick | | undefined | Callback function for node click |
edgeOpacity | number | 0.4 | Opacity value for edges (0 to 1) |
edgeGradientFill | boolean | true | Enable gradient fill based on node colors |
enableTooltip | boolean | false | Enable tooltip on hover |
enableToolbar | boolean | false | Enable/disable graph toolbar |
tooltipId | string | "sankey-tooltip-container" | Tooltip HTML element id |
tooltipTemplate | (content) => string | default template | HTML template for tooltip |
tooltipBorderColor | string | "#BCBCBC" | Border color of tooltip |
tooltipBGColor | string | "#FFFFFF" | Background color of tooltip |
fontSize | string | "14px" | Font size of node labels |
fontFamily | string | "" | Font family of node labels |
fontWeight | string | "400" | Font weight of node labels |
fontColor | string | "#000000" | Font color of node labels |
Node order
ApexSankey places nodes into columns and orders each column to cut edge crossings. There is no option to pin the order: an order array in the data or options has no effect, and since 1.12.4 the unused code behind it is gone, so you can delete one if you pass it. To let readers move nodes themselves, set draggableNodes: true. See Node ordering for what you can adjust.
Custom Tooltip
<script setup lang="ts">
import ApexSankey from "vue-apexsankey";
import type { GraphData, SankeyOptions } from "vue-apexsankey";
const data: GraphData = {
nodes: [
{ id: "a", title: "A" },
{ id: "b", title: "B" },
],
edges: [{ source: "a", target: "b", value: 10 }],
};
const options: Partial<SankeyOptions> = {
enableTooltip: true,
tooltipTemplate: ({ source, target, value }) => `
<div style="padding: 8px;">
<strong>${source.title}</strong> → <strong>${target.title}</strong>
<br />
Value: ${value}
</div>
`,
};
</script>
<template>
<ApexSankey :data="data" :options="options" />
</template>
Using the Composable
For more control, you can use the useSankey composable directly:
<script setup lang="ts">
import { ref } from "vue";
import { useSankey } from "vue-apexsankey";
import type { GraphData, SankeyOptions } from "vue-apexsankey";
const containerRef = ref<HTMLElement | null>(null);
const data = ref<GraphData>({
nodes: [
{ id: "a", title: "A" },
{ id: "b", title: "B" },
],
edges: [{ source: "a", target: "b", value: 10 }],
});
const options = ref<Partial<SankeyOptions>>({
nodeWidth: 20,
});
const { graph, isReady, render, destroy, recreate } = useSankey({
containerRef,
data,
options,
});
</script>
<template>
<div ref="containerRef" style="width: 800px; height: 600px;" />
</template>
TypeScript
All types are exported for use in your TypeScript projects:
import ApexSankey, {
GraphData,
Node,
Edge,
SankeyOptions,
CommonOptions,
NodeOptions,
EdgeOptions,
FontOptions,
TooltipOptions,
SankeyGraph,
} from "vue-apexsankey";
SSR Support
This component is SSR-safe. It renders an empty container on the server and only initializes the chart client-side after the component is mounted.