我无法使用 d3.js 在 3d 圆环图中添加放置标签

问题描述

我使用 codepen 上的代码创建了一个 D3 圆环图,但我无法向其中添加标签。我希望在每个部分的侧面添加标签。为了创建这个圆环图,我使用了 D3.js:

enter image description here

这是我用过的代码

    <script type="text/javascript">
        var dataset = [
    { name: 'Savings',count: 3250 },{ name: 'Housing',count: 1707 },{ name: 'Transportation',count: 377 },{ name: 'Misc',count: 365 },{ name: 'Insurance',count: 314 },{ name: 'Utilities',count: 294 },{ name: 'Student Loans',count: 262 },{ name: 'Food',count: 250 },{ name: 'Phone',count: 10 },];

var total=0;

dataset.forEach(function(d){
    total+= d.count;
});


var pie=d3.layout.pie()
        .value(function(d){return d.count})
        .sort(null);


var data_ready = pie(d3.entries(dataset))
var w=300,h=300;

var outerRadiusArc=w/2;
var innerRadiusArc=100;
var shadowWidth=10;

var outerRadiusArcShadow=innerRadiusArc+1;
var innerRadiusArcShadow=innerRadiusArc-shadowWidth;

var color = d3.scale.ordinal()
 .range(['#f5e232','#64eb34','#2d72e0','#e3251b','#d61be3','#f0b00e','#0ef0c3','#e61240','#db12e6']).domain(["Saving","Housing","Transportayion","Misc","Insurance","Utilities","Student Loan","Food","Phone"])
;

var svg=d3.select("#chart")
        .append("svg")
        .attr({
            width:w,height:h,class:'shadow'
        }).append('g')
        .attr({
            transform:'translate('+w/2+','+h/2+')'
        });


var createChart=function(svg,outerRadius,innerRadius,fillFunction,className){

    var arc=d3.svg.arc()
            .innerRadius(outerRadius)
            .outerRadius(innerRadius);

    var path=svg.selectAll('.'+className)
            .data(pie(dataset))
            .enter()
            .append('path')
            .attr({
                class:className,d:arc,fill:fillFunction
            });

    path.transition()
            .duration(1000)
            .attrTween('d',function(d) {
                var interpolate = d3.interpolate({startAngle: 0,endAngle: 0},d);
                return function(t) {
                    return arc(interpolate(t));
                };
            });
};

createChart(svg,outerRadiusArc,innerRadiusArc,function(d,i){
    return color(d.data.name);
},'path1');

createChart(svg,outerRadiusArcShadow,innerRadiusArcShadow,i){
    var c=d3.hsl(color(d.data.name));
    return d3.hsl((c.h+5),(c.s -.07),(c.l -.15));
},'path2');

var addText= function (text,y,size) {
    svg.append('text')
            .text(text)
            .attr({
                'text-anchor':'middle',y:y
            })
            .style({
                fill:'black','font-size':size,});
};


var addTexttwo= function (text,x,y:y,x:x,})
            .style({
                fill:'white',});
};

var restOfTheData=function(){

    addText(function(){
        return "$6,830";
    },40,'30px');


    addText(function(){
        return "Shine's";
    },-20,'20px');

    addText(function(){
        return "Monthly Budget";
    },'20px');



};

setTimeout(restOfTheData,1000);


function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");
}
    </script>

我希望结果看起来有点像这样。甜甜圈侧面带有标签

enter image description here

解决方法

此代码将标签放在馅饼周围:

const textRadius = d => outerRadiusArc + (d.data.count < 50 ? 15 : 5);
const textX = d => textRadius(d) * Math.sin((d.startAngle + d.endAngle) / 2);
const textY = d => textRadius(d) * -Math.cos((d.startAngle + d.endAngle) / 2);
const textAnchor = d => (d.startAngle + d.endAngle) / 2 > Math.PI ? 'end' : 'start';
            
svg.selectAll('text.label')
  .data(pie(dataset))
  .enter()
  .append('text')
  .classed('label',true)
  .text(d => d.data.name)
  .attr('x',textX)
  .attr('y',textY)
  .attr('text-anchor',textAnchor)
  .attr('alignment-baseline','middle')

