简体   繁体   English

D3.js:当场旋转文本

[英]D3.js: Rotate text on-spot

I have a pie chart with a 38 items in it.我有一个饼图,里面有 38 个项目。 The radius is quite big and thus the text turns inward.半径很大,因此文本向内转。 The only problem I have is that the text stands upside down.我唯一的问题是文本倒置。 I tried to fix that with just a normal rotation but that doesn't work, as it rotates around the center of my whole graph.我试图通过正常旋转来解决这个问题,但这不起作用,因为它围绕我整个图形的中心旋转。 I searched for answers and found smth similar.我搜索了答案,发现有些相似。 I tried to use that code for my own purposed but failed.我试图为自己的目的使用该代码,但失败了。

I also checked an example on b.locks and as far as I understand it: Here they rotate and then just place it at the spot where it was before.我还检查了一个关于 b.locks例子,据我所知:在这里它们旋转,然后将它放在之前的位置。

My text did a lot of stuff but hardly what I wanted.我的文字做了很多事情,但几乎没有我想要的。 With the current state it stacks everything in the middle of my graph.在当前状态下,它将所有内容堆叠在我的图表中间。

Here is my code:这是我的代码:

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

})

I'm also adding my data-set in a shortened version below.我还在下面的缩短版本中添加了我的数据集。 As I am new to D3 I would really appreciate if someone could tell me how to achieve that the text rotates on spot or direct me in another direction on how to achieve my goal :) Thanks a lot.由于我是 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"
        }
    ]
}   

To rotate something about its centre you need to move its centre to (0, 0), them rotate it, then move it back.要围绕其中心旋转某些东西,您需要将其中心移动到 (0, 0),然后旋转它,然后将其移回。 So where you are adding the transforms, do:因此,在添加转换的位置,请执行以下操作:

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

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

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