You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 10:00:26