简体   繁体   English

如何更改压缩圆d3中圆的对齐方式

[英]How to change the alignment of circles in packed circle d3

I'm trying to change the alignment of the circle so that I can see the text in the middle Just like in this image.我正在尝试更改圆圈的对齐方式,以便我可以看到中间的文本,就像在这张图片中一样。

图片

I need help on how to align all the circles towards the circumference of the outer circle.我需要有关如何将所有圆与外圆的圆周对齐的帮助。 I tried to add the text but it is overlapping with the circle in the center.我试图添加文本,但它与中心的圆圈重叠。 Is it possible to change the alignment of the circle?是否可以更改圆的对齐方式?

My code is mentioned below.我的代码在下面提到。

 var root = { "name": "flare", "threat_level": "High", "size": 15000, "children": [{ "name": "Ghost", "threat_level": "High", "size": 1200 }, { "name": "Wiper", "threat_level": "Medium", "size": 1330 }, { "name": "PowerLiks", "threat_level": "Medium", "size": 1333 }, { "name": "Fareit", "threat_level": "Medium", "size": 1300 }, { "name": "Tribe", "threat_level": "High", "size": 1330 }, { "name": "Oilrig", "threat_level": "High", "size": 1330 } ] } var svg = d3.select("svg"), margin = 20, diameter = +svg.attr("width"), g = svg.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")"); const color = (type) => type == 'High' ? '#F72047' : (type == 'Medium' ? '#FFFFFF' : '#fff0') //colorScale var defs = svg.append("defs"); var levels = ['High', 'Medium', 'Low'] levels.forEach((d) => { //Create a radial Sun-like gradient defs.append("radialGradient") .attr("id", "sun-gradient_" + d) .selectAll("stop") .data([{ offset: "0%", color: "#1A1D27" }, { offset: "80%", color: "#1A1D27" }, { offset: "100%", color: d == 'High' ? "#CB1F40" : "#959595" } ]) .enter().append("stop") .attr("offset", function (d) { return d.offset; }) .attr("stop-color", function (d) { return d.color; }); // .interpolate(d3.interpolateHcl); }) var pack = d3.pack() .size([diameter - margin, diameter - margin]) .padding(50); root = d3.hierarchy(root) .sum(function (d) { return d.size; }) .sort(function (a, b) { return b.value - a.value; }); var focus = root, nodes = pack(root).descendants(), view; var circle = g.selectAll("circle") .data(nodes) .enter().append("circle") .attr("class", function (d) { return d.parent ? d.children ? "node" : "node node--leaf" : "node node--root"; }) .style("fill", (d) => `url(#${'sun-gradient_' + d.data.threat_level})`) .style('stroke', (d) => color(d.data.threat_level)) .style('stroke-width', 1) .on("click", function (e, d) { if (focus !== d) zoom(d); e.stopPropagation(); }); var text = g.selectAll("text") .data(nodes) .enter().append("text") .attr("class", "label") .text(function (d) { return d.parent === root ? d.data.name : d.data.size; }) .style('font-family', 'Metropolis Bold') .style('font-size', (d) => d.parent === root ? '12px' : '24px') .style('text-anchor', 'middle') .style('fill', (d) => d.parent === root ? '#FFFFFF' : '#F72047') .style('text-transform', 'uppercase') var node = g.selectAll("circle,text"); svg .style("background", color(-1)) .on("click", function () { zoom(root); }); zoomTo([root.x, root.y, root.r * 2 + margin]); function zoom(d) { var focus0 = focus; focus = d; var transition = d3.transition() .duration(750) .tween("zoom", function (d) { var i = d3.interpolateZoom(view, [focus.x, focus.y, focus.r * 2 + margin]); return function (t) { zoomTo(i(t)); }; }); transition.selectAll("text") .filter(function (d) { return d.parent === focus || this.style.display === "inline"; }) .style("fill-opacity", function (d) { return d.parent === focus ? 1 : 0; }) .on("start", function (d) { if (d.parent === focus) this.style.display = "inline"; }) .on("end", function (d) { if (d.parent !== focus) this.style.display = "none"; }); } function zoomTo(v) { var k = diameter / v[2]; view = v; node.attr("transform", function (d) { return "translate(" + (dx - v[0]) * k + "," + (dy - v[1]) * k + ")"; }); circle.attr("r", function (d) { return dr * k; }); }
 <svg width="600" height="600"></svg> <script src="https://d3js.org/d3.v4.min.js"></script>

The packed circle layout is designed to take a group of objects and pack them as tightly as possible within a circle.打包的圆形布局旨在获取一组对象并将它们尽可能紧密地打包在一个圆圈内。 So this isn't what you want.所以这不是你想要的。

Method 1: Radial Tree Layout方法一:径向树布局

If you want to arrange a set of objects evenly around the circumference of a circle with a given radius, you want something similar to a "radial tree layout".如果你想在给定半径的圆周上均匀地排列一组对象,你需要类似于“径向树布局”的东西。 You can see an example of that in Chapter 6 of the book you linked to ( Tree, Cluster, and Radial Layouts ), though you'll not want the lines between the nodes.您可以在您链接到的书的第 6 章中看到一个示例(树、簇和径向布局),尽管您不希望节点之间有线条。

There's also an example given in the answer to this question: d3.js - how to arrange the `squre` box around the `circle` properly这个问题的答案中还给出了一个例子: d3.js - 如何正确地在 `circle` 周围安排 `squre` 框

Method 2: Use sin and cos方法二:使用sincos

Alternatively, you can divide the circumference of the circle by the number of objects you want to place, then use sin and cos to calculate their center point x and y manually.或者,您可以将圆的周长除以要放置的对象数,然后使用sincos手动计算它们的中心点 x 和 y。

There's an example of that here: d3.js radially position elements around an object这里有一个例子: d3.js 在对象周围径向定位元素

And a variation here: https://spin.atomicobject.com/2015/06/12/objects-around-svg-circle-d3-js/这里有一个变体: https ://spin.atomicobject.com/2015/06/12/objects-around-svg-circle-d3-js/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM