用Svelte實現響應式、反應式的動畫數據可視化

Tom Fevrier 和 Matthias Stahl 最近向 Svelte 社區介紹了使用 Svelte 實現響應性、交互式和動畫數據可視化的技術。

在 Svelte Society 組織的一次演講中(基于數據的Svelte和D3可視化),Tom Fevrier,法國金融報紙《回聲報》的圖片記者,用 Svelte 從無開始實現了兩個動畫響應式圖形。

他演示的響應式曲線可以在這里看到:

圖形動畫可以在這里看到:

Fevrier 解釋說,背后的核心思想是利用了 D3 和 Svelte。D3 有一組用于圖形可視化的函數,用來計算尺度插值形狀等。另一方面,Svelte 負責處理圖形可視化的模塊化(通過組件)、交互性(事件處理)、反應性和響應性(通過數據綁定)。

Fevrier 進一步解釋說,開發人員可以借助 Svelte 將命令式 D3 代碼轉換成聲明式 Svelte 代碼。Fevrier 通過以下的 D3 代碼來說明他的想法:

d3.selectAll('circle')  .data(data).enter()  .append('circle')  .attr('cx', d => xScale(d.a))  .attr('cy', d => xScale(d.b))  .attr('r', d => radiusScale(d.c))  .attr('fill', 'rebeccapurple')
復制代碼

轉成 Svelte 代碼:

{#each data as d}  <circle    cx = {xScale(d.a)}   cy = {xScale(d.b)}   r = {radiusScale(d.c)}   fill = 'rebeccapurple'   >{/each}
復制代碼

雖然 D3 可以處理自己的動畫和交互,并對可視化數據中的變化作出反應,但 Fevrier 表示,相應的 D3 API(例如update)的復雜性比 Svelte 的更高。

窗口大小的響應能力可以通過靈活的 Svelte 數據綁定輕松實現。開發者可以使用 Svelte 內置的動畫運動轉換API 來實現流暢的動畫,這些動畫利用 CSS 而不是 JavaScript——它們不會阻塞主線程。開發人員還可以利用 Svelte 提供的模塊化將復雜的圖形分解為可重用的組件。

上面的代碼生成的氣泡圖是由散點圖組件和可重用軸組件組成的。散點圖組件的代碼如下:

<script>        import { scaleLinear, scaleLog, scaleSqrt } from 'd3-scale';        import { extent } from 'd3-array';        import { select } from 'd3-selection';        import Axis from './Axis.svelte';        export let data;        const height = 400;        const margin = 40;        let width;        $: xScale = scaleLog()                .domain(extent(data, d =>  d.gdp /  d.population))                .range([margin, width - margin]);        $: yScale = scaleLinear()                .domain(extent(data, d =>  d.life_expectancy))                .range([height - margin, margin]);        $: radiusScale = scaleSqrt()                .domain(extent(data, d =>  d.population))                .range([2, 50]);        const reveal = (node, { duration }) => {                const radius = select(node).attr('r');                return {                        duration,                        tick: (t) => select(node).attr('r', t * radius)                };        }script><div class='scatter-plot' bind:clientWidth={width}>        {#if width}                <svg width={width} height={height}>                        <Axis {width} {height} {margin} scale={xScale} position='bottom' />                        <Axis {width} {height} {margin} scale={yScale} position='left' />                        {#each data as d}                                <circle                                        cx={xScale( d.gdp /  d.population)}                                        cy={yScale( d.life_expectancy)}                                        r={radiusScale( d.population)}                                        fill='rebeccapurple'                                        in:reveal={{ duration: 1000 }}                                />                        {/each}                svg>        {/if}div><style>style>`
復制代碼

在上面的代碼示例中,bind:clientWidth 確保寬度變量始終隨圖形元素的大小而變化,從而可以在窗口的大小發生變化時更新圖形(響應性)。 SVG 原語的 in:reveal 參數實現了相應的動畫效果。這里使用 D3 來計算數據的域、軸的比例以及選擇圖形 DOM 節點。

代碼中使用了d3-fetch來導入 CSV 格式的數據,使用d3-axisd3-selectiond3-array計算可視化數據的域和范圍,以及使用d3-shaped3-scale來計算線性尺度、對數尺度和平方尺度。

演示可以在線獲得,實現代碼可以在GitHub上找到。讀者可以觀看包含大量額外技術細節的完整演講

2020年Svelte峰會的一次演講中,Matthias Stahl 提供了一個使用 Svelte 實現高級數據可視化的示例——這次沒有使用 D3。

雖然這次的可視化更加高級,但 Stahl 也只是使用了類似的 Svelte API 和技術。Stahl 的可視化示例還具有交互性,因為當用戶在圖形給定實體上移動滑鼠或單擊滑鼠時,它會做出反應。Stahl 還使用了 Svelte 組件(一個 Slider 組件)來實現可重用性和模塊化,即 Svelte 動畫和轉換 API。Stahl 還使用事件分派實現組件之間的通信和 Svelte 的 use 指令。

這個可視化項目,叫作外部干擾屬性跟蹤器(Foreign Interference Attribution Tracker),也可以在線訪問。實現代碼可以在GitHub上找到。Stahl 使用 Svelte 和 D3 創建的高級可視化示例(例如機票價格兒童死亡率)也可以在線上找到。

對使用 Svelte 進行數據可視化感興趣的開發人員也可以看一下Pancake,這是一個 Svelte 實驗性圖表庫,由 Svelte 的作者 Rich Harris 創建。Pancake 致力于在不使用 JavaScript 的情況下實現響應式圖表。

Svelte 峰會是一個關于 Svelte 的虛擬會議。2020 年的峰會于 10 月在網上舉行。完整的演講清單將在 Youtube 的Svelte Scociety頻道發布。

原文鏈接

Animated, Responsive, and Reactive Data Visualization with Svelte

0 条回复 A文章作者 M管理員
    暫無討論,說說你的看法吧