Saturday, November 24, 2018

D3 - Donut Chart

Here  I do a WEB API call and get the required data.


Sample code is as below

$(document).ready(function () {

    var jsonDataTshirt = {};
    var tshirts = [];

    jsonDataTshirt.tshirts = tshirts;
.
.
.


    //1) get tshirt sizes
    $.getJSON("API/MyWEBAPICall",
        function (Data) {

            $.each(Data, function (key, val) {

                if (key != "$id") {
                    var uCategory = { "fruit": key, "count": Number(val) };
                    jsonDataTshirt.tshirts.push(uCategory);
                }
            });

            // margin
            var margin = { top: 20, right: 20, bottom: 20, left: 20 },
                width = 400 - margin.right - margin.left,
                height = 400 - margin.top - margin.bottom,
                radius = width / 2 - 20;

            // color range
            var color = d3.scaleOrdinal()
                .range(["#BBDEFB", "#90CAF9", "#64B5F6", "#42A5F5", "#2196F3", "#1E88E5", "#1976D2"]);

            // donut chart arc
            var arc2 = d3.arc()
                .outerRadius(radius - 10)
                .innerRadius(radius - 70);

            // arc for the labels position
            var labelArc = d3.arc()
                .outerRadius(radius - 40)
                .innerRadius(radius - 40);

            // generate pie chart and donut chart
            var pie = d3.pie()
                .sort(null)
                .value(function (d) { return d.count; });

            // define the svg donut chart
            var svg2 = d3.select("#pie-tshirts-male").append("svg")
                .attr("width", width)
                .attr("height", height)
              .append("g")
                .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

            var data = jsonDataTshirt.tshirts;
            // parse data
            data.forEach(function (d) {
                d.count = +d.count;
                d.fruit = d.fruit;
            })

            // "g element is a container used to group other SVG elements"
            var g2 = svg2.selectAll(".arc2")
                .data(pie(data))
              .enter().append("g")
                .attr("class", "arc2");

            // append path
            g2.append("path")
                .attr("d", arc2)
                .style("fill", function (d) { return color(d.data.fruit); })
              .transition()
                .ease(d3.easeLinear)
                .duration(2000)
                .attrTween("d", tweenDonut);

            // append text
            g2.append("text")
              .transition()
                .ease(d3.easeLinear)
                .duration(2000)
              .attr("transform", function (d) { return "translate(" + labelArc.centroid(d) + ")"; })
                .attr("dy", ".35em")
                .text(function (d) { return d.data.fruit; });

            //Add the count in outside the arc
                g2.append("text")
                    .transition()
                    .ease(d3.easeLinear)
                    .duration(2000)
                    .attr("transform", function(d) {
                        var _d = labelArc.centroid(d);
                        _d[0]*= 1.4; //multiply by a constant factor
                        _d[1] *= 1.4; //multiply by a constant factor
                        return "translate(" +_d + ")";
                        })
                    .attr("dy", ".35em")
                    .text(function (d) {
                       return d.data.count;
                        })
                    .style("font-size", "10px");;

            function tweenDonut(b) {
                b.innerRadius = 0;
                var i = d3.interpolate({ startAngle: 0, endAngle: 0 }, b);
                return function (t) { return arc2(i(t)); };
            }

        });
.
.
.
});


Sample: Do nut chart is drawn as shown in the middle