阿里云主机折上折
  • 微信号
Current Site:Index > The Sankey diagram (Sankey) achieves this.

The Sankey diagram (Sankey) achieves this.

Author:Chuan Chen 阅读数:22412人阅读 分类: ECharts

Basic Concepts of Sankey Diagrams

A Sankey diagram is a specific type of flow diagram used to depict the movement of energy, materials, or costs between different nodes. The nodes in the diagram are connected by arrows, with the width of the lines proportional to the flow quantity. This type of chart was first proposed by Irish engineer Matthew Henry Phineas Riall Sankey in 1898 to illustrate the energy efficiency of steam engines.

In the field of data visualization, Sankey diagrams are particularly suitable for displaying:

  • Energy flows within energy systems
  • Fund transfers between different departments
  • User navigation paths between web pages
  • Material flows in product manufacturing processes

Implementing Sankey Diagrams in ECharts

ECharts provides comprehensive support for Sankey diagrams, allowing the creation of complex flow relationship charts with simple configurations. The basic implementation requires defining two core data structures: nodes and links:

option = {
  series: [{
    type: 'sankey',
    layout: 'none',
    data: [{
      name: 'Node 1'
    }, {
      name: 'Node 2'
    }],
    links: [{
      source: 'Node 1',
      target: 'Node 2',
      value: 10
    }]
  }]
};

Node and Link Configuration

Advanced Node Configuration

Nodes support rich style customization, including color and label display:

data: [
  {
    name: 'Raw Material Procurement',
    itemStyle: {
      color: '#FF9F43'
    },
    label: {
      color: '#333',
      fontWeight: 'bold'
    }
  },
  {
    name: 'Production Processing',
    itemStyle: {
      color: '#28C76F'
    }
  }
]

Link Style Control

Links can be styled with gradients, transparency, and other visual effects:

links: [
  {
    source: 'Raw Material Procurement',
    target: 'Production Processing',
    value: 100,
    lineStyle: {
      color: 'gradient',
      opacity: 0.7,
      curveness: 0.2
    }
  }
]

Implementing Interactive Features

ECharts Sankey diagrams support rich interactive functionalities:

series: [{
  type: 'sankey',
  // Enable dragging
  draggable: true,
  // Node click event
  emphasis: {
    focus: 'adjacency',
    itemStyle: {
      borderWidth: 3
    }
  },
  // Mouse hover style
  blur: {
    itemStyle: {
      opacity: 0.1
    }
  }
}]

Complex Data Example

When handling multi-level data, node relationships need to be organized logically:

const data = {
  nodes: [
    {name: 'Total Budget'},
    {name: 'Marketing Department'},
    {name: 'R&D Department'},
    {name: 'Online Advertising'},
    {name: 'Offline Events'},
    {name: 'Product Development'},
    {name: 'Technical Research'}
  ],
  links: [
    {source: 'Total Budget', target: 'Marketing Department', value: 300},
    {source: 'Total Budget', target: 'R&D Department', value: 500},
    {source: 'Marketing Department', target: 'Online Advertising', value: 200},
    {source: 'Marketing Department', target: 'Offline Events', value: 100},
    {source: 'R&D Department', target: 'Product Development', value: 350},
    {source: 'R&D Department', target: 'Technical Research', value: 150}
  ]
};

Deep Style Customization

Global Style Configuration

series: [{
  type: 'sankey',
  nodeWidth: 20,
  nodeGap: 10,
  layoutIterations: 32,
  label: {
    position: 'right',
    fontSize: 12
  },
  lineStyle: {
    color: 'source',
    curveness: 0.5
  }
}]

Responsive Design

Implement responsiveness with ECharts' resize method:

window.addEventListener('resize', function() {
  myChart.resize();
});

// Container style
#chart-container {
  width: 100%;
  height: 600px;
  min-width: 300px;
}

Dynamic Data Updates

Implement dynamic data loading and updates:

function updateChart(newData) {
  const option = myChart.getOption();
  option.series[0].data = newData.nodes;
  option.series[0].links = newData.links;
  myChart.setOption(option);
}

// Simulate asynchronous data loading
setTimeout(() => {
  updateChart({
    nodes: [...],
    links: [...]
  });
}, 2000);

