Customization in Angular Sankey component
18 Nov 201824 minutes to read
The Sankey component provides extensive customization options to create visualizations that match your specific design requirements and data presentation needs. From styling and theming to advanced visual techniques, the component enables complete control over appearance and behavior.
This guide covers comprehensive customization techniques including styling, theming, color mapping, and visual customization strategies.
Styling Overview
The Sankey Chart supports multiple levels of styling customization:
- Global Styling: Apply consistent styles to all elements
- Element-Level Styling: Customize specific nodes, links, or labels
- Data-Driven Styling: Apply styles based on data values or conditions
- Theme-Based Styling: Use predefined themes or create custom themes
Node and Link Styling
Use the nodeStyle and linkStyle properties to configure global appearance for nodes and links. Individual nodes/links can override these values or be customized during rendering events.
Global Node Styling
Apply consistent styling to all nodes using nodeStyle.
import { Component, OnInit } from '@angular/core';
import { SankeyAllModule } from '@syncfusion/ej2-angular-charts';
@Component({
imports: [SankeyAllModule],
standalone: true,
selector: 'app-container',
template: `
<div class="control-pane">
<div class="control-section" id="sankey-container">
<ejs-sankey width="90%" height="450px" [nodeStyle]="nodeStyle">
<e-sankey-nodes>
<e-sankey-node id="Agricultural Waste"></e-sankey-node>
<e-sankey-node id="Biomass Residues"></e-sankey-node>
<e-sankey-node id="Bio-conversion"></e-sankey-node>
<e-sankey-node id="Liquid Biofuel"></e-sankey-node>
<e-sankey-node id="Electricity"></e-sankey-node>
<e-sankey-node id="Heat"></e-sankey-node>
</e-sankey-nodes>
<e-sankey-links>
<e-sankey-link sourceId="Agricultural Waste" targetId="Bio-conversion" [value]="84.152"></e-sankey-link>
<e-sankey-link sourceId="Biomass Residues" targetId="Bio-conversion" [value]="24.152"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Liquid Biofuel" [value]="10.597"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Electricity" [value]="36.862"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Heat" [value]="60.845"></e-sankey-link>
</e-sankey-links>
</ejs-sankey>
</div>
</div>
`
})
export class AppComponent implements OnInit {
public nodeStyle?: Object;
ngOnInit(): void {
this.nodeStyle = {
fill: '#4472C4',
opacity: 0.8,
border: { width: 2, color: '#2E5090' }
};
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Global Link Styling
Configure link appearance using linkStyle to control opacity, curvature and color blending.
import { Component, OnInit } from '@angular/core';
import {
SankeyAllModule,
SankeyTooltipService,
SankeyLegendService
} from '@syncfusion/ej2-angular-charts';
@Component({
standalone: true,
selector: 'app-container',
imports: [SankeyAllModule],
providers: [SankeyTooltipService, SankeyLegendService],
template: `
<div class="control-pane">
<div class="control-section" id="sankey-container">
<ejs-sankey
width="90%"
height="450px"
[linkStyle]="linkStyle">
<e-sankey-nodes>
<e-sankey-node id="Agricultural Waste"></e-sankey-node>
<e-sankey-node id="Biomass Residues"></e-sankey-node>
<e-sankey-node id="Bio-conversion"></e-sankey-node>
<e-sankey-node id="Liquid Biofuel"></e-sankey-node>
<e-sankey-node id="Electricity"></e-sankey-node>
<e-sankey-node id="Heat"></e-sankey-node>
</e-sankey-nodes>
<e-sankey-links>
<e-sankey-link sourceId="Agricultural Waste" targetId="Bio-conversion" [value]="84.152"></e-sankey-link>
<e-sankey-link sourceId="Biomass Residues" targetId="Bio-conversion" [value]="24.152"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Liquid Biofuel" [value]="10.597"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Electricity" [value]="36.862"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Heat" [value]="60.845"></e-sankey-link>
</e-sankey-links>
</ejs-sankey>
</div>
</div>
`
})
export class AppComponent implements OnInit {
public linkStyle: object = {};
ngOnInit(): void {
this.linkStyle = {
opacity: 0.5,
curvature: 0.4
};
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Custom Node Appearance
You can set properties on each node object to override global styles or use rendering events such as nodeRendering, linkRendering, and labelRendering to apply dynamic, data-driven styles.
import { Component } from '@angular/core';
import { SankeyAllModule } from '@syncfusion/ej2-angular-charts';
@Component({
imports: [SankeyAllModule],
standalone: true,
selector: 'app-container',
template: `
<div class="control-pane">
<div class="control-section" id="sankey-container">
<ejs-sankey width="90%" height="450px">
<e-sankey-nodes>
<e-sankey-node id="Agricultural Waste"></e-sankey-node>
<e-sankey-node id="Biomass Residues"></e-sankey-node>
<e-sankey-node id="Bio-conversion"></e-sankey-node>
<e-sankey-node id="Liquid Biofuel"></e-sankey-node>
<e-sankey-node id="Electricity"></e-sankey-node>
<e-sankey-node id="Heat"></e-sankey-node>
</e-sankey-nodes>
<e-sankey-links>
<e-sankey-link sourceId="Agricultural Waste" targetId="Bio-conversion" [value]="84.152"></e-sankey-link>
<e-sankey-link sourceId="Biomass Residues" targetId="Bio-conversion" [value]="24.152"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Liquid Biofuel" [value]="10.597"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Electricity" [value]="36.862"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Heat" [value]="60.845"></e-sankey-link>
</e-sankey-links>
</ejs-sankey>
</div>
</div>
`
})
export class AppComponent {}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Custom Node Labels
Override label settings per-node using the label object on node definitions.
import { Component, OnInit } from '@angular/core';
import { SankeyAllModule } from '@syncfusion/ej2-angular-charts';
import { SankeyLabelSettings } from '@syncfusion/ej2-angular-charts';
@Component({
standalone: true,
selector: 'app-container',
imports: [SankeyAllModule],
template: `
<div class="control-pane">
<div class="control-section" id="sankey-container">
<ejs-sankey
width="90%"
height="450px"
[labelSettings]="labelSettings">
<e-sankey-nodes>
<e-sankey-node id="Agricultural Waste"></e-sankey-node>
<e-sankey-node id="Biomass Residues"></e-sankey-node>
<e-sankey-node id="Bio-conversion"></e-sankey-node>
<e-sankey-node id="Liquid Biofuel"></e-sankey-node>
<e-sankey-node id="Electricity"></e-sankey-node>
<e-sankey-node id="Heat"></e-sankey-node>
</e-sankey-nodes>
<e-sankey-links>
<e-sankey-link sourceId="Agricultural Waste" targetId="Bio-conversion" [value]="84.152"></e-sankey-link>
<e-sankey-link sourceId="Biomass Residues" targetId="Bio-conversion" [value]="24.152"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Liquid Biofuel" [value]="10.597"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Electricity" [value]="36.862"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Heat" [value]="60.845"></e-sankey-link>
</e-sankey-links>
</ejs-sankey>
</div>
</div>
`
})
export class AppComponent implements OnInit {
public labelSettings?: object;
ngOnInit(): void {
this.labelSettings = {
fontFamily:'Segoe UI',
fontWeight: 'bold',
fontSize: '14px',
color: '#1a1a1a'
};
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Color Customization
Predefined Color Palettes
Assign colors to nodes directly in your data model:
const nodes = [
{ id: 'Source1', label: { text: 'Source 1' }, color: '#3DA6D4' },
{ id: 'Source2', label: { text: 'Source 2' }, color: '#FFA500' },
{ id: 'Target', label: { text: 'Target' }, color: '#28A745' }
];Color Mapping
Map colors to categories or value ranges using rendering events or by preprocessing your data.
import { Component } from '@angular/core';
import { SankeyAllModule } from '@syncfusion/ej2-angular-charts';
import {
SankeyTooltipService,
SankeyLegendService,
SankeyExportService
} from '@syncfusion/ej2-angular-charts';
@Component({
imports: [SankeyAllModule],
providers: [
SankeyTooltipService,
SankeyLegendService,
SankeyExportService
],
standalone: true,
selector: 'app-container',
template: `
<div class="control-pane">
<div class="control-section" id="sankey-container">
<ejs-sankey
width="90%"
height="450px">
<e-sankey-nodes>
<e-sankey-node id="Agricultural Waste"></e-sankey-node>
<e-sankey-node id="Biomass Residues"></e-sankey-node>
<e-sankey-node id="Bio-conversion"></e-sankey-node>
<e-sankey-node id="Liquid Biofuel"></e-sankey-node>
<e-sankey-node id="Electricity"></e-sankey-node>
<e-sankey-node id="Heat"></e-sankey-node>
</e-sankey-nodes>
<e-sankey-links>
<e-sankey-link sourceId="Agricultural Waste" targetId="Bio-conversion" [value]="84.152"></e-sankey-link>
<e-sankey-link sourceId="Biomass Residues" targetId="Bio-conversion" [value]="24.152"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Liquid Biofuel" [value]="10.597"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Electricity" [value]="36.862"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Heat" [value]="60.845"></e-sankey-link>
</e-sankey-links>
</ejs-sankey>
</div>
</div>
`
})
export class AppComponent {}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Theme Customization
Set a theme globally or on the component to apply consistent visuals across the diagram. For Angular, apply the theme via global styles or component inputs depending on the package.
const theme = 'Material';import { Component, OnInit } from '@angular/core';
import { SankeyAllModule } from '@syncfusion/ej2-angular-charts';
import {
SankeyTooltipService,
SankeyLegendService,
SankeyExportService
} from '@syncfusion/ej2-angular-charts';
@Component({
standalone: true,
selector: 'app-container',
imports: [SankeyAllModule],
providers: [
SankeyTooltipService,
SankeyLegendService,
SankeyExportService
],
template: `
<div class="control-pane">
<div class="control-section" id="sankey-container">
<ejs-sankey
width="90%"
height="450px"
[nodeStyle]="nodeStyle">
<e-sankey-nodes>
<e-sankey-node id="Agricultural Waste"></e-sankey-node>
<e-sankey-node id="Biomass Residues"></e-sankey-node>
<e-sankey-node id="Bio-conversion"></e-sankey-node>
<e-sankey-node id="Liquid Biofuel"></e-sankey-node>
<e-sankey-node id="Electricity"></e-sankey-node>
<e-sankey-node id="Heat"></e-sankey-node>
</e-sankey-nodes>
<e-sankey-links>
<e-sankey-link sourceId="Agricultural Waste" targetId="Bio-conversion" [value]="84.152"></e-sankey-link>
<e-sankey-link sourceId="Biomass Residues" targetId="Bio-conversion" [value]="24.152"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Liquid Biofuel" [value]="10.597"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Electricity" [value]="36.862"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Heat" [value]="60.845"></e-sankey-link>
</e-sankey-links>
</ejs-sankey>
</div>
</div>
`
})
export class AppComponent implements OnInit {
public nodeStyle?: object;
ngOnInit(): void {
const customTheme = {
nodeFill: '#5A5A5A'
};
this.nodeStyle = { fill: customTheme.nodeFill };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Tooltip Customization
Create custom tooltip templates for rich content:
import { Component, OnInit } from '@angular/core';
import { SankeyAllModule } from '@syncfusion/ej2-angular-charts';
import {
SankeyTooltipService,
SankeyLegendService
} from '@syncfusion/ej2-angular-charts';
@Component({
imports: [SankeyAllModule],
providers: [
SankeyTooltipService,
SankeyLegendService
],
standalone: true,
selector: 'app-container',
template: `
<div class="control-pane">
<div class="control-section" id="sankey-container">
<ejs-sankey
width="90%"
height="450px"
[tooltip]="tooltip">
<e-sankey-nodes>
<e-sankey-node id="Agricultural Waste"></e-sankey-node>
<e-sankey-node id="Biomass Residues"></e-sankey-node>
<e-sankey-node id="Bio-conversion"></e-sankey-node>
<e-sankey-node id="Liquid Biofuel"></e-sankey-node>
<e-sankey-node id="Electricity"></e-sankey-node>
<e-sankey-node id="Heat"></e-sankey-node>
</e-sankey-nodes>
<e-sankey-links>
<e-sankey-link sourceId="Agricultural Waste" targetId="Bio-conversion" [value]="84.152"></e-sankey-link>
<e-sankey-link sourceId="Biomass Residues" targetId="Bio-conversion" [value]="24.152"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Liquid Biofuel" [value]="10.597"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Electricity" [value]="36.862"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Heat" [value]="60.845"></e-sankey-link>
</e-sankey-links>
</ejs-sankey>
</div>
</div>
`
})
export class AppComponent implements OnInit {
public tooltip?: Object;
ngOnInit(): void {
this.tooltip = {
enable: true,
linkTemplate: '<div style="padding:10px"><b>${sourceId} → ${targetId}</b><br/>Value: ${value}</div>'
};
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));Advanced Customization Patterns
Conditional Styling Based on Data
Use the nodeRendering or linkRendering events to apply conditional styles:
const onNodeRendering = (args) => {
const value = args.node.value || 0;
if (value > 200) {
args.node.color = '#00A651';
} else if (value > 100) {
args.node.color = '#FFB81C';
} else {
args.node.color = '#E81B23';
}
};Category-Based Styling
Assign styles based on categories in your preprocessing step or during rendering:
const categoryColors = { Energy: '#FF6B6B', Transport: '#4ECDC4', Industry: '#95E1D3' };
const onNodeRendering = (args) => {
const category = extractCategory(args.node.id);
args.node.color = categoryColors[category] || '#999';
};Interactive Styling
Apply hover and focus visuals in interaction handlers:
const onNodeEnter = (args) => { args.node.highlightOpacity = 1; };
const onNodeLeave = (args) => { args.node.highlightOpacity = 0.3; };Performance Optimization
For charts with many nodes and links, optimize rendering performance:
-
Use Global Styles: Apply global
nodeStyleandlinkStyleinstead of individual customization - Minimize Calculations: Reduce complex calculations in rendering events
- Conditional Rendering: Only customize visible elements in viewport
- Cache Results: Cache computed styles and colors
Customization Best Practices
Key Considerations
-
Consistency
- Maintain consistent color schemes across nodes and links
- Use meaningful colors that represent data categories
- Apply visual hierarchy through size and opacity
-
Performance
- Avoid complex calculations in rendering events
- Use global styles when possible
- Optimize for large datasets
-
Accessibility
- Don’t rely solely on color for information
- Ensure sufficient contrast ratios
- Provide alternative representations
-
User Experience
- Use intuitive color mapping
- Provide clear visual feedback for interactions
- Maintain visual consistency with your application
-
Maintainability
- Document custom styling logic
- Use reusable style functions
- Separate styling from business logic
Example: Comprehensive Customization
import { Component, OnInit } from '@angular/core';
import { SankeyAllModule } from '@syncfusion/ej2-angular-charts';
import {
SankeyTooltipService,
SankeyLegendService,
SankeyExportService,
} from '@syncfusion/ej2-angular-charts';
@Component({
imports: [SankeyAllModule],
providers: [
SankeyTooltipService,
SankeyLegendService,
SankeyExportService
],
standalone: true,
selector: 'app-container',
template: `
<div class="control-pane">
<div class="control-section" id="sankey-container">
<ejs-sankey
width="90%"
height="450px"
title="Comprehensive Sankey Customization"
[margin]="margin"
[nodeStyle]="nodeStyle"
[linkStyle]="linkStyle"
[labelSettings]="labelSettings"
[tooltip]="tooltip"
[legendSettings]="legendSettings">
<e-sankey-nodes>
<e-sankey-node id="Agricultural Waste" fill="#FF6B6B"></e-sankey-node>
<e-sankey-node id="Biomass Residues"></e-sankey-node>
<e-sankey-node id="Bio-conversion" fill="#4ECDC4"></e-sankey-node>
<e-sankey-node id="Liquid Biofuel" fill="#45B7D1"></e-sankey-node>
<e-sankey-node id="Electricity" fill="#FFA07A"></e-sankey-node>
<e-sankey-node id="Heat" fill="#98D8C8"></e-sankey-node>
</e-sankey-nodes>
<e-sankey-links>
<e-sankey-link sourceId="Agricultural Waste" targetId="Bio-conversion" [value]="84.152"></e-sankey-link>
<e-sankey-link sourceId="Biomass Residues" targetId="Bio-conversion" [value]="24.152"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Liquid Biofuel" [value]="10.597"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Electricity" [value]="36.862"></e-sankey-link>
<e-sankey-link sourceId="Bio-conversion" targetId="Heat" [value]="60.845"></e-sankey-link>
</e-sankey-links>
</ejs-sankey>
</div>
</div>
`
})
export class AppComponent implements OnInit {
public margin?: Object;
public nodeStyle?: Object;
public linkStyle?: Object;
public labelSettings?: Object;
public tooltip?: Object;
public legendSettings?: Object;
ngOnInit(): void {
this.margin = { left: 40, right: 40, top: 40, bottom: 40 };
this.nodeStyle = { opacity: 0.85 };
this.linkStyle = { opacity: 0.6, curvature: 0.5 };
this.labelSettings = { visible: true, color: 'black' };
this.tooltip = {
enable: true,
format: '<b>${sourceNodeName} → ${targetNodeName}</b><br/>Value: ${value}'
};
this.legendSettings = { visible: true, position: 'Bottom' };
}
}import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import 'zone.js';
bootstrapApplication(AppComponent).catch((err) => console.error(err));