原文(持续更新):datavis-note.benbinbin.com/article/d3/…
系列文章可以查看《数据可视化》专栏
💡 本文的代码需要依赖 D3 环境,版本为 v7.3.0
🔍 所参考的 Observable Notebook:Scatterplot
Observable Notebook 官方样例是较通用的代码,下一步是结合 notebook 里的演示数据改写代码,虽然会降低了代码的通用性,但可以将代码进行简化,然后在 Codepen 里复现,这个散点图是宽高固定为 width = 640, height = 400
然后基于它进行改进,为图表添加响应页面大小变化的功能。
实现图表的随页面大小响应式变化功能有两种方案:
方案一:只设置 svg 元素的宽高,即整体缩放图表来实现(主要使用 CSS 的 transform scale 属性实现),但是可能造成图表元素过大或过小的问题
⚙️ 代码具体演示效果可以查看这个 Codepen
其核心代码如下
/**
*
* 监听页面调整大小的操作,并相应地调整散点图的大小
*
*/
// 监听页面(容器)的大小变化
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 进行缩放,在页面较小时图表的可视性可能较差