如何为D3绘制的正方形网格添加内边距?
给D3正方形网格添加内边距的两种方案
方案一:固定方块尺寸,手动添加间距
适合需要保持方块大小固定的场景,通过计算位置直接留出间距:
- 定义
cellPadding变量,调整它控制方块间的空隙大小; - 修改方块的
x/y坐标计算,让每个位置包含间距;
修改后的关键代码:
initializeVisual() { let vis = this; vis.margin = {top: 20, right: 20, bottom: 20, left: 40}; vis.width = document.getElementById(vis.parentElement).getBoundingClientRect().width - vis.margin.left - vis.margin.right; vis.height = 800 - vis.margin.top - vis.margin.bottom; // init drawing area vis.svg = d3.select('#' + vis.parentElement).append('svg') .attr('width', vis.width + vis.margin.left + vis.margin.right) .attr('height', vis.height + vis.margin.top + vis.margin.bottom) .append('g') .attr('transform', `translate (${vis.margin.left}, ${vis.margin.top})`); // Draws the initial grid let squaresPerRow = 16; const cellPadding = 5; // 调整此值改变间距大小 vis.squares = vis.svg.selectAll('.squares') .data(d3.range(256)) .enter() .append('rect') .attr('x', (d, i) => { let col = i % squaresPerRow; return col * (this.cellWidth + cellPadding); }) .attr('y', (d, i) => { let row = Math.floor(i / squaresPerRow); return row * (this.cellHeight + cellPadding); }) .attr('width', this.cellWidth) .attr('height', this.cellHeight) .attr('fill', 'lightgrey'); // 可选:检查网格是否超出容器宽度 const totalGridWidth = (this.cellWidth + cellPadding) * squaresPerRow - cellPadding; if (totalGridWidth > vis.width) { console.warn('网格宽度超出容器,请调整cellWidth或cellPadding'); } }
方案二:使用d3.scaleBand自动适配(推荐)
d3.scaleBand(带区比例尺)天生适配带间距的网格布局,能自动适配容器尺寸,保持间距比例:
- 定义间距比例
cellPadding(0到1之间,值越大间距越大); - 创建x、y方向的带区比例尺,自动计算方块位置和尺寸;
修改后的关键代码:
initializeVisual() { let vis = this; vis.margin = {top: 20, right: 20, bottom: 20, left: 40}; vis.width = document.getElementById(vis.parentElement).getBoundingClientRect().width - vis.margin.left - vis.margin.right; vis.height = 800 - vis.margin.top - vis.margin.bottom; // init drawing area vis.svg = d3.select('#' + vis.parentElement).append('svg') .attr('width', vis.width + vis.margin.left + vis.margin.right) .attr('height', vis.height + vis.margin.top + vis.margin.bottom) .append('g') .attr('transform', `translate (${vis.margin.left}, ${vis.margin.top})`); // Draws the initial grid let squaresPerRow = 16; const cellPadding = 0.1; // 间距比例,0~1之间,值越大空隙越大 // x方向带区比例尺 const xScale = d3.scaleBand() .domain(d3.range(squaresPerRow)) .range([0, vis.width]) .paddingInner(cellPadding); // y方向带区比例尺(总共有256/16=16行) const yScale = d3.scaleBand() .domain(d3.range(16)) .range([0, vis.height]) .paddingInner(cellPadding); vis.squares = vis.svg.selectAll('.squares') .data(d3.range(256)) .enter() .append('rect') .attr('x', (d, i) => xScale(i % squaresPerRow)) .attr('y', (d, i) => yScale(Math.floor(i / squaresPerRow))) .attr('width', xScale.bandwidth()) .attr('height', yScale.bandwidth()) .attr('fill', 'lightgrey'); }
内容的提问来源于stack exchange,提问作者zeroes_ones
相关产品推荐
相关产品推荐

