如何在d3.js中修复饼图标签

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在d3.js中修复饼图标签相关的知识,希望对你有一定的参考价值。

我有一个饼状图,工作正常。但是问题在于,当馅饼的切片如此之小时,无法看到其中的数字:

enter image description here

而不是在绿色切片上看到3.21%。它仅显示21

我该如何解决?我仍然对D3.js仍然很陌​​生,并且正在使用d3版本5。

这是我的代码小提琴:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>DASHBOARD</title>

    <!--Lib css-->
    <!--bootstrap-->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
        integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

    <!--<link rel="stylesheet" href="bootstrapDateTimePicker/daterangepicker.min.css"> -->


    <!--jquery-->
    <script src="https://code.jquery.com/jquery-3.5.0.js"
        integrity="sha256-r/AaFHrszJtwpe+tHyNi/XCfMxYpbsRg2Uqn0x3s2zc=" crossorigin="anonymous"></script>

    <!--own css-->
    <!--lib js-->

    <!--bootstrap-->
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"
        integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6"
        crossorigin="anonymous"></script>

    <!--fontawesome js-->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>

    <!--d3(chart) js-->
    <script src="https://d3js.org/d3.v5.min.js"></script>

</head>

<body>
    <div class="wrapper">
        <!-- Sidebar -->

        <!--Page content-->
        <div id="content">
            <!-- navbar -->
            <div class="container">
                <div class="col-md-6">
                    <div class="card shadow mb-3">
                        <h5 class="card-header">
                            Downtime vs Uptime
                        </h5>
                        <div class="card-body">
                            <div id="pieChart2"></div>
                        </div>
                    </div>
                </div>
            </div>

            <script>

                var data = ["columns_percent":"Down Time","percentage_result":3.21,"columns_percent":"Up Time","percentage_result":96.79];


                var svgCirWidth = 600, svgCirHeight = 300, radius = Math.min(svgCirWidth, svgCirHeight) / 2;

                const pieContainer = d3.select("#pieChart2")
                    .append("svg")
                    .attr("width", svgCirWidth)
                    .attr("height", svgCirHeight);

                //create group element to hold pie chart

                var g = pieContainer.append("g")
                    .attr("transform", "translate(" + 350 + "," + radius + ")");

                var color = d3.scaleOrdinal(d3.schemeSet3);

                var pie = d3.pie().value(function (d) 
                    return d.percentage_result;
                );

                var path = d3.arc()
                    .outerRadius(radius)
                    .innerRadius(0);

                var arc = g.selectAll("arc")
                    .data(pie(data))
                    .enter() //means keeps looping in the data
                    .append("g");

                arc.append("path")
                    .attr("d", path)
                    .attr("fill", function (d) 
                        return color(d.data.percentage_result);
                    )
                    .append("text")
                    .text("afdaf");

                var label = d3.arc()
                    .outerRadius(radius)
                    .innerRadius(0);

                arc.append("text")
                    .attr("transform", (d) => 
                        return "translate(" + label.centroid(d) + ")";
                    )
                    .attr("text-anchor", "middle")
                    .text((d) => 
                        return d.data.percentage_result + "%";
                    );

                var legendG = g.selectAll(".legend")
                    .data(pie(data))
                    .enter()
                    .append("g")
                    .attr("transform", function (d, i) 
                        return "translate(" + (-300) + "," + (i * 15 + 20) + ")";
                    )
                    .attr("class", "legend");

                legendG.append("rect")
                    .attr("width", 10)
                    .attr("height", 10)
                    .attr("fill", function (d) 
                        return color(d.value);
                    );

                legendG.append("text")
                    .text(function (d) 
                        return d.data.columns_percent + " - " + d.data.percentage_result + "%";
                    )
                    .style("font-size", 12)
                    .attr("y", 10)
                    .attr("x", 11);
            </script>


</body>

</html>
答案

最简单的解决方案是切换绘制的SVG路径的顺序,以便最后绘制饼图的最小切片,从而将其绘制在其他元素的顶部。

var data = [

    "columns_percent": "Up Time",
    "percentage_result": 96.79
,
    "columns_percent": "Down Time",
    "percentage_result": 3.21
,
]

Sorting an array of objects by property values

以上是关于如何在d3.js中修复饼图标签的主要内容,如果未能解决你的问题,请参考以下文章

使用 d3.js 向饼图添加工具提示

如何使用 d3 js 在 SVG 中正确使用 Use 标签?

d3.js:饼图布局 - 调整角度以创建快门效果

使用 D3.js 创建频率计数饼图

即使 Web 浏览器控制台中没有错误,d3 js 饼图也没有显示。和 SVG 正在追加

使用 d3.js 和 TypeScript 绘制饼图时出现编译错误