echarts

vamseeachanta's avatarfrom vamseeachanta

Create powerful interactive charts with Apache ECharts - balanced ease-of-use and customization

0stars🔀0forks📁View on GitHub🕐Updated Jan 9, 2026

When & Why to Use This Skill

The Apache ECharts skill empowers users to build sophisticated, interactive data visualizations with ease. It bridges the gap between simple charting and complex customization, offering a wide array of chart types—from basic line and bar charts to advanced heatmaps and geographic maps—optimized for performance and mobile responsiveness. This skill is ideal for developers and data analysts looking to transform raw data into professional, web-ready visual insights.

Use Cases

  • Interactive Business Dashboards: Generate multi-series bar and line charts to compare quarterly performance and revenue trends with built-in tooltips and legends.
  • Geographic Data Mapping: Visualize regional statistics, sales distribution, or logistics data using integrated GeoMap support and custom map registrations.
  • Real-Time Data Monitoring: Implement dynamic charts that update in real-time to track live system metrics, financial tickers, or IoT sensor data.
  • Large-Scale Data Visualization: Efficiently render and explore massive datasets (100k+ points) using advanced sampling and progressive rendering techniques.
  • Cross-Platform Web Integration: Create responsive chart components specifically optimized for TypeScript, React, or Vue.js environments.
nameecharts
version1.0.0
descriptionCreate powerful interactive charts with Apache ECharts - balanced ease-of-use and customization
authorworkspace-hub
categorydata-visualization
tags[charts, echarts, apache, interactive, typescript, mobile]
platforms[web, javascript, typescript]

Apache ECharts Visualization Skill

Create stunning, interactive charts with Apache ECharts - the perfect balance of ease-of-use and extensive customization.

When to Use This Skill

Use ECharts when you need:

  • Balance of ease and power - Easy to start, powerful when needed
  • Broad chart variety - 20+ chart types including geo maps
  • TypeScript support - Full type definitions
  • Mobile responsiveness - Built-in responsive design
  • Large datasets - Efficient rendering of 100k+ points
  • Chinese/International - Excellent i18n support

Avoid when:

  • Ultimate customization needed (use D3.js)
  • Only need simple charts (use Chart.js)
  • 3D scientific visualizations (use Plotly)

Core Capabilities

1. Basic Line Chart

<!DOCTYPE html>
<html>
<head>
  <script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
</head>
<body>
  <div id="main" style="width: 600px; height: 400px;"></div>
  <script>
    var myChart = echarts.init(document.getElementById('main'));

    var option = {
      title: {
        text: 'Monthly Sales'
      },
      tooltip: {
        trigger: 'axis'
      },
      legend: {
        data: ['Sales']
      },
      xAxis: {
        type: 'category',
        data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
      },
      yAxis: {
        type: 'value'
      },
      series: [{
        name: 'Sales',
        type: 'line',
        data: [120, 200, 150, 80, 70, 110],
        smooth: true
      }]
    };

    myChart.setOption(option);
  </script>
</body>
</html>

2. Bar Chart with Multiple Series

var option = {
  title: {
    text: 'Quarterly Revenue Comparison'
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'shadow'
    }
  },
  legend: {
    data: ['2023', '2024']
  },
  grid: {
    left: '3%',
    right: '4%',
    bottom: '3%',
    containLabel: true
  },
  xAxis: {
    type: 'category',
    data: ['Q1', 'Q2', 'Q3', 'Q4']
  },
  yAxis: {
    type: 'value',
    name: 'Revenue (k$)'
  },
  series: [
    {
      name: '2023',
      type: 'bar',
      data: [120, 200, 150, 80],
      itemStyle: {
        color: '#5470C6'
      }
    },
    {
      name: '2024',
      type: 'bar',
      data: [180, 250, 200, 120],
      itemStyle: {
        color: '#91CC75'
      }
    }
  ]
};

myChart.setOption(option);

3. Pie Chart with Rich Formatting