var dataset = [
    { name: 'Savings',count: 3250 },{ name: 'Housing',count: 1707 },{ name: 'Transportation',count: 377 },{ name: 'Misc',count: 365 },{ name: 'Insurance',count: 314 },{ name: 'Utilities',count: 294 },{ name: 'Student Loans',count: 262 },{ name: 'Food',count: 250 },{ name: 'Phone',count: 10 },];

var total=0;

dataset.forEach(function(d){
    total+= d.count;
});


var pie=d3.layout.pie()
        .value(function(d){return d.count})
        .sort(null);


var data_ready = pie(d3.entries(dataset))
var w=400,h=300;

var outerRadiusArc=120;
var innerRadiusArc=90;
var shadowWidth=10;

var outerRadiusArcShadow=innerRadiusArc+1;
var innerRadiusArcShadow=innerRadiusArc-shadowWidth;

var color = d3.scale.ordinal()
 .range(['red','#f5e232','orange','#2d72e0','#e3251b','#d61be3','#f0b00e','#0ef0c3','#e61240','#db12e6']).domain(["Saving","Housing","Transportayion","Misc","Insurance","Utilities","Student Loan","Food","Phone"])
;

var svg = d3.select("#chart")
        .append("svg")
        .attr({
            width:w,height:h,class:'shadow'
        }).append('g')
        .attr({
            transform:'translate('+w/2+','+h/2+')'
        });


var createChart=function(svg,outerRadius,innerRadius,fillFunction,className){

    var arc=d3.svg.arc()
            .innerRadius(outerRadius)
            .outerRadius(innerRadius);

    var path=svg.selectAll('.'+className)
            .data(pie(dataset))
            .enter()
            .append('path')
            .attr({
                class:className,d:arc,fill:fillFunction
            });

    path.transition()
            .duration(1000)
            .attrTween('d',function(d) {
                var interpolate = d3.interpolate({startAngle: 0,endAngle: 0},d);
                return function(t) {
                    return arc(interpolate(t));
                };
            })
            .each(d => {
              console.log(d);
            })
   const textRadius = d => outerRadiusArc + (d.data.count < 50 ? 15 : 5);
   const textX = d => textRadius(d) * Math.sin((d.startAngle + d.endAngle) / 2);
   const textY = d => textRadius(d) * -Math.cos((d.startAngle + d.endAngle) / 2);
   const textAnchor = d => (d.startAngle + d.endAngle) / 2 > Math.PI ? 'end' : 'start';
            
   svg.selectAll('text.label')
    .data(pie(dataset))
    .enter()
    .append('text')
    .classed('label',true)
    .text(d => d.data.name)
    .attr('x',textX)
    .attr('y',textY)
    .attr('text-anchor',textAnchor)
    .attr('alignment-baseline','middle')
   /*
   svg.selectAll('circle.point')
    .data(pie(dataset))
    .enter()
    .append('circle')
    .classed('point',true)
    .attr('r',3)
    .attr('cx',textX)
    .attr('cy',textY)
     */                
};

createChart(svg,outerRadiusArc,innerRadiusArc,function(d,i){
    return color(d.data.name);
},'path1');

createChart(svg,outerRadiusArcShadow,innerRadiusArcShadow,i){
    var c=d3.hsl(color(d.data.name));
    return d3.hsl((c.h+5),(c.s -.07),(c.l -.15));
},'path2');

var addText= function (text,y,size) {
    svg.append('text')
            .text(text)
            .attr({
                'text-anchor':'middle',y:y
            })
            .style({
                fill:'black','font-size':size,});
};


var addTexttwo= function (text,x,y:y,x:x,})
            .style({
                fill:'white',});
};

var restOfTheData=function(){

    addText(function(){
        return "$6,830";
    },40,'30px');


    addText(function(){
        return "Shine's";
    },-20,'20px');

    addText(function(){
        return "Monthly Budget";
    },'20px');



};

setTimeout(restOfTheData,1000);


function numberWithCommas(x) {
    return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");
}
.label {
  font-family: 'Ubuntu';
  font-size: 10px;
  
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<div id="chart" />

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...