javascript - D3.js:现场旋转文本

标签 javascript d3.js pie-chart coordinate-transformation

我有一个饼图,其中包含 38 个项目。半径相当大,因此文本向内转。我遇到的唯一问题是文字颠倒了。我尝试仅通过正常旋转来解决此问题,但这不起作用,因为它围绕整个图表的中心旋转。我寻找答案并发现类似的东西。我尝试使用 that code为了我自己的目的但失败了。

我还检查了 example on b.locks据我了解:它们在这里旋转,然后将其放置在之前的位置。

我的文字做了很多事情,但几乎不是我想要的。在当前状态下,它将所有内容堆叠在我的图表中间。

这是我的代码:

var margin = { left:80, right:100, top:50, bottom:100 },
    height = 1200 - margin.top - margin.bottom, 
    width = 1280 - margin.left - margin.right,
    cwidth = 50;

var svg = d3.select("#pie-chart svg")
    .append("g")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .attr("transform", "translate(" + 525 + "," + 450 + ")")
    .append("g")

/*gives the same numeric value to every object in the datafile (cuz they dont have numeric values) */     
var pie = d3.pie()
    .value(function(d){return 1})
;

//load data
d3.json("./data/unidata.json").then(function(data){
    //console.log(data);  
    var arc = d3.arc();

    var gs = svg.selectAll("g")
                .data(d3.values(data))
                .enter()
                .append("g")
                .attr("transform", "translate(" + margin.left + ", " + margin.top + ")")
    ;

    var arcIndexDictionary = {};
    var arcRingIndexSizeDictionary = {};


    // Visible arc
    gs.selectAll("path")
        .data(function(d,i) {       
            return pie(d).map(function(e){e.ringIndex = i; return e});
        })
        .enter()
        .append("path")
        .attr("class", "nameArc")
        .attr("id", function(d,i) { 
            return d.data.name + "nameArc_"+i+i; 
        })
        .attr("d", 
            function(d, i) {
                var innerRadius = cwidth * d.ringIndex;
                var outerRadius = cwidth * (d.ringIndex + 1);
                var outerRadiusSlim = cwidth * (d.ringIndex + 1) + 2 * cwidth;
                // stores how many items are there in a ring in order to decide which text to flip
                arcRingIndexSizeDictionary[d.ringIndex] = i;
                // Main Arc - draws the rings
                if (d.ringIndex == 0){
                    arcIndexDictionary[d.data.name + "nameArc_"+i] = (innerRadius + outerRadius) / 2.0;
                    return arc.innerRadius(innerRadius).outerRadius(outerRadius)(d);
                }
                else if (d.ringIndex == 1){
                    arcIndexDictionary[d.data.name + "nameArc_"+i] = (innerRadius + outerRadiusSlim) / 2.04; 
                    return arc.innerRadius(innerRadius).outerRadius(outerRadiusSlim)(d);
                }
            }
        )
        .attr("fill", "grey") 
    ;

    // Placing text
    gs.selectAll(".nameText")
        .data(function(d,i) {       
            return pie(d).map(function(e){e.ringIndex = i; return e});
        })
        .enter()
        .append("text")
            .attr("class", "nameText")  
            .attr('dy', function(d, i, array){
            var ringItemCount = arcRingIndexSizeDictionary[d.ringIndex];
        }) 
        .append("textPath")
            .attr("xlink:href",function(d, i, array){
                return "#" + d.data.name + "nameArc_"+i+i;   
            })        
        .style("text-anchor", function(d, i){
                var ringItemCount = arcRingIndexSizeDictionary[d.ringIndex];    
                if(d.ringIndex == 1 && i <= ringItemCount/2) {
                    return "start"; //HERE
                } else {
                    return "start"
                }           
                })
        .attr("startOffset", function(d, i){ 
            if(d.ringIndex == 1 && i <= ringItemCount/2) 
                return "50%"; 
                if(d.ringIndex == 1) return "12%";   
                var ringItemCount = arcRingIndexSizeDictionary[d.ringIndex];
            }) 
        .text(function(d, i, array){ 
            if (d.ringIndex > 0)
            {return d.data.name};
            })
            .style('font-family', 'arial')
            .attr('font-size', function(d){
                if(d.ringIndex > 1){return '13px'} else {
                    return '9px';
                }})
    ;


    // ROTATE
    d3.selectAll("text")
    // https://stackoverflow.com/questions/26049488/how-to-get-absolute-coordinates-of-object-inside-a-g-group
    .attr("transform", function(d, i){
        if(d != undefined)
        {
            var ringItemCount = arcRingIndexSizeDictionary[d.ringIndex];          
            var rightPieCount = ringItemCount / 2;
            var halfPoint = rightPieCount / 2;  
            if(d.ringIndex == 1 && i <= ringItemCount/2)
            {
                // if you add 1 to x you need to add 180 / 19 * i
                var locationData = this.getBBox();
                var centerX = locationData.x + (locationData.width / 2);
                var centerY = locationData.y + (locationData.height / 2);
                // Fix their centralized locations 
                /*  
                if (locationData.y < 0){
                    centerX = centerX + i * 7;
                    centerY = centerY - (halfPoint - i) * 6;   
                } else {
                    centerX = centerX + (rightPieCount - i) * 7;
                    centerY = centerY - (-(halfPoint - i) * 6);
                } */
                console.log(centerX, centerY);
                var result = "";
                result += 'translate(' + centerX + ',' + centerY + ')';
                result += 'rotate(180)';
                return result;
            }
        }
    })
    ;

    // middle text
    gs.append("text")
        .attr("text-anchor", "middle")
        .attr('font-size', '0.8em')
        .attr('font-family', 'arial')
        .style('fill', 'white')
        .text("Inf FB") 

})

