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

D3.js v3报错:Cannot read property 'call' of undefined原因咨询

问题原因及解决方案

让我们一步步拆解你遇到的Cannot read property 'call' of undefined错误,以及代码里的其他问题:

1. D3版本API混用(最直接的错误原因)

你使用的是D3 v3,但代码里调用了d3.forceSimulation()、d3.forceCollide()、d3.forceRadial()这些只有D3 v4及以上版本才有的API。在D3 v3中,力布局的API完全不同,d3.forceSimulation根本不存在,所以调用它会返回undefined,后续链式调用.force()自然就会抛出Cannot read property 'force' of undefined的错误。

2. d3.json()用法错误

D3 v3中d3.json()的第一个参数是JSON文件的URL地址,用来加载远程或本地的JSON文件,而不是直接传入一个JSON对象。你现在直接把json变量传进去,D3会尝试请求一个以这个JSON对象字符串为路径的资源,显然不存在,导致回调里的data是undefined,后续基于data的数据绑定都会失效。

3. 语法错误

代码最后定义pie布局时,value函数的闭合不完整,少了一个)和},这会导致代码解析失败,影响整体执行。


修正后的完整代码

下面是针对以上问题修复后的代码,保留了你的核心需求(径向力布局的气泡图):

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8"> 
    <title>D3 Test</title> 
    <script src="https://d3js.org/d3.v3.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
    <link rel="stylesheet" type="text/css" href="./css/style.css"> 
</head> 
<body style="background-color: rgb(233, 236, 239);"> 
    <br>
    <legend align="center">Convergencia de ODS con Plan Nacional de Desarrollo</legend>
    <hr> 
    <div class="container"> 
        <div class="jumbotron">
            <!-- 添加缺失的msg元素 -->
            <div id="msg" style="display:none;"></div>
            <script> 
                var w = 1200; 
                var h = 550; 
                var radius = Math.min(w, h); 

                var dataset = [ [ 600, 150] ]; 
                var json = [ 
                    { "pais": "Ecuador", "pais_nid": 14, "ods": "1. Fin a la pobreza", "ods_nid": 35, "ods_color_hex": "E5243B", "objetivos_plan_ods": 5 }, 
                    { "pais": "Ecuador", "pais_nid": 14, "ods": "2. Hambre cero", "ods_nid": 36, "ods_color_hex": "DDA63A", "objetivos_plan_ods": 9 } 
                ]; 

                // 直接使用本地json数据,无需d3.json加载
                var data = json;

                var rScale = d3.scale.linear() 
                    .domain([0, d3.max(data, function(d) { return d.objetivos_plan_ods; })]) 
                    .range([2, 40]); 

                // 创建SVG元素,将原点移到中心方便径向布局
                var svg = d3.select("div.jumbotron") 
                    .append("svg") 
                    .attr("width", w) 
                    .attr("height", h)
                    .attr("transform", "translate(" + w/2 + "," + h/2 + ")");

                // 绘制中心圆圈
                svg.append("circle")
                    .attr("r", 125) 
                    .attr("stroke", "rgb(255, 255, 255)") 
                    .attr("stroke-width", "8") 
                    .attr("fill", "none"); 

                svg.on("click", function() { 
                    document.getElementById("msg").setAttribute("style", "display:none;"); 
                    document.getElementById("msg").innerHTML = ''; 
                    d3.event.stopPropagation(); 
                }); 

                // 绑定数据创建节点
                var node = svg.selectAll("circle.node") 
                    .data(data) 
                    .enter() 
                    .append("circle") 
                    .attr("class", "node")
                    .attr("style", "cursor:pointer;") 
                    .attr("r", function(d) { return rScale(d.objetivos_plan_ods);}) 
                    .attr("fill", function(d) { 
                        // 使用JSON中提供的颜色,添加透明度
                        return "#" + d.ods_color_hex + "80"; 
                    }) 
                    .attr("id", function(d) { return "circle-" + d.ods_nid; }) 
                    .on("click",function(d) { 
                        document.getElementById("msg").removeAttribute("style"); 
                        d3.select("#circle-" + d.ods_nid)
                            .attr("stroke", "rgb(140, 233, 255)")
                            .attr("stroke-width", "6");
                        document.getElementById("msg").innerHTML = d.ods; 
                        d3.event.stopPropagation(); 
                    }) 
                    .on("mouseout", function(d) { 
                        document.getElementById("msg").setAttribute("style", "display:none;"); 
                        d3.select("#circle-" + d.ods_nid)
                            .attr("stroke", null)
                            .attr("stroke-width", null);
                        document.getElementById("msg").innerHTML = ''; 
                        d3.event.stopPropagation(); 
                    }); 

                // 使用D3 v3的力布局实现径向分布
                var force = d3.layout.force()
                    .nodes(data)
                    .size([w, h])
                    // 电荷力防止节点重叠
                    .charge(function(d) { return -Math.pow(rScale(d.objetivos_plan_ods), 2.0) * 1.5; })
                    // 自定义径向约束力,让节点围绕中心分布
                    .on("tick", function(e) {
                        node.each(radialForce(e.alpha))
                            .attr("cx", function(d) { return d.x; })
                            .attr("cy", function(d) { return d.y; });
                    })
                    .start();

                // 自定义径向力函数,让节点保持在半径125的圆附近
                function radialForce(alpha) {
                    return function(d) {
                        var dx = d.x - w/2;
                        var dy = d.y - h/2;
                        var r = Math.sqrt(dx * dx + dy * dy);
                        var k = (125 - r) * alpha * 0.1;
                        d.x += dx * k;
                        d.y += dy * k;
                    };
                }

                // 修正pie布局的语法错误
                var color = d3.scale.category20(); 
                var pie = d3.layout.pie() 
                    .value(function(d) { return 5; });
            </script>
        </div>
    </div>
</body> 
</html>

额外说明

  • 移除了D3 v4+的独立模块,D3 v3已包含这些功能,无需额外引入。
  • 将随机色替换为JSON中提供的ods_color_hex,并添加了透明度,更贴合需求。
  • 补充了缺失的#msg元素,避免DOM操作报错。
  • 使用D3 v3原生的d3.layout.force()实现径向分布效果,替代v4版本的forceRadial。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:21:51