How to rotate the D3 chart so that the selected arc is at the bottom?

Viewed 1900

I am trying to develop an application where users can click on the D3 pie chart and see information which relates to the selection. How can I rotate the arc's so that the clicked arc comes to the bottom (the centre of the arc clicked on should be at the bottom)? I have been playing around with rotating the pie by selecting the arc group but I would appreciate any idea on how to achieve this. Here is some code I have so far.

 var self = this;
    var instanceId = Math.floor(Math.random() * 100000);

    var margin = {
        top: 5,
        right: 15,
        bottom: 50,
        left: 20
    };

    self.width = this.htmlElement.parentElement.parentElement.offsetWidth - margin.right - margin.left;
    self.height =   window.innerHeight / 3 ;
    self.curAngle = 0;

    self.svgParent.html("<h4 style='color:green;'>Sponsors </h4><br>");

    // Update data for the chart
    self.updateChartData = function () {

        if(!self.svg) {
            this.svg = this.svgParent
                .classed("svg-container", true)
                .append("svg")
                .attr("preserveAspectRatio", "xMinYMin meet")
                .attr("viewBox", "0 0 " + this.width + " " + this.height)
                .append("g")
                .classed("svg-content-responsive", true);
                //.attr("transform", "translate(" + this.width / 2 + "," + this.height / 2 + ")");
        }

        var svgg = this.svg
          .append("g")
          .classed("svg-content-responsive", true)
          .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        self.svg.selectAll(".arctext").remove();
        self.svg.selectAll(".pie-widget-total-label").remove();

        var pie = d3.pie().sort(sort)(self.selectedData.map(function (d: any) {
            return d.count;
        }));

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

        var outsideLabel = d3.arc()
            .outerRadius(radius * 0.9)
            .innerRadius(radius * 0.9);

        var middleLabel = d3.arc()
            .outerRadius(radius * 0.75)
            .innerRadius(radius * 0.75);

        var insideLabel = d3.arc()
            .outerRadius(radius * 0.6)
            .innerRadius(radius * 0.6);

        var g = self.svg
            .attr("width", self.width + margin.left + margin.right)
            .attr("height", self.height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + self.width / 2 + "," + self.height / 2 + ")");

        var defs = g.append("defs");

        var lightGradients = defs.selectAll(".arc")
            .data(pie)
            .enter()
            .append("radialGradient")
            .attr("id", function (d: any) {
                return "lightGradient-" + instanceId + "-" + d.index;
            })
            .attr("gradientUnits", "userSpaceOnUse")
            .attr("cx", "0")
            .attr("cy", "0")
            .attr("r", "120%");

        var darkGradients = defs.selectAll(".arc")
            .data(pie)
            .enter()
            .append("radialGradient")
            .attr("id", function (d: any) {
                return "darkGradient-" + instanceId + "-" + d.index;
            })
            .attr("gradientUnits", "userSpaceOnUse")
            .attr("cx", "0")
            .attr("cy", "0")
            .attr("r", "120%");

        lightGradients.append("stop")
            .attr("offset", "0%")
            .attr("style", function (d: any) {
                return "stop-color: " + d3.color(color(d.index)) + ";";
            });

        lightGradients.append("stop")
            .attr("offset", "100%")
            .attr("style", function (d: any) {
                return "stop-color: black;";
            });

        darkGradients.append("stop")
            .attr("offset", "0%")
            .attr("style", function (d: any) {
                return "stop-color: " + d3.color(color(d.index)).darker(0.5) + ";";
            });

        darkGradients.append("stop")
            .attr("offset", "100%")
            .attr("style", function (d: any) {
                return "stop-color: black;";
            });

        self.tooltip = d3.select("body")
            .append("div")
            .attr("class", "pie-widget-tooltip")
            .style("opacity", 0);

        self.arc = g.selectAll(".arc")
            .data(pie)
            .enter()
            .append("g")
            .attr("class", "arc");

        var arcpath = self.arc.append("path")
            .attr("id", function (d: any) {
                return d.index;
            })
            .attr("d", path)
            .attr("stroke", "white")
            .attr("stroke-width", "2px")
            .attr("fill", function (d: any) {
                return "url(#lightGradient-" + instanceId + "-" + d.index + ")";
            })
            .on("click", function (d: any) {
                console.log("About to send::::" + getStudyLabel(d.index));
                self.selectedIndustryTypeService.sendMessage(getStudyLabel(d.index));
                self.showDialog();
                self.rotateChart();
             })

            .transition()
            .duration(function(d:any, i:any) {
                return i * 800;
            })
            .attrTween('d', function(d:any) {
                var i = d3.interpolate(d.startAngle + 0.1, d.endAngle);
                return function (t: any) {
                    d.endAngle = i(t);
                    return path(d);
                }
            });

        function arcTween(a: any) {
            var i = d3.interpolate(this._current, a);
            this._current = i(0);
            return function(t: any) {
                return path(i(t));
            };
        }

        var gtext = self.svg
            .append("g")
            .attr("transform", "translate(" + self.width / 2 + "," + self.height / 2 + ")");

        var arctext = gtext.selectAll(".arctext")
            .data(pie)
            .enter()
            .append("g")
            .attr("class", "arctext");

        var primaryLabelText = arctext.append("text")
          .on("click", function (d: any) {
            console.log("About to send::::" + getStudyLabel(d.index));
            self.selectedIndustryTypeService.sendMessage(getStudyLabel(d.index));
            self.showDialog();
          })
            .transition()
            .duration(750)
            .attr("transform", function (d: any) {
                return "translate(" + middleLabel.centroid(d) + ")";
            })
            .attr("dy", "-0.75em")
            .attr("font-family", "sans-serif")
            .attr("font-size", "15px")
            .attr("class", "sponsor-pie-widget-label")
            .text(function (d: any) {
                if (d.endAngle - d.startAngle < 0.3) {
                    return "";
                } else {
                    return getStudyLabel(d.index);
                }
            });

        var secondaryLabelText = arctext.append("text")
          .on("click", function (d: any) {
            console.log("About to send::::" + getStudyLabel(d.index));
            self.selectedIndustryTypeService.sendMessage(getStudyLabel(d.index));
            self.showDialog();
          })
            .transition()
            .duration(750)
            .attr("transform", function (d: any) {
                return "translate(" + middleLabel.centroid(d) + ")";
            })
            .attr("dy", "0.75em")
            .attr("font-family", "sans-serif")
            .attr("font-size", "10px")
            .attr("class", "sponsor-pie-widget-label")
            .text(function (d: any) {
                if (d.endAngle - d.startAngle < 0.3) {
                    return "";
                } else {
                    return getPatientsLabel(d.index);
                }
            });

        var n = 0;
        for (var i = 0; i < self.selectedData.length; i++) {
            n = n + this.selectedData[i]["count"];
        }
        var total = self.svg
            .append("g")
            .attr("transform", "translate(" + (self.width / 2 - 20 ) + "," + self.height / 2 + ")")
        total.append("text")
            .attr("class", "pie-widget-total-label")
            .text("Total\r\n" + n);
    }.bind(self);


    self.showDialog = function() {
        this.router.navigateByUrl('/myRouteName');
    }.bind(self);

    self.rotateChart = function() {
      self.arc.attr("transform", "rotate(-45)");
    }.bind(self);
1 Answers
Related