繁体   English   中英

如何旋转D3图表以使所选圆弧位于底部?

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

我正在尝试开发一个应用程序,用户可以单击D3饼图并查看与选择有关的信息。 如何旋转圆弧,使单击的圆弧位于底部(单击的圆弧的中心应位于底部)? 我一直在通过选择弧线组来旋转饼图,但是对于实现该方法的任何想法,我将不胜感激。 这是我到目前为止的一些代码。

 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);

您可以通过适当地更改圆弧的开始/结束角度来旋转圆弧,但这会比所需的复杂。

一个更简单的解决方案是旋转容纳整个饼图的g ,同时以其他方式旋转所有标签,以使它们保持水平。

我只是以该块中的规范饼图为例:

 var svg = d3.select("svg"), width = +svg.attr("width"), height = +svg.attr("height"), radius = Math.min(width, height) / 2, g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); var color = d3.scaleOrdinal(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]); var data = [ {age:"<5", population: 2704659},{age:"5-13", population: 4499890},{age:"14-17", population: 2159981},{age:"18-24", population: 3853788},{age:"25-44", population: 14106543},{age:"45-64", population: 8819342},{age:"≥65", population: 612463} ] var pie = d3.pie() .sort(null) .value(function(d) { return d.population; }); var path = d3.arc() .outerRadius(radius - 10) .innerRadius(0); var label = d3.arc() .outerRadius(radius - 40) .innerRadius(radius - 40); var arc = g.selectAll(".arc") .data(pie(data)) .enter().append("g") .attr("class", "arc"); arc.append("path") .attr("d", path) .attr("fill", function(d) { return color(d.data.age); }) .on("click",function(d) { // The amount we need to rotate: var rotate = 180-(d.startAngle + d.endAngle)/2 / Math.PI * 180; // Transition the pie chart g.transition() .attr("transform", "translate(" + width / 2 + "," + height / 2 + ") rotate(" + rotate + ")") .duration(1000); // Τransition the labels: text.transition() .attr("transform", function(dd) { return "translate(" + label.centroid(dd) + ") rotate(" + (-rotate) + ")"; }) .duration(1000); }); var text = arc.append("text") .attr("transform", function(d) { return "translate(" + label.centroid(d) + ")"; }) .attr("dy", "0.35em") .text(function(d) { return d.data.age; }); 
 .arc text { font: 10px sans-serif; text-anchor: middle; } .arc path { stroke: #fff; } 
 <svg width="960" height="500"></svg> <script src="https://d3js.org/d3.v4.min.js"></script> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM