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 进行缩放,在页面较小时图表的可视性可能较差