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

如何在D3.js中按给定坐标设置并固定网络图节点位置?

修复D3.js v3力导向图节点坐标失效与边不显示问题

以下是调整后的完整代码,可直接运行解决节点坐标不生效、边未显示的问题:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>D3.js v3 Fixed Position Force Graph</title>
    <script src="https://d3js.org/d3.v3.min.js"></script>
    <style>
        .node {
            stroke: #fff;
            stroke-width: 1.5px;
        }
        .link {
            stroke: #999;
            stroke-opacity: 0.6;
        }
        .label {
            font-size: 12px;
            fill: #333;
        }
    </style>
</head>
<body>
    <svg width="600" height="400"></svg>
    <script>
        // 原始节点数据
        var rawNodes = [
            {
                "data": {
                    "id": 1,
                    "desc": "Rohit",
                    "pos": [121.0284957885742, 116.3165512084961, 59.36788940429688]
                }
            },
            {
                "data": {
                    "id": 2,
                    "desc": "Deep",
                    "pos": [12.10284957885742, 116.3165512084961, 5.936788940429688]
                }
            },
            {
                "data": {
                    "id": 3,
                    "desc": "Deepa",
                    "pos": [12.10284957885742, 11.63165512084961, 5.936788940429688]
                }
            }
        ];

        // 原始边数据
        var rawEdges = [
            {
                "data": {
                    "id": "1_2",
                    "source": 1,
                    "target": 2
                }
            }
        ];

        // 预处理节点:转换为D3力布局兼容格式,锁定坐标
        var nodes = rawNodes.map(function(item) {
            return {
                id: item.data.id,
                desc: item.data.desc,
                x: item.data.pos[0], // 取三维坐标的X轴值
                y: item.data.pos[1], // 取三维坐标的Y轴值
                fixed: true // 固定节点位置,禁止力布局修改
            };
        });

        // 预处理边:将source/target从ID转为节点对象引用
        var edges = rawEdges.map(function(item) {
            return {
                id: item.data.id,
                source: nodes.find(node => node.id === item.data.source),
                target: nodes.find(node => node.id === item.data.target)
            };
        });

        // 初始化SVG容器
        var svg = d3.select("svg"),
            width = +svg.attr("width"),
            height = +svg.attr("height");

        // 创建力布局实例
        var force = d3.layout.force()
            .nodes(nodes)
            .links(edges)
            .size([width, height])
            .charge(-400) // 可根据需求调整节点排斥力
            .linkDistance(100)
            .on("tick", updateGraph);

        // 绘制边
        var link = svg.selectAll(".link")
            .data(edges)
            .enter().append("line")
            .attr("class", "link");

        // 绘制节点
        var node = svg.selectAll(".node")
            .data(nodes)
            .enter().append("circle")
            .attr("class", "node")
            .attr("r", 10)
            .style("fill", "#3388ff")
            .call(force.drag); // 保留拖拽功能,不需要可删除此行

        // 绘制节点标签
        var label = svg.selectAll(".label")
            .data(nodes)
            .enter().append("text")
            .attr("class", "label")
            .text(function(d) { return d.desc; });

        // 启动力布局
        force.start();

        // 力布局更新回调:同步节点与边的位置
        function updateGraph() {
            // 更新边的端点位置
            link
                .attr("x1", d => d.source.x)
                .attr("y1", d => d.source.y)
                .attr("x2", d => d.target.x)
                .attr("y2", d => d.target.y);

            // 更新节点位置
            node
                .attr("cx", d => d.x)
                .attr("cy", d => d.y);

            // 更新标签位置
            label
                .attr("x", d => d.x + 15)
                .attr("y", d => d.y + 5);
        }
    </script>
</body>
</html>

核心调整说明

  • 节点坐标处理:从原始数据的data.pos中提取XY坐标,赋值给节点的x/y属性,并设置fixed: true锁定位置,避免力布局的物理模拟改变预设坐标。
  • 边数据修正:D3.js v3要求边的source和target必须是节点对象而非ID,因此通过find方法将ID转换为对应的节点引用。
  • 渲染逻辑优化:在力布局的tick回调中直接使用节点的预设坐标更新元素位置,确保坐标始终与给定值一致。

内容的提问来源于stack exchange,提问作者Rohit Chakraborty

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 00:56:07