我正在尝试使用静态大小圆圈值实现D3 包布局,我希望 D3 只负责放置,但我发现 d3 覆盖了提供的圆圈大小。我不确定如何保持从数据传递的相同大小。请参阅下面的代码,其中,当我将带有标签的子项的大小RAD从100to更改5000时,我看到其他圆圈的大小正在变化,如何使布局以从数据中获得的确切大小进行渲染?请给我一些指针或jsfiddle
链接到 codepen - https://codepen.io/navinleon/pen/mxZJWr
提前致谢。
var w = 1000,
h = 500;
var data = {
name: "root",
children: [{
label: 'RAD',
size: 100,
color: '#c99700'
}, {
label: 'BIL',
size: 100,
color: '#008ce6'
}, {
label: 'EEN',
size: 100,
color: '#007377'
}, {
label: 'INO',
size: 100,
color: '#b4975a'
}, ]
};
var canvas = d3.select("#canvas")
.append("svg:svg")
.attr('width', w)
.attr('height', h);
var nodes = d3.layout.pack()
.value(function (d) {
return d.size;
}).padding(100)
.size([w, h])
.nodes(data);
// Get rid of root node
nodes.shift();
canvas.selectAll('circles')
.data(nodes)
.enter()
.append('svg:circle')
.attr('cx', function (d) {
return d.x;
})
.attr('cy', function (d) {
return d.y;
})
.attr('r', function (d) {
return d.r;
})
.attr('fill', function (d) {
return d.color;
});
Run Code Online (Sandbox Code Playgroud)
事实上,有一种方便的方法,名为d3.packSiblings,它似乎正是您所需要的(无需任何力模拟)来定位节点。
根据API:
\n\n\n\n\n打包指定的圆数组,每个圆都必须具有
\ncircle.r指定圆\xe2\x80\x99s 半径的属性。
因此,将size数据中的属性更改为r,您所需要的只是:
var packed = d3.packSiblings(data.children);\nRun Code Online (Sandbox Code Playgroud)\n\n这是演示:
\n\nvar packed = d3.packSiblings(data.children);\nRun Code Online (Sandbox Code Playgroud)\r\nvar data = {\r\n name: "root",\r\n children: [{\r\n label: \'RAD\',\r\n r: 50,\r\n color: \'#c99700\'\r\n }, {\r\n label: \'BIL\',\r\n r: 75,\r\n color: \'#008ce6\'\r\n }, {\r\n label: \'EEN\',\r\n r: 20,\r\n color: \'#007377\'\r\n }, {\r\n label: \'INO\',\r\n r: 42,\r\n color: \'#b4975a\'\r\n }, ]\r\n};\r\n\r\nvar packed = d3.packSiblings(data.children);\r\n\r\nvar w = 500,\r\n h = 400;\r\nvar svg = d3.select("body")\r\n .append("svg")\r\n .attr("width", w)\r\n .attr("height", h)\r\n .append("g")\r\n .attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");\r\n\r\nvar color = d3.scaleOrdinal(d3.schemeCategory10);\r\n\r\nvar nodes = svg.selectAll(null)\r\n .data(data.children)\r\n .enter()\r\n .append("circle")\r\n .attr("cx", function(d) {\r\n return d.x\r\n })\r\n .attr("cy", function(d) {\r\n return d.y\r\n })\r\n .attr("r", function(d) {\r\n return d.r\r\n })\r\n .style("fill", function(_, i) {\r\n return color(i)\r\n })Run Code Online (Sandbox Code Playgroud)\r\n您实际上不需要圆形包装布局。圆包布局必然适合数组指定区域中的所有圆pack.size。
由于您想自己设置圆圈的大小并且希望 D3 只负责放置,所以我想到的最明显的选择是使用力模拟。
\n\nforceX在此建议的解决方案中,我们将使用和将焦点设置为 SVG 的中心forceY。然后,我们将停止模拟并运行给定的次数(元素越少,需要的迭代就越少):
var simulation = d3.forceSimulation(data.children)\n .force("x", d3.forceX(w / 2))\n .force("y", d3.forceY(h / 2))\n .force("collide", d3.forceCollide(function(d) {\n return d.size\n }))\n .stop();\nRun Code Online (Sandbox Code Playgroud)\n\n这是一些演示。
\n\n首先,将所有圆的半径设置为 100:
\n\n<script src="https://d3js.org/d3.v5.min.js"></script>Run Code Online (Sandbox Code Playgroud)\r\nvar simulation = d3.forceSimulation(data.children)\n .force("x", d3.forceX(w / 2))\n .force("y", d3.forceY(h / 2))\n .force("collide", d3.forceCollide(function(d) {\n return d.size\n }))\n .stop();\nRun Code Online (Sandbox Code Playgroud)\r\n现在让我们将 3 个圆的大小减小到 20 个:
\n\nvar w = 500,\r\n h = 400;\r\nvar svg = d3.select("body")\r\n .append("svg")\r\n .attr("width", w)\r\n .attr("height", h);\r\n\r\nvar color = d3.scaleOrdinal(d3.schemeCategory10)\r\n\r\nvar data = {\r\n name: "root",\r\n children: [{\r\n label: \'RAD\',\r\n size: 100,\r\n color: \'#c99700\'\r\n }, {\r\n label: \'BIL\',\r\n size: 100,\r\n color: \'#008ce6\'\r\n }, {\r\n label: \'EEN\',\r\n size: 100,\r\n color: \'#007377\'\r\n }, {\r\n label: \'INO\',\r\n size: 100,\r\n color: \'#b4975a\'\r\n }, ]\r\n};\r\n\r\nvar simulation = d3.forceSimulation(data.children)\r\n .force("x", d3.forceX(w / 2))\r\n .force("y", d3.forceY(h / 2))\r\n .force("collide", d3.forceCollide(function(d) {\r\n return d.size\r\n }))\r\n .stop();\r\n\r\nfor (var i = 0; i < 100; ++i) simulation.tick();\r\n\r\nvar nodes = svg.selectAll(null)\r\n .data(data.children)\r\n .enter()\r\n .append("circle")\r\n .attr("cx", function(d) {\r\n return d.x\r\n })\r\n .attr("cy", function(d) {\r\n return d.y\r\n })\r\n .attr("r", function(d) {\r\n return d.size\r\n })\r\n .style("fill", function(_, i) {\r\n return color(i)\r\n })Run Code Online (Sandbox Code Playgroud)\r\n<script src="https://d3js.org/d3.v5.min.js"></script>Run Code Online (Sandbox Code Playgroud)\r\n现在所有圆圈的大小均为 10:
\n\nvar w = 500,\r\n h = 400;\r\nvar svg = d3.select("body")\r\n .append("svg")\r\n .attr("width", w)\r\n .attr("height", h);\r\n\r\nvar color = d3.scaleOrdinal(d3.schemeCategory10)\r\n\r\nvar data = {\r\n name: "root",\r\n children: [{\r\n label: \'RAD\',\r\n size: 20,\r\n color: \'#c99700\'\r\n }, {\r\n label: \'BIL\',\r\n size: 100,\r\n color: \'#008ce6\'\r\n }, {\r\n label: \'EEN\',\r\n size: 20,\r\n color: \'#007377\'\r\n }, {\r\n label: \'INO\',\r\n size: 20,\r\n color: \'#b4975a\'\r\n }, ]\r\n};\r\n\r\nvar simulation = d3.forceSimulation(data.children)\r\n .force("x", d3.forceX(w / 2))\r\n .force("y", d3.forceY(h / 2))\r\n .force("collide", d3.forceCollide(function(d) {\r\n return d.size\r\n }))\r\n .stop();\r\n\r\nfor (var i = 0; i < 100; ++i) simulation.tick();\r\n\r\nvar nodes = svg.selectAll(null)\r\n .data(data.children)\r\n .enter()\r\n .append("circle")\r\n .attr("cx", function(d) {\r\n return d.x\r\n })\r\n .attr("cy", function(d) {\r\n return d.y\r\n })\r\n .attr("r", function(d) {\r\n return d.size\r\n })\r\n .style("fill", function(_, i) {\r\n return color(i)\r\n })Run Code Online (Sandbox Code Playgroud)\r\n<script src="https://d3js.org/d3.v5.min.js"></script>Run Code Online (Sandbox Code Playgroud)\r\n最后,让其中一个圆的大小为 5000。您唯一看到的就是整个 SVG 为单一颜色...但这就是您所要求的:圆的半径为 5000 像素。核实:
\n\nvar w = 500,\r\n h = 400;\r\nvar svg = d3.select("body")\r\n .append("svg")\r\n .attr("width", w)\r\n .attr("height", h);\r\n\r\nvar color = d3.scaleOrdinal(d3.schemeCategory10)\r\n\r\nvar data = {\r\n name: "root",\r\n children: [{\r\n label: \'RAD\',\r\n size: 10,\r\n color: \'#c99700\'\r\n }, {\r\n label: \'BIL\',\r\n size: 10,\r\n color: \'#008ce6\'\r\n }, {\r\n label: \'EEN\',\r\n size: 10,\r\n color: \'#007377\'\r\n }, {\r\n label: \'INO\',\r\n size: 10,\r\n color: \'#b4975a\'\r\n }, ]\r\n};\r\n\r\nvar simulation = d3.forceSimulation(data.children)\r\n .force("x", d3.forceX(w / 2))\r\n .force("y", d3.forceY(h / 2))\r\n .force("collide", d3.forceCollide(function(d) {\r\n return d.size\r\n }))\r\n .stop();\r\n\r\nfor (var i = 0; i < 100; ++i) simulation.tick();\r\n\r\nvar nodes = svg.selectAll(null)\r\n .data(data.children)\r\n .enter()\r\n .append("circle")\r\n .attr("cx", function(d) {\r\n return d.x\r\n })\r\n .attr("cy", function(d) {\r\n return d.y\r\n })\r\n .attr("r", function(d) {\r\n return d.size\r\n })\r\n .style("fill", function(_, i) {\r\n return color(i)\r\n })Run Code Online (Sandbox Code Playgroud)\r\n<script src="https://d3js.org/d3.v5.min.js"></script>Run Code Online (Sandbox Code Playgroud)\r\n| 归档时间: |
|
| 查看次数: |
2007 次 |
| 最近记录: |