Dean Fogarty

df.id.au

Dean Fogarty

/ home / technical / svelte / echarts

A minimal component that wraps Apache ECharts.


Our goal?

Provide a minimal wrapper around Apache ECharts. It must be responsive to size, options and theme changes.

Method

Install echarts as per the manual:

% npm install echarts

The component itself is straightforward, if a little long. We will break it up into parts.

Component initialisation

    import { onMount, onDestroy } from 'svelte';
    import * as echarts from 'echarts';

onMount() and onDestroy() are used for initialisation and cleanup of the ECharts instance.

Props

Required for chart initialisation:

    export let id;
    export let theme;
    export let width = 200;
    export let height = 200;

Required for setting chart options:

    export let option;
    export let notMerge = false;
    export let replaceMerge = undefined;
    export let lazyUpdate = false;

Setup

Creating and destroying the chart, as well as setting chart options:

    let chart;                      // our chart instance

    const setOption = () => {
        if (chart && !chart.isDisposed()) {
            chart.setOption(
                option,
                notMerge,
                replaceMerge,
                lazyUpdate
            );
        }
    };

    const destroyChart = () => {
        if (chart && !chart.isDisposed()) {
            chart.dispose();
        }
    };

    const makeChart = () => {
        destroyChart();
        chart = echarts.init(
            document.getElementById(id),
            theme
        );
    };

Initialisation and teardown:

    onMount(() => {
        makeChart();
    });

    onDestroy(() => {
        destroyChart();
    });

Resizing

Resizing with ECharts is done using echartsInstance.resize(). Debouncing has been added in this example:

    let timeoutId: any;
    const handleResize = () => {
        if (timeoutId == undefined) {
            timeoutId = setTimeout(() => {
                if (chart && !chart.isDisposed()) {
                    chart.resize();
                }
                timeoutId = undefined;
            }, 500);
        }
    };

Reactivity

We want the component to react to changes in size, option and theme. While width and option are easy, changing the theme requires destroying the chart and remaking it:

    $: width && handleResize();
    $: option && setOption();
    $: if (chart && theme) {
        makeChart();
        setOption();
    }

The DOM

ECharts requires attaching to a DOM element, identified by id. We take advantage of Svelte’s block element bindings to watch for changes in width:

<div bind:clientWidth={width}>
    <div
        id={id}
        style="height: {height}px"
    />
</div>

All together

Putting all those elements together (say, ./EChart.js):

<script>
    // component initialisation
    // props
    // setup
    // resizing
    // reactivity
</script>

<!-- the DOM -->

Usage

Use the component whever it’s required. Supply arguments as per the manual:

<script>
    import EChart from './EChart.js';

    let option = {
        title: {
            text: 'Chart title',
        },
        ...
    };
</script>

<div>
    <EChart {option} />
</div>

Summary

We created the minimal wrapper around Apache ECharts. It is a fully reactive component, handling sizing, options and theme changes.

Improvements

  • This component does the minimum required; it could be filled out to better match the ECharts Instance API.

More information