Performance Optimization Techniques

Optimization strategies for handling large-scale data:

series: [{
  type: 'sankey',
  // Reduce layout iterations
  layoutIterations: 0,
  // Simplify node styles
  itemStyle: {
    borderWidth: 0
  },
  // Disable animations
  animation: false,
  // Use level configuration to control display hierarchy
  levels: [{
    depth: 0,
    itemStyle: {
      color: '#F76258'
    }
  }, {
    depth: 1,
    itemStyle: {
      color: '#33B5E5'
    }
  }]
}]

Practical Application Examples

Website User Behavior Analysis

const userFlowData = {
  nodes: [
    {name: 'Homepage'},
    {name: 'Product Page'},
    {name: 'Shopping Cart'},
    {name: 'Payment Page'},
    {name: 'Registration Page'},
    {name: 'Exit'}
  ],
  links: [
    {source: 'Homepage', target: 'Product Page', value: 1560},
    {source: 'Product Page', target: 'Shopping Cart', value: 870},
    {source: 'Shopping Cart', target: 'Payment Page', value: 490},
    {source: 'Payment Page', target: 'Exit', value: 480},
    {source: 'Homepage', target: 'Registration Page', value: 320},
    {source: 'Registration Page', target: 'Exit', value: 300}
  ]
};

Energy Flow Analysis

const energyData = {
  nodes: [
    {name: 'Coal', itemStyle: {color: '#333'}},
    {name: 'Natural Gas', itemStyle: {color: '#4E79A7'}},
    {name: 'Power Generation', itemStyle: {color: '#F28E2B'}},
    {name: 'Industry', itemStyle: {color: '#E15759'}},
    {name: 'Residential', itemStyle: {color: '#76B7B2'}}
  ],
  links: [
    {source: 'Coal', target: 'Power Generation', value: 50},
    {source: 'Natural Gas', target: 'Power Generation', value: 30},
    {source: 'Power Generation', target: 'Industry', value: 45},
    {source: 'Power Generation', target: 'Residential', value: 35}
  ]
};

Advanced Interactive Features

Implement custom tooltips and click events:

option = {
  tooltip: {
    trigger: 'item',
    formatter: function(params) {
      if(params.dataType === 'node') {
        return `${params.name}<br/>Total Inflow: ${params.value}`;
      } else {
        return `${params.source} → ${params.target}<br/>Flow: ${params.value}`;
      }
    }
  },
  series: [{
    type: 'sankey',
    // ...
  }]
};

myChart.on('click', function(params) {
  if(params.dataType === 'node') {
    console.log('Clicked node:', params.name);
  } else if(params.dataType === 'edge') {
    console.log(`Clicked link: ${params.source}→${params.target}`);
  }
});

Combining with Other Charts

Combining Sankey diagrams with pie charts:

option = {
  grid: [
    {left: '5%', top: '5%', width: '45%', height: '90%'},
    {right: '5%', top: '5%', width: '45%', height: '90%'}
  ],
  series: [
    {
      type: 'sankey',
      gridIndex: 0,
      // ...Sankey diagram configuration
    },
    {
      type: 'pie',
      gridIndex: 1,
      radius: ['30%', '70%'],
      data: [
        {value: 335, name: 'Direct Access'},
        {value: 310, name: 'Email Marketing'}
      ]
    }
  ]
};

Data Format Conversion

Converting raw data into the format required for Sankey diagrams:

function convertToSankeyData(rawData) {
  const nodes = [];
  const links = [];
  const nodeMap = new Map();
  
  // Collect all unique nodes
  rawData.forEach(item => {
    if(!nodeMap.has(item.source)) {
      nodeMap.set(item.source, {name: item.source});
    }
    if(!nodeMap.has(item.target)) {
      nodeMap.set(item.target, {name: item.target});
    }
  });
  
  // Convert to array
  nodes.push(...nodeMap.values());
  
  // Create links
  links.push(...rawData.map(item => ({
    source: item.source,
    target: item.target,
    value: item.value
  })));
  
  return {nodes, links};
}

// Raw data example
const rawData = [
  {source: 'A', target: 'B', value: 10},
  {source: 'A', target: 'C', value: 20}
];

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.