var option = {
  title: {
    text: 'Traffic Sources',
    left: 'center'
  },
  tooltip: {
    trigger: 'item',
    formatter: '{a} <br/>{b}: {c} ({d}%)'
  },
  legend: {
    orient: 'vertical',
    left: 'left'
  },
  series: [
    {
      name: 'Access From',
      type: 'pie',
      radius: '50%',
      data: [
        { value: 1048, name: 'Search Engine' },
        { value: 735, name: 'Direct' },
        { value: 580, name: 'Email' },
        { value: 484, name: 'Affiliate' },
        { value: 300, name: 'Video Ads' }
      ],
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }
  ]
};

myChart.setOption(option);

Complete Examples

Example 1: Loading Data from CSV

// Fetch CSV data
fetch('../data/sales.csv')
  .then(response => response.text())
  .then(csvText => {
    // Parse CSV
    const lines = csvText.trim().split('\n');
    const headers = lines[0].split(',');

    const categories = [];
    const values = [];

    for (let i = 1; i < lines.length; i++) {
      const row = lines[i].split(',');
      categories.push(row[0]);
      values.push(parseFloat(row[1]));
    }

    // Create chart
    var myChart = echarts.init(document.getElementById('main'));
    var option = {
      title: { text: 'Sales Data from CSV' },
      tooltip: { trigger: 'axis' },
      xAxis: {
        type: 'category',
        data: categories
      },
      yAxis: { type: 'value' },
      series: [{
        name: 'Sales',
        type: 'line',
        data: values,
        smooth: true,
        areaStyle: {}
      }]
    };

    myChart.setOption(option);
  });

Example 2: Multi-Axis Chart

var option = {
  title: {
    text: 'Temperature and Precipitation'
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      type: 'cross'
    }
  },
  legend: {
    data: ['Temperature', 'Precipitation']
  },
  xAxis: {
    type: 'category',
    data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
  },
  yAxis: [
    {
      type: 'value',
      name: 'Temperature (°C)',
      position: 'left',
      axisLabel: {
        formatter: '{value} °C'
      }
    },
    {
      type: 'value',
      name: 'Precipitation (mm)',
      position: 'right',
      axisLabel: {
        formatter: '{value} mm'
      }
    }
  ],
  series: [
    {
      name: 'Temperature',
      type: 'line',
      yAxisIndex: 0,
      data: [2, 5, 9, 15, 20, 25],
      smooth: true
    },
    {
      name: 'Precipitation',
      type: 'bar',
      yAxisIndex: 1,
      data: [50, 45, 40, 35, 30, 25]
    }
  ]
};

myChart.setOption(option);

Example 3: Heatmap Calendar

// Generate data for a year
function getVirtulData(year) {
  const date = +echarts.time.parse(year + '-01-01');
  const end = +echarts.time.parse(+year + 1 + '-01-01');
  const dayTime = 3600 * 24 * 1000;
  const data = [];
  for (let time = date; time < end; time += dayTime) {
    data.push([
      echarts.time.format(time, '{yyyy}-{MM}-{dd}', false),
      Math.floor(Math.random() * 10000)
    ]);
  }
  return data;
}

var option = {
  title: {
    text: 'Activity Heatmap Calendar'
  },
  tooltip: {
    position: 'top',
    formatter: function (p) {
      return p.data[0] + ': ' + p.data[1];
    }
  },
  visualMap: {
    min: 0,
    max: 10000,
    calculable: true,
    orient: 'horizontal',
    left: 'center',
    top: 'top'
  },
  calendar: {
    range: '2024',
    cellSize: ['auto', 13]
  },
  series: {
    type: 'heatmap',
    coordinateSystem: 'calendar',
    data: getVirtulData('2024')
  }
};

myChart.setOption(option);

Example 4: Gauge Chart

var option = {
  title: {
    text: 'Performance Score'
  },
  tooltip: {
    formatter: '{a} <br/>{b} : {c}%'
  },
  series: [
    {
      name: 'Score',
      type: 'gauge',
      progress: {
        show: true
      },
      detail: {
        valueAnimation: true,
        formatter: '{value}%'
      },
      data: [
        {
          value: 85,
          name: 'Overall Score'
        }
      ]
    }
  ]
};

