How to put a legend in a pie chart in d3.js

穿精又带淫゛_ 提交于 2020-05-24 03:30:07

问题


I have this pie chart created in d3.js and want to put some legend on it. But the is almost all of the documentation i've read so far is only for d3.js version 3 and a lot has changed for v5. Some says that there is already a built in legend maker of d3 which i don't understand how to use it. Please help.

Below is my code snippet of the pie chart:

/** START OF PIE CHART */

var data = [{"region_iso_code":"PH-00","total_up_percentage":97.69},{"region_iso_code":"PH-01","total_up_percentage":99.83},{"region_iso_code":"PH-02","total_up_percentage":97.96},{"region_iso_code":"PH-03","total_up_percentage":99.29},{"region_iso_code":"PH-04","total_up_percentage":98.36},{"region_iso_code":"PH-05","total_up_percentage":98.02},{"region_iso_code":"PH-06","total_up_percentage":96.91},{"region_iso_code":"PH-07","total_up_percentage":99.75},{"region_iso_code":"PH-LAG","total_up_percentage":98.84}]

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

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

//create group element to hold pie chart

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

var color = d3.scaleOrdinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"])

var pie = d3.pie().value(function (d) {
    return d.total_up_percentage;
});

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.total_up_percentage);
    })
    .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.total_up_percentage + "%"
    });

/* END OF PIE CHART */
<!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">
    <!--fontawesome-->
    <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
        integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

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

    <!--own css-->
    <style>
        @import "https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700";

        body {
            font-family: 'Poppins', sans-serif;
            background: #fafafa;
        }

        p {
            font-family: 'Poppins', sans-serif;
            font-size: 1.1em;
            font-weight: 300;
            line-height: 1.7em;
            color: #999;
        }

        a,
        a:hover,
        a:focus {
            color: inherit;
            text-decoration: none;
            transition: all 0.3s;
        }

        .navbar {
            padding: 15px 10px;
            background: #fff;
            border: none;
            border-radius: 0;
            margin-bottom: 40px;
            box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
        }

        .navbar-btn {
            box-shadow: none;
            outline: none !important;
            border: none;
        }


        /* ---------------------------------------------------
    SIDEBAR STYLE
----------------------------------------------------- */

        .wrapper {
            display: flex;
            width: 100%;
            align-items: stretch;
        }

        #sidebar {
            min-width: 250px;
            max-width: 250px;
            background: rgb(60, 95, 238);
            color: #fff;
            transition: all 0.3s;
        }

        #sidebar.active {
            margin-left: -250px;
        }

        #sidebar .sidebar-header {
            padding: 20px;
            background: rgb(90, 121, 243);
        }

        #sidebar ul.components {
            padding: 20px 0;
            border-bottom: 1px solid #47748b;
        }

        #sidebar ul p {
            color: #fff;
            padding: 10px;
        }

        #sidebar ul li a {
            padding: 10px;
            font-size: 1.1em;
            display: block;
        }

        #sidebar ul li a:hover {
            color: #7386D5;
            background: #fff;
        }

        #sidebar ul li.active>a,
        a[aria-expanded="true"] {
            color: #fff;
            background: #6d7fcc;
        }

        a[data-toggle="collapse"] {
            position: relative;
        }

        .dropdown-toggle::after {
            display: block;
            position: absolute;
            top: 50%;
            right: 20px;
            transform: translateY(-50%);
        }

        ul ul a {
            font-size: 0.9em !important;
            padding-left: 30px !important;
            background: #6d7fcc;
        }

        ul.CTAs {
            padding: 20px;
        }

        ul.CTAs a {
            text-align: center;
            font-size: 0.9em !important;
            display: block;
            border-radius: 5px;
            margin-bottom: 5px;
        }

        a.download {
            background: #fff;
            color: #7386D5;
        }

        a.article,
        a.article:hover {
            background: #6d7fcc !important;
            color: #fff !important;
        }

        /* ---------------------------------------------------
    CONTENT STYLE
----------------------------------------------------- */

        #content {
            width: 100%;
            padding: 20px;
            min-height: 100vh;
            transition: all 0.3s;
        }

        /* ---------------------------------------------------
    MEDIAQUERIES
----------------------------------------------------- */

        @media (max-width: 768px) {
            #sidebar {
                margin-left: -250px;
            }

            #sidebar.active {
                margin-left: 0;
            }

            #sidebarCollapse span {
                display: none;
            }
        }

        /* ---------------------------------------------------
    CHART STYLE
----------------------------------------------------- 

        /* LINE CHART STYLE */

        .axis--x path {
            display: none;
        }

        .line {
            fill: none;
            stroke: steelblue;
            stroke-width: 1.5px;
        }
    </style>

    <!--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 -->
        <nav id="sidebar">
            <ul class="list-unstyled components">
                <li class="active">
                    <a href="/">DASHBOARD</a>
                </li>
            </ul>
            <!--End of nav.sidebar-->
        </nav>

        <!--Page content-->
        <div id="content">
            <!-- navbar -->
            <nav class="navbar navbar-expand-lg navbar-light bg-light">
                <div class="container-fluid">
                    <button type="button" id="sidebarCollapse" class="btn btn-info">
                        <i class="fas fa-align-justify"></i>
                    </button>
                </div>
            </nav>

            <!--End of div.row-->
            <div class="row">
                <div class="col-12">
                    <div class="card shadow mb-5">
                        <div class="card-body">
                            <div id="pieChart">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <!--End of div.row-->
        </div>


    </div>

    </div>
    <!--End of div.wrapper-->
    <script src="js/script.js"></script>


</body>

</html>

回答1:


Just a draft version to answer your question, please make changes and tweak values as per your requirements.

