ASP.NET Razor Pages+d3.v3报错:无法读取undefined的weight属性
问题
使用ASP.NET Razor Pages技术栈实现无向图:在PageModel中用C#定义Node、Link类生成数据,序列化为JSON传递给前端,再用d3.v3.min.js绘制图形。运行时触发报错:
Uncaught TypeError: Cannot read properties of undefined (reading 'weight') at l.start (d3.v3.min.js:4:22672) at GraphTesting:102:5
未定义过weight属性,无法定位其来源,完整代码如下:
Node类
public class Node { public int Id { get; set; } public string Label { get; set; } public Node(int id, string label) { Id = id; Label = label; } }
Link类
public class Link { public int Source { get; set; } public int Target { get; set; } public int Value { get; set; } public Link(int source, int target, int value) { Source = source; Target = target; Value = value; } }
PageModel代码
public class GraphTestingModel : PageModel { public string GraphData { get; private set; } public void OnGet() { var nodes = GetNodes(); var links = GetLinks(); var data = new { nodes, links }; GraphData = JsonConvert.SerializeObject(data); } private List<Node> GetNodes() { var nodes = new List<Node> { new Node(0, "Myriel"), new Node(1, "Napoleon"), new Node(2, "MlleBaptistine"), new Node(3, "MmeMagloire"), new Node(4, "CountessDeLo"), new Node(5, "Geborand"), new Node(6, "Champtercier"), new Node(7, "Cravatte"), new Node(8, "Count"), new Node(9, "OldMan"), new Node(10, "Labarre") }; return nodes; } private List<Link> GetLinks() { var links = new List<Link> { new Link(1, 0, 1), new Link(2, 0, 8), new Link(3, 0, 10), new Link(3, 2, 6), new Link(4, 0, 1), new Link(5, 0, 1), new Link(6, 0, 1), new Link(7, 0, 1), new Link(8, 0, 2), new Link(9, 0, 1) }; return links; } }
视图代码
<head> <meta charset="UTF-8"> <title>Spider Diagram</title> <script src="https://d3js.org/d3.v3.min.js"></script> <style> svg { font: 10px sans-serif; } .link { stroke: #999; stroke-opacity: 0.6; } .node circle { fill: #fff; stroke: steelblue; stroke-width: 1.5px; } .node text { font-size: 12px; } </style> </head> <body> <div id="graph"></div> <script> var data = @Html.Raw(Model.GraphData); console.log(data); var width = 960, height = 500, radius = 6; var force = d3.layout.force() .gravity(.05) .charge(-120) .linkDistance(80) .size([width, height]); var svg = d3.select("#graph").append("svg") .attr("width", width) .attr("height", height); var color = d3.scale.category20(); force .nodes(data.nodes) .links(data.links) .start(); var link = svg.selectAll(".link") .data(data.links); var node = svg.selectAll(".node") .data(data.nodes); node.exit().remove(); link.exit().remove(); link.enter().append("line") .attr("class", "link") .style("stroke-width", function (d) { if ("value" in d) { return Math.sqrt(d.value); } else { return 1; } }); var groups = node.enter() .append("g") .attr("class", "node"); groups.append("circle").attr("r", function (d) { if ("id" in d) { return 5; } else { return 0; } }) .style("fill", function (d) { return color(d.value); }) .call(force.drag); groups.append("text") .attr("dx", 12) .attr("dy", ".35em") .text("hi"); node.selectAll("text") .text(function (d) { if ("label" in d) { return d.label; } else { return d.id; } } ); force.on("tick", function () { link.attr("x1", function (d) { return d.source.x; }) .attr("y1", function (d) { return d.source.y; }) .attr("x2", function (d) { return d.target.x; }) .attr("y2", function (d) { return d.target.y; }); node.attr("cx", function (d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); }) .attr("cy", function (d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); }); node.attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; }); }); </script> </body>
原因分析
weight属性来自D3.v3的力导向布局(d3.layout.force)。在D3.v3中,力布局默认会读取链接对象的weight属性来计算链接强度,若链接对象没有该属性,就会抛出上述错误。你的Link类定义的是Value属性(序列化后为value),与D3默认期望的weight不匹配,导致报错。
解决方案
1. 指定链接强度的属性
修改力布局初始化代码,添加.linkStrength()方法,显式指定使用value作为链接强度的计算依据:
var force = d3.layout.force() .gravity(.05) .charge(-120) .linkDistance(80) .linkStrength(function(d) { return d.value; }) // 新增此行,指定用value计算强度 .size([width, height]);
2. 修复节点属性冲突
视图代码中tick事件处理里,同时设置了<g>元素(node)的cx/cy和transform属性,但<g>元素没有cx/cy属性,会导致无效操作,需删除cx/cy相关代码:
force.on("tick", function () { link.attr("x1", function (d) { return d.source.x; }) .attr("y1", function (d) { return d.source.y; }) .attr("x2", function (d) { return d.target.x; }) .attr("y2", function (d) { return d.target.y; }); // 删除以下两行无效代码 // node.attr("cx", function (d) { return d.x = Math.max(radius, Math.min(width - radius, d.x)); }) // .attr("cy", function (d) { return d.y = Math.max(radius, Math.min(height - radius, d.y)); }); node.attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; }); });
内容的提问来源于stack exchange,提问作者Finsser
相关产品推荐
相关产品推荐

