【问题标题】:I am not able to add put labels in 3d donut chart using d3.js我无法使用 d3.js 在 3d 圆环图中添加标签
【发布时间】:2021-06-10 13:43:50
【问题描述】:

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

这是我使用的代码:

    <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,function(d,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,size) {
    svg.append('text')
            .text(text)
            .attr({
                'text-anchor':'middle',
                y:y,
                x:x,
            })
            .style({
                fill:'white',
                'font-size':size,


            });
};

var restOfTheData=function(){

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


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

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



};

setTimeout(restOfTheData,1000);


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

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

【问题讨论】:

    标签: javascript svg d3.js donut-chart


    【解决方案1】:

    这段代码将标签放在饼图周围:

    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,function(d,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,size) {
        svg.append('text')
                .text(text)
                .attr({
                    'text-anchor':'middle',
                    y:y,
                    x:x,
                })
                .style({
                    fill:'white',
                    'font-size':size,
    
    
                });
    };
    
    var restOfTheData=function(){
    
        addText(function(){
            return "$6,830";
        },40,'30px');
    
    
        addText(function(){
            return "Shine's";
        },-20, '20px');
    
        addText(function(){
            return "Monthly Budget";
        },0, '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" />

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多