/** START OF PIE CHART */

var data = [{"region_iso_code":"PH-00","total_up_percentage":97.69},{"region_iso_code":"PH-01","total_up_percentage":99.83},{"region_iso_code":"PH-02","total_up_percentage":97.96},{"region_iso_code":"PH-03","total_up_percentage":99.29},{"region_iso_code":"PH-04","total_up_percentage":98.36},{"region_iso_code":"PH-05","total_up_percentage":98.02},{"region_iso_code":"PH-06","total_up_percentage":96.91},{"region_iso_code":"PH-07","total_up_percentage":99.75},{"region_iso_code":"PH-LAG","total_up_percentage":98.84}]

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

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

//create group element to hold pie chart

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


var color = d3.scaleOrdinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"])

var pie = d3.pie().value(function (d) {
    return d.total_up_percentage;
});

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.total_up_percentage);
    })
    .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.total_up_percentage + "%"
    });






//console.log(pie(data))

var legendG = g.selectAll(".legend")
        .data(pie(data))
        .enter()
        .append("g")
        .attr("transform", function(d,i){
            return "translate(" + (-250) + "," + (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.region_iso_code;
      })
      .style("font-size", 12)
      .attr("y", 10)
      .attr("x", 11);



/* END OF PIE CHART */
<!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">
    <!--fontawesome-->
    <link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
        integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

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

    <!--own css-->
    <style>
        @import "https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700";

        body {
            font-family: 'Poppins', sans-serif;
            background: #fafafa;
        }

        p {
            font-family: 'Poppins', sans-serif;
            font-size: 1.1em;
            font-weight: 300;
            line-height: 1.7em;
            color: #999;
        }

        a,
        a:hover,
        a:focus {
            color: inherit;
            text-decoration: none;
            transition: all 0.3s;
        }

        .navbar {
            padding: 15px 10px;
            background: #fff;
            border: none;
            border-radius: 0;
            margin-bottom: 40px;
            box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.1);
        }

        .navbar-btn {
            box-shadow: none;
            outline: none !important;
            border: none;
        }


        /* ---------------------------------------------------
    SIDEBAR STYLE
----------------------------------------------------- */

        .wrapper {
            display: flex;
            width: 100%;
            align-items: stretch;
        }

        #sidebar {
            min-width: 250px;
            max-width: 250px;
            background: rgb(60, 95, 238);
            color: #fff;
            transition: all 0.3s;
        }

        #sidebar.active {
            margin-left: -250px;
        }

        #sidebar .sidebar-header {
            padding: 20px;
            background: rgb(90, 121, 243);
        }

        #sidebar ul.components {
            padding: 20px 0;
            border-bottom: 1px solid #47748b;
        }

        #sidebar ul p {
            color: #fff;
            padding: 10px;
        }

        #sidebar ul li a {
            padding: 10px;
            font-size: 1.1em;
            display: block;
        }

        #sidebar ul li a:hover {
            color: #7386D5;
            background: #fff;
        }

        #sidebar ul li.active>a,
        a[aria-expanded="true"] {
            color: #fff;
            background: #6d7fcc;
        }

        a[data-toggle="collapse"] {
            position: relative;
        }

        .dropdown-toggle::after {
            display: block;
            position: absolute;
            top: 50%;
            right: 20px;
            transform: translateY(-50%);
        }

        ul ul a {
            font-size: 0.9em !important;
            padding-left: 30px !important;
            background: #6d7fcc;
        }

        ul.CTAs {
            padding: 20px;
        }

        ul.CTAs a {
            text-align: center;
            font-size: 0.9em !important;
            display: block;
            border-radius: 5px;
            margin-bottom: 5px;
        }

        a.download {
            background: #fff;
            color: #7386D5;
        }

        a.article,
        a.article:hover {
            background: #6d7fcc !important;
            color: #fff !important;
        }

        /* ---------------------------------------------------
    CONTENT STYLE
----------------------------------------------------- */

        #content {
            width: 100%;
            padding: 20px;
            min-height: 100vh;
            transition: all 0.3s;
        }

        /* ---------------------------------------------------
    MEDIAQUERIES
----------------------------------------------------- */

        @media (max-width: 768px) {
            #sidebar {
                margin-left: -250px;
            }

            #sidebar.active {
                margin-left: 0;
            }

            #sidebarCollapse span {
                display: none;
            }
        }

        /* ---------------------------------------------------
    CHART STYLE
----------------------------------------------------- 

        /* LINE CHART STYLE */

        .axis--x path {
            display: none;
        }

        .line {
            fill: none;
            stroke: steelblue;
            stroke-width: 1.5px;
        }
    </style>

    <!--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 -->
        <nav id="sidebar">
            <ul class="list-unstyled components">
                <li class="active">
                    <a href="/">DASHBOARD</a>
                </li>
            </ul>
            <!--End of nav.sidebar-->
        </nav>

        <!--Page content-->
        <div id="content">
            <!-- navbar -->
            <nav class="navbar navbar-expand-lg navbar-light bg-light">
                <div class="container-fluid">
                    <button type="button" id="sidebarCollapse" class="btn btn-info">
                        <i class="fas fa-align-justify"></i>
                    </button>
                </div>
            </nav>

            <!--End of div.row-->
            <div class="row">
                <div class="col-12">
                    <div class="card shadow mb-5">
                        <div class="card-body">
                            <div id="pieChart">
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <!--End of div.row-->
        </div>


    </div>

    </div>
    <!--End of div.wrapper-->
    <script src="js/script.js"></script>


</body>

</html>


来源:https://stackoverflow.com/questions/61571681/how-to-put-a-legend-in-a-pie-chart-in-d3-js

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!