myChart.setOption(option);

// Animate the value
setInterval(() => {
  const newValue = Math.random() * 100;
  option.series[0].data[0].value = newValue.toFixed(2);
  myChart.setOption(option);
}, 2000);

Example 5: Geographic Map (China)

// Load map data
fetch('https://cdn.jsdelivr.net/npm/echarts/map/json/china.json')
  .then(response => response.json())
  .then(chinaJson => {
    echarts.registerMap('china', chinaJson);

    var option = {
      title: {
        text: 'Sales by Province',
        left: 'center'
      },
      tooltip: {
        trigger: 'item',
        formatter: '{b}<br/>{c} (units)'
      },
      visualMap: {
        min: 0,
        max: 1000,
        text: ['High', 'Low'],
        calculable: true
      },
      series: [
        {
          name: 'Sales',
          type: 'map',
          map: 'china',
          roam: true,
          emphasis: {
            label: {
              show: true
            }
          },
          data: [
            { name: 'Beijing', value: 500 },
            { name: 'Shanghai', value: 800 },
            { name: 'Guangdong', value: 900 },
            { name: 'Zhejiang', value: 700 }
          ]
        }
      ]
    };

    myChart.setOption(option);
  });

Example 6: Dynamic Real-Time Data

var data = [];
var now = new Date();

function randomData() {
  now = new Date(+now + 1000);
  return {
    name: now.toString(),
    value: [
      [now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/') + ' ' +
      [now.getHours(), now.getMinutes(), now.getSeconds()].join(':'),
      Math.round(Math.random() * 100)
    ]
  };
}

// Initialize with 100 points
for (var i = 0; i < 100; i++) {
  data.push(randomData());
}

var option = {
  title: {
    text: 'Real-Time Data Stream'
  },
  tooltip: {
    trigger: 'axis',
    formatter: function (params) {
      params = params[0];
      return params.value[0] + ' : ' + params.value[1];
    },
    axisPointer: {
      animation: false
    }
  },
  xAxis: {
    type: 'time',
    splitLine: {
      show: false
    }
  },
  yAxis: {
    type: 'value',
    boundaryGap: [0, '100%'],
    splitLine: {
      show: false
    }
  },
  series: [
    {
      name: 'Value',
      type: 'line',
      showSymbol: false,
      data: data,
      smooth: true
    }
  ]
};

myChart.setOption(option);

// Update every second
setInterval(() => {
  data.shift();
  data.push(randomData());

  myChart.setOption({
    series: [{
      data: data
    }]
  });
}, 1000);

Best Practices

1. Use Responsive Design

// Make chart responsive
window.addEventListener('resize', function() {
  myChart.resize();
});

// Or set explicit size
myChart.resize({
  width: 800,
  height: 600
});

2. Use Loading and Empty States

// Show loading
myChart.showLoading();

// Fetch data
fetch('../data/data.json')
  .then(response => response.json())
  .then(data => {
    myChart.hideLoading();
    myChart.setOption(option);
  });

// Handle no data
if (data.length === 0) {
  myChart.setOption({
    title: {
      text: 'No Data Available',
      left: 'center',
      top: 'center'
    }
  });
}

3. Use Themes

// Use built-in themes
var myChart = echarts.init(document.getElementById('main'), 'dark');

// Or custom theme
var customTheme = {
  color: ['#c23531', '#2f4554', '#61a0a8'],
  backgroundColor: '#f4f4f4'
};

var myChart = echarts.init(document.getElementById('main'), customTheme);

4. Optimize for Large Datasets

option = {
  series: [{
    type: 'line',
    // Enable sampling for large datasets
    sampling: 'lttb',
    // Use progressive rendering
    progressive: 1000,
    progressiveThreshold: 3000,
    data: largeDataArray
  }]
};

Available Chart Types

Basic Charts

  • Line, Bar, Pie, Scatter, Candlestick

Advanced Charts

  • Radar, Heatmap, Tree, Treemap, Sunburst, Parallel, Sankey, Funnel, Gauge

Maps

  • GeoMap, BMap (Baidu Maps), Google Maps

3D Charts (with GL extension)

  • 3D Bar, 3D Line, 3D Scatter, 3D Surface, Globe

Graph Charts

  • Graph, Force-directed Graph

TypeScript Support

import * as echarts from 'echarts';

type EChartsOption = echarts.EChartsOption;

const option: EChartsOption = {
  title: {
    text: 'TypeScript Example'
  },
  xAxis: {
    type: 'category',
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      data: [120, 200, 150, 80, 70, 110, 130],
      type: 'line'
    }
  ]
};

