Created
May 2, 2023 20:03
-
-
Save kalebpace/2b381bd7f75fd36324c1b5f881ae26b5 to your computer and use it in GitHub Desktop.
Rough implementation of SSR/CSR ECharts support in Svelte
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script lang="ts" context="module"> | |
// ECharts does not export init options type, so we mirror | |
// https://echarts.apache.org/en/api.html#echarts.init | |
export type ContainerOpts = | |
| { | |
devicePixelRatio?: number; | |
renderer?: 'svg' | 'canvas'; | |
useDirtyRect?: boolean; | |
useCoarsePointer?: boolean; | |
pointerSize?: number; | |
width?: number | string; | |
height?: number | string; | |
// we use svelte's browser module to determine ssr mode later | |
// ssr?: boolean | |
} | |
| undefined; | |
// https://echarts.apache.org/en/theme-builder.html | |
// Support default theme selection | |
export type ThemeOpts = | |
| 'vintage' | |
| 'dark' | |
| 'westeros' | |
| 'essos' | |
| 'wonderland' | |
| 'walden' | |
| 'chalk' | |
| 'infographic' | |
| 'macarons' | |
| 'roma' | |
| 'shine' | |
| 'purple-passion' | |
| 'halloween' | |
| string | |
| undefined; | |
</script> | |
<script lang="ts"> | |
import { onMount, onDestroy } from 'svelte'; | |
import { browser } from '$app/environment'; | |
import { init } from 'echarts'; | |
import type { ECharts, EChartsCoreOption } from 'echarts'; | |
export let containerOpts: ContainerOpts; | |
export let chartOpts: EChartsCoreOption; | |
export let theme: ThemeOpts; | |
$: chartOpts && | |
instance && | |
instance.setOption({ | |
...chartOpts, | |
// Ensure SVG is entirely rendered via SSR before returning response, | |
// but allow user to override this behavior | |
// https://echarts.apache.org/en/option.html#series-scatter.progressive | |
progressive: chartOpts?.progressive || 0 | |
}); | |
let container: any; | |
let instance: ECharts; | |
if (!browser) { | |
// Force SVG since this component doesnt implement canvas support yet | |
instance = init(null as any, theme, { | |
...containerOpts, | |
ssr: true, | |
renderer: "svg" | |
}); | |
} | |
// We first render SSR and return a response, then ship the entire data set to the client to be hydrated for interactivity | |
// if using SSR with CSR in sveltekit | |
onMount(async () => { | |
instance = init(container as HTMLElement, theme, { | |
...containerOpts, | |
ssr: false | |
}); | |
}); | |
onDestroy(async () => { | |
instance.dispose(); | |
}); | |
</script> | |
<svelte:window on:resize={() => instance.resize()} /> | |
<div bind:this={container}> | |
{#if !browser} | |
{@html instance.renderToSVGString() || ''} | |
{/if} | |
</div> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment