如何将D3生成的圆形对象按行排列(每5个或按宽度换行)
D3圆形自动换行实现方案
一、按固定数量(每5个)换行
要实现每5个圆形自动换行,只需调整圆形的cx和cy属性计算方式,利用数据索引判断当前圆的行列位置:
- 列位置:通过
counter % 5获取当前圆在该行的序号(从0开始),乘以单个圆的横向占用宽度(含间隙)后加上偏移量 - 行位置:通过
Math.floor(counter / 5)获取当前圆所在的行数,乘以行间距后加上初始纵向偏移
修改后的关键代码:
// 绘制圆形 var circleAttributes = circles .attr("cx", function(e, counter){ const column = counter % 5; return 50 * column + 50; // 50为横向单位宽度,可按需调整 }) .attr("cy", function(e, counter){ const row = Math.floor(counter / 5); return 30 + row * 60; // 60为行间距,确保上下圆不重叠 }) .attr("r", 20 )
二、按SVG容器宽度自动换行
如果需要根据容器实际宽度动态计算每行容纳的圆形数量,可先获取SVG的实际宽度,再推导每行容量:
async function draw(){ const data = jsonData; // 创建自适应宽度的SVG容器 var svgContainer = d3.select("#myChart").append("svg") .attr("width", "100%") .attr("height", "auto"); // 获取SVG实际宽度(确保容器已加载完成) const svgWidth = svgContainer.node().getBoundingClientRect().width; const circleUnitWidth = 50; // 单个圆的横向占用宽度(直径40+10间隙) const perRowCount = Math.floor(svgWidth / circleUnitWidth); // 每行可容纳的圆形数 // 绑定数据并创建圆形元素 var circles = svgContainer.selectAll("circle") .data(data) .enter() .append("circle") // 设置圆形位置 var circleAttributes = circles .attr("cx", function(e, counter){ const column = counter % perRowCount; return circleUnitWidth * column + circleUnitWidth/2; // 横向居中 }) .attr("cy", function(e, counter){ const row = Math.floor(counter / perRowCount); return circleUnitWidth/2 + row * circleUnitWidth; // 纵向居中 }) .attr("r", 20 ) // 根据总行数动态调整SVG高度 const totalRows = Math.ceil(data.length / perRowCount); svgContainer.attr("height", totalRows * circleUnitWidth); } draw()
说明:这种方式会根据SVG容器宽度自动适配每行数量,同时动态调整SVG高度以容纳所有行。若需响应窗口大小变化,可添加resize事件监听重新调用draw函数。
完整代码示例
数据部分:
[ { "category": "apple", "step": 1, "description": "Lorem ipsum dolor sit amet" }, { "category": "banana", "step": 2, "description": "Lorem ipsum dolor sit amet" }, { "category": "grape", "step": 3, "description": "Lorem ipsum dolor sit amet" }, { "category": "apple", "step": 3, "description": "Lorem ipsum dolor sit amet" }, { "category": "banana", "step": 2, "description": "Lorem ipsum dolor sit amet" }, { "category": "grape", "step": 1, "description": "Lorem ipsum dolor sit amet" } ]
固定每5个换行的完整绘制函数:
async function draw(){ const data = jsonData; var svgContainer = d3.select("#myChart").append("svg") .attr("viewBox", `0 0 500 500`) var circles = svgContainer.selectAll("circle") .data(data) .enter() .append("circle") var circleAttributes = circles .attr("cx", function(e, counter){ return 50 * (counter % 5) + 50; }) .attr("cy", function(e, counter){ return 30 + Math.floor(counter / 5) * 60; }) .attr("r", 20 ) } draw()
内容的提问来源于stack exchange,提问作者amarton
相关产品推荐
相关产品推荐

