我试图在力布局中的所有组上绘制凸包.但我只设法画出一半的凸壳.当D3尝试绘制剩余的外壳时,控制台返回ERROR:尚未创建元素.然而,当我检查控制台中的“groups”变量时,所有组数据都存在x,y数据都很好地设置.见下图:
我甚至尝试在刻度函数中延迟绘制船体,但它仍然不起作用&我得到了相同的结果(如下图所示).
JSFiddle: Only getting half the no. of convex hulls I want
这是代码:
<script> var radius = 5.5; var color = d3.scaleOrdinal(d3.schemeCategory20b); var scale = d3.scaleLinear() .domain([0.5,1]) .range([1.8,3.8]); var svg2 = d3.select("#svg2"); var w = +svg2.attr("width"),h = +svg2.attr("height"); var hull = svg2.append("path") .attr("class","hull"); var groupPath = function(d) { return "M" + d3.polygonHull(d.values.map(function(i) { return [i.x,i.y]; })) .join("L") + "Z"; }; function ticked() { 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; }); fnode .attr("cx",function (d) { return d.x = Math.max(radius,Math.min(w - radius,d.x)); }) .attr("cy",function (d) { return d.y = Math.max(radius,Math.min(h - radius,d.y)); }) .attr("r",radius); delayHull(6000); } function delayHull(delay) { setTimeout(function() { svg2.selectAll("path") .data(groups) .attr("d",groupPath) .enter() .append("path") .attr("class","hull") .attr("d",groupPath); },delay); } var simulation,link,fnode,groups; var fnodeg = svg2.append("g") .attr("class","fnode"); var linkg = svg2.append("g") .attr("class","links") .attr("id","linkg"); d3.json("..//vizData//forceLayout//forceLayout_15000.json",function(error,graph) { if (error) throw error; simulation = d3.forceSimulation() .force("link",d3.forceLink().id(function (d) { return d.id; }).distance(30).strength(1)) .force("charge",d3.forceManyBody().strength(-2).distanceMin(15).distanceMax(180)) .force("center",d3.forceCenter(w / 2,h / 2)) .force("collide",d3.forceCollide().strength(1).iterations(2)); link = linkg.selectAll("line") .data(graph.links) .enter().append("line") .attr("stroke-width",function (d) { return scale(d.value); }); fnode = fnodeg.selectAll("circle") .data(graph.nodes) .enter().append("circle") .attr("r",radius) .attr("fill",function (d) { return color(d.truth); }); simulation .nodes(graph.nodes); simulation.force("link") .links(graph.links); groups = d3.nest().key(function(d) { return d.group; }).entries(graph.nodes); simulation.on("tick",ticked); fnode.append("title") .text(function (d) { return d.id; }); link.append("title") .text(function (d) { return d.value; }); }) </script>
我参考了这个http://bl.ocks.org/donaldh/2920551凸壳实例;他在tick函数之外设置了他的“groups”变量,这没关系.
我究竟做错了什么???
解决方法
在
Andrew’s answer的基础上,当集群只有两个点时,您可以简单地推送另一个内部数组:
if (d.values.length === 2) { var arr = d.values.map(function(i) { return [i.x,i.y]; }) arr.push([arr[0][0],arr[0][1]]); return "M" + d3.polygonHull(arr).join("L") + "Z";
以下是仅包含此更改的代码:
var radius = 5.5; var color = d3.scaleOrdinal(d3.schemeCategory20b); var scale = d3.scaleLinear() .domain([0.5,1]) .range([1.8,3.8]); var svg2 = d3.select("#svg2"); var w = +svg2.attr("width"),h = +svg2.attr("height"); var hull = svg2.append("path") .attr("class","hull"); var groupPath = function(d) { if (d.values.length === 2) { var arr = d.values.map(function(i) { return [i.x,i.y]; }) arr.push([arr[0][0],arr[0][1]]); return "M" + d3.polygonHull(arr).join("L") + "Z"; } else { return "M" + d3.polygonHull(d.values.map(function(i) { return [i.x,i.y]; })) .join("L") + "Z"; } }; function ticked() { 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; }); fnode .attr("cx",function(d) { return d.x = Math.max(radius,function(d) { return d.y = Math.max(radius,radius); delayHull(1000); } function delayHull(delay) { setTimeout(function() { svg2.selectAll("path") .data(groups) .attr("d",groupPath) .enter() .append("path") .attr("class","hull") .attr("d",groupPath); },delay); } var simulation,groups; var fnodeg = svg2.append("g") .attr("class","fnode"); var linkg = svg2.append("g") .attr("class","links") .attr("id","linkg"); d3.json('https://api.myjson.com/bins/bkzxh',graph) { if (error) throw error; simulation = d3.forceSimulation() .force("link",d3.forceLink().id(function(d) { return d.id; }).distance(30).strength(1)) .force("charge",d3.forceCollide().strength(1).iterations(2)); link = linkg.selectAll("line") .data(graph.links) .enter().append("line") .attr("stroke-width",function(d) { return scale(d.value); }); fnode = fnodeg.selectAll("circle") .data(graph.nodes) .enter().append("circle") .attr("r",function(d) { return color(d.truth); }); simulation .nodes(graph.nodes); simulation.force("link") .links(graph.links); groups = d3.nest().key(function(d) { return d.group; }).entries(graph.nodes); simulation.on("tick",ticked); fnode.append("title") .text(function(d) { return d.id; }); link.append("title") .text(function(d) { return d.value; }); });
.links line { stroke: #999; stroke-opacity: 0.8; } .fnode circle { stroke: #fff; stroke-width: 1.5px; fill-opacity: 1; } .hull { fill: steelblue; stroke: steelblue; fill-opacity: 0.3; stroke-opacity: 0.3; stroke-width: 10px; stroke-linejoin: round; }
<script src="https://d3js.org/d3.v4.js"></script> <svg id="svg2" width="600" height="600" style="margin-left: -5px"></svg>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。