[英]d3 donut chart transform: translateY
我正在制作一个图表,其中显示了每种数据类型的百分比,如下所示:
但是我复制代码时遇到问题,我创建的代码与前面的示例相同,但是标题将它们放在百分比上方,我想通过将它们放在第一张图像中的数字上方来修复它,因为我像这样:
这是我发送来调用文本的代码,在示例中它已经向我抛出了一个转换,但我想上传它以便它保留为标题
svg
.selectAll("allLabels")
.data(name_ready)
.enter()
.append("text")
.text(function (d) {
console.log(d.data.key);
return d.data.key;
})
.style("font-size", "1rem")
.attr("transform", function (d) {
var pos = outerArc.centroid(d);
var midangle = d.startAngle + (d.endAngle - d.startAngle) / 2;
pos[0] = radius * 0.99 * (midangle < Math.PI ? 1 : -1);
return "translate(" + pos + ")";
})
.attr("class", "fontDonut")
.style("text-anchor", function (d) {
var midangle = d.startAngle + (d.endAngle - d.startAngle) / 2;
return midangle < Math.PI ? "start" : "end";
});
代码是这样的,因为它是自动的,它根据有多少数据来定位自己
// set the dimensions and margins of the graph var width = 400; var height = 250; // The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin. var radius = 100; // append the svg object to the div called 'my_dataviz' var svg = d3 .select("#my_char") .append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); // Create dummy data var data = { "25%": 25, "30% ": 30, "20%": 20, "25% ": 25 } var name = { "Married": 30, "Divorced": 30, "Single": 40, "Single2 ": 25 } // set the color scale var color = d3 .scaleOrdinal([`#C8DBFB`, `#93B6F8`, `#256EF1`]); // Compute the position of each group on the pie: var pie = d3 .pie() .sort(null) // Do not sort group by size .value(function(d) { return d.value; }); var data_ready = pie(d3.entries(data)); var name_ready = pie(d3.entries(name)); // The arc generator var arc = d3 .arc() .innerRadius(radius * 0.6) // This is the size of the donut hole .outerRadius(radius * 0.8); // Another arc that won't be drawn. Just for labels positioning var outerArc = d3 .arc() .innerRadius(radius * 0.9) .outerRadius(radius * 0.9); // Build the pie chart: Basically, each part of the pie is a path that we build using the arc function. svg .selectAll("allSlices") .data(data_ready) .enter() .append("path") .attr("d", arc) .attr("fill", function(d) { return color(d.data.key); }) .style("opacity", 0.7); // Add the polylines between chart and labels: svg .selectAll("allLabels") .data(data_ready) .enter() .append("text") .text(function(d) { console.log(d.data.key); return d.data.key; }) .style("font-size", "2rem") .style("font-weight", "700") .attr("transform", function(d) { var pos = outerArc.centroid(d); var midangle = d.startAngle + (d.endAngle - d.startAngle) / 2; pos[0] = radius * 0.99 * (midangle < Math.PI ? 1 : -1); return "translate(" + pos + ")"; }) .style("text-anchor", function(d) { var midangle = d.startAngle + (d.endAngle - d.startAngle) / 2; return midangle < Math.PI ? "start" : "end"; }); svg .selectAll("allLabels") .data(name_ready) .enter() .append("text") .text(function(d) { console.log(d.data.key); return d.data.key; }) .style("font-size", "1rem") .attr("transform", function(d) { var pos = outerArc.centroid(d); var midangle = d.startAngle + (d.endAngle - d.startAngle) / 2; pos[0] = radius * 0.99 * (midangle < Math.PI ? 1 : -1); return "translate(" + pos + ")"; }) .attr("class", "fontDonut") .style("text-anchor", function(d) { var midangle = d.startAngle + (d.endAngle - d.startAngle) / 2; return midangle < Math.PI ? "start" : "end"; });
.fontDonut { margin-top: 8rem; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.0.0/d3.min.js"></script> <div class="text-center bg-white shadow py-6 px-6 chart-container"> <div class="flex justify-start font-bold mb-4 "> <p class="font-bold ml-4">Children</p> </div> <div id="my_char" /> </div>
不要将这两个值视为单独的值,而是将它们当作一个块来使用。 我像你一样使用基本的三角函数来找到中点的角度,然后从中心画一条线,所以标签与圆弧的中间对齐,并且所有标签与甜甜圈的距离相同。
然后,我不必摆弄标签,而只需在顶部添加百分比,并带有一个小的偏移量。 请注意, margin
仅适用于 HTML,不适用于 SVG。
// set the dimensions and margins of the graph var width = 400; var height = 250; // The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin. var radius = 100; // append the svg object to the div called 'my_dataviz' var svg = d3 .select("#my_char") .append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); // Create dummy data var data = { //"Married": 30, "Divorced": 30, "Single": 40, "Single2 ": 25 } // set the color scale var color = d3 .scaleOrdinal([`#C8DBFB`, `#93B6F8`, `#256EF1`, `darkblue`]); // Compute the position of each group on the pie: var pie = d3 .pie() .sort(null) // Do not sort group by size .value(function(d) { return d.value; }); var data_ready = pie(d3.entries(data)); // The arc generator var arc = d3 .arc() .innerRadius(radius * 0.6) // This is the size of the donut hole .outerRadius(radius * 0.8); // Another arc that won't be drawn. Just for labels positioning var outerArc = d3 .arc() .innerRadius(radius * 0.9) .outerRadius(radius * 0.9); // Build the pie chart: Basically, each part of the pie is a path that we build using the arc function. svg .selectAll("path") .data(data_ready) .enter() .append("path") .attr("d", arc) .attr("fill", function(d) { return color(d.data.key); }) .style("opacity", 0.7); // Add the polylines between chart and labels: const labelGroup = svg .selectAll(".labelGroup") .data(data_ready) .enter() .append("g") .attr("class", "labelGroup") // Transform the whole group, not the individual text items .attr("transform", function(d) { // Get the angle var midAngle = d.startAngle + (d.endAngle - d.startAngle) / 2; // Define the radius var textRadius = 1.4 * radius; // Use trigonometry to find the correct position var x = Math.sin(midAngle) * textRadius; var y = -Math.cos(midAngle) * textRadius; y = Math.min(y, height / 2 - 20); return "translate(" + [x, y] + ")"; }) .style("text-anchor", "middle"); labelGroup .append("text") .text(function(d) { return d.data.key; }) .attr("dominant-baseline", "hanging") .attr("dy", 5) .style("font-size", "2rem") .style("font-weight", "700"); labelGroup .append("text") .text(function(d) { return d.data.value + "%"; }) .attr("dy", -5) .style("font-size", "1rem");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.0.0/d3.min.js"></script> <div class="text-center bg-white shadow py-6 px-6 chart-container"> <div class="flex justify-start font-bold mb-4 "> <p class="font-bold ml-4">Children</p> </div> <div id="my_char" /> </div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.