const chartDom = document.getElementById('main')!;
const myChart = echarts.init(chartDom);
myChart.setOption(option);

Installation

CDN

<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>

NPM

npm install echarts
import * as echarts from 'echarts';

// Or import specific modules
import * as echarts from 'echarts/core';
import { LineChart } from 'echarts/charts';
import { GridComponent } from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';

echarts.use([LineChart, GridComponent, CanvasRenderer]);

Advanced Features

Animation Configuration

option = {
  animation: true,
  animationDuration: 1000,
  animationEasing: 'cubicOut',
  animationDelay: function (idx) {
    return idx * 50;
  }
};

DataZoom (Zoom/Pan)

option = {
  dataZoom: [
    {
      type: 'inside', // Mouse wheel zoom
      start: 0,
      end: 100
    },
    {
      type: 'slider', // Slider zoom
      start: 0,
      end: 100
    }
  ],
  // ... rest of option
};

Brush Selection

option = {
  brush: {
    toolbox: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'],
    xAxisIndex: 0
  },
  // ... rest of option
};

myChart.on('brushSelected', function (params) {
  var brushComponent = params.batch[0];
  var selected = brushComponent.selected[0].dataIndex;
  console.log('Selected data indices:', selected);
});

Event Handling

// Click event
myChart.on('click', function (params) {
  console.log('Clicked:', params);
  alert('You clicked on ' + params.name);
});

// Hover event
myChart.on('mouseover', function (params) {
  console.log('Hovered:', params);
});

// Custom events
myChart.dispatchAction({
  type: 'highlight',
  seriesIndex: 0,
  dataIndex: 1
});

Integration Examples

With React

import { useEffect, useRef } from 'react';
import * as echarts from 'echarts';

function EChartsComponent({ option }) {
  const chartRef = useRef(null);
  const chartInstance = useRef(null);

  useEffect(() => {
    if (!chartInstance.current) {
      chartInstance.current = echarts.init(chartRef.current);
    }

    chartInstance.current.setOption(option);

    const handleResize = () => chartInstance.current.resize();
    window.addEventListener('resize', handleResize);

    return () => {
      window.removeEventListener('resize', handleResize);
      chartInstance.current?.dispose();
    };
  }, [option]);

  return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
}

With Vue

<template>
  <div ref="chart" style="width: 600px; height: 400px;"></div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  props: ['option'],
  mounted() {
    this.chart = echarts.init(this.$refs.chart);
    this.chart.setOption(this.option);

    window.addEventListener('resize', this.handleResize);
  },
  beforeUnmount() {
    window.removeEventListener('resize', this.handleResize);
    this.chart.dispose();
  },
  methods: {
    handleResize() {
      this.chart.resize();
    }
  },
  watch: {
    option: {
      deep: true,
      handler(newOption) {
        this.chart.setOption(newOption);
      }
    }
  }
};
</script>

Resources

Performance Tips

  1. Use progressive rendering for >10k points
  2. Enable sampling for time series data
  3. Lazy load chart instances
  4. Dispose charts when unmounting
  5. Use Canvas renderer for large datasets

Use this skill for the best balance of ease-of-use and powerful customization!