D3.js 開發實戰——散點圖(二)響應性(方案一)

語言: CN / TW / HK

Offer 駕到,掘友接招!我正在參與2022春招打卡活動,點擊查看活動詳情


系列文章可以查看《數據可視化》專欄


💡 本文的代碼需要依賴 D3 環境,版本為 v7.3.0

🔍 所參考的 Observable Notebook:Scatterplot

Observable Notebook 官方樣例是較通用的代碼,下一步是結合 notebook 裏的演示數據改寫代碼,雖然會降低了代碼的通用性,但可以將代碼進行簡化,然後在 Codepen 裏復現,這個散點圖是寬高固定為 width = 640, height = 400 然後基於它進行改進,為圖表添加響應頁面大小變化的功能。

實現圖表的隨頁面大小響應式變化功能有兩種方案:

方案一:只設置 svg 元素的寬高,即整體縮放圖表來實現(主要使用 CSS 的 transform scale 屬性實現),但是可能造成圖表元素過大或過小的問題

⚙️ 代碼具體演示效果可以查看這個 Codepen

scatterplot-responsive-version-1.gif

其核心代碼如下

```js / * 監聽頁面調整大小的操作,並相應地調整散點圖的大小 * / // 監聽頁面(容器)的大小變化 const container = document.getElementById("container");

let width = container.clientWidth; let height = container.clientHeight;

let timer = null;

function debounce(delay = 500) { if (timer) { // (如果倒計時的時間未到,而再次觸發 debounce 函數)阻止計時器執行回調函數 clearTimeout(timer); }

// 重新設置計時器,倒計時重新計算 timer = setTimeout(function () { // 經過延遲後,執行核心代碼 // 獲取當前容器的的寬高值 const w = container.clientWidth; const h = container.clientHeight;

// 當頁面的寬度或高度改變時 if (w !== width || h !== height) { width = w; height = h; // 重新設置 svg 畫布參數 svg.attr("width", w) .attr("height", h) .attr("viewBox", [0, 0, w, h]) }

// 執行完核心代碼後,清空計時器 timer timer = null; }, delay); }

function resized() { // 實際使用防抖函數時,可以設置延遲時間 // 這裏設置為延遲 1000 毫秒 debounce(500); }

// 監聽頁面調整大小時分發的 resize 事件 function setListener() { window.addEventListener("resize", resized); return function removeListener() { window.removeEventListener("resize", resized); }; }

// 當需要時調用方法註銷監聽器(例如移除圖表時) const removeListener = setListener(); ```

從演示可知該方案是對整個 SVG 進行縮放,在頁面較小時圖表的可視性可能較差