我还在下面的缩短版本中添加了我的数据集。 由于我是 D3 的新手,如果有人能告诉我如何实现文本现场旋转或指导我如何实现目标的另一个方向,我将非常感激:) 非常感谢。

{   "Leitsatz": [],
    "Profs": [
        {
            "name": "Softwarekonstruktion"
        },
        {
            "name": "Verteilte Systeme"
        },
        {
            "name": "Angew. Softwaretechnik"
        },
        {
            "name": "Sicherheit"
        },
        {
            "name": "(W1) Sicherheit/ Sicherheitsmgmt."
        },
        {
            "name": "Rechennetze"
        },
        {
            "name": "Theoretische Inf."
        },
        {
            "name": "(W1) Theoretische Inf.)"
        },
        {
            "name": "(W1) Informatikbildung)"
        },
        {
            "name": "(W1) Mobile Services"
        },
        {
            "name": "(W1TT) Informatik"
        },
        {
            "name": "Wiss. Rechnen (DKRZ)"
        },
        {
            "name": "Wiss. Visualisierung (Dir. RRZ)"
        },
        {
            "name": "Daten Enginieering"
        },
        {
            "name": "Simulation & Visualisierung"
        },
        {
            "name": "Alg. Molekulares Design"
        },
        {
            "name": "(W1) Angewandte Bioinf."
        },
        {
            "name": "Rechnerg. Bioinformatik"
        },
        {
            "name": "Maschinelles Lernen"
        },
        {
            "name": "Autonome Systeme"
        },
        {
            "name": "(W1TT) Sem. Systeme"
        },
        {
            "name": "Wissenstechnologien"
        },
        {
            "name": "Signalverarbeitung"
        },
        {
            "name": "Bildverarbeitung"
        },
        {
            "name": "(W1TT) Assistenzsysteme"
        },
        {
            "name": "Sprachverarbeitung"
        },
        {
            "name": "Sprachtechnologie"
        },
        {
            "name": "Multimodale Systeme"
        },
        {
            "name": "Mensch-Computer-Interaktion"
        },
        {
            "name": "Usability & Softwareergonomie"
        },
        {
            "name": "Ethik in der Informationstechnik"
        },
        {
            "name": "IT-Gestaltung"
        },
        {
            "name": "(W1TT) Wirtschaftsinformatik"
        },
        {
            "name": "(W1TT) Betriebssystem"
        },
        {
            "name": "(W1TT) Adaptive Systeme"
        },
        {
            "name": "IT Management"
        },
        {
            "name": "Digital Technochange"
        },
        {
            "name": "Datenbanken"
        }
    ]
}   

最佳答案

要绕其中心旋转某物,您需要将其中心移动到 (0, 0),旋转它,然后将其移回。因此,在添加转换的地方,请执行以下操作:

// ROTATE
d3.selectAll("text")
  .attr("transform", function(d, i) {
    if (d !== undefined) {
        var ringItemCount = arcRingIndexSizeDictionary[d.ringIndex];
        if (d.ringIndex == 1 && i <= ringItemCount / 2) {
            var locationData = this.getBBox();
            var centerX = locationData.x + (locationData.width / 2);
            var centerY = locationData.y + (locationData.height / 2);

            var result = 'translate(' + centerX + ',' + centerY + ')';
            result += 'rotate(180)';
            result += 'translate(' + (-centerX) + ',' + (-centerY) + ')';
            return result;
        }
    }
});

关于javascript - D3.js:现场旋转文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59930164/

相关文章:

html - IE 9 中的 Rapheal 饼图渲染问题

javascript - 尝试查找 JS 代码中的错误 - 使用 Javascript 更改 CSS

javascript - 更改 jquery 中一组元素的一个 attr 名称但不同的值

javascript - Bootstrap 3 容器内的文本覆盖全 Angular 图像

javascript - 使用D3生成基本表时tbody标签元素返回空

javascript - 最简单的 D3.js 示例不起作用

Prototype 的 Ajax.Updater 导致 JavaScript 内存丢失?

javascript - SVG 文本的动态样式

internet-explorer - CSS3 PIE 不适用于 IE7 和 IE8

highcharts - 如何将两个饼图( Highcharts )相邻对齐