【问题标题】:Data binding in d3 v3 donut chartd3 v3 圆环图中的数据绑定
【发布时间】:2021-05-23 15:14:47
【问题描述】:

所以我一直在尝试在 d3.js 中创建一个圆环图,但在向图表添加标签时遇到了麻烦。我的图表数据在一个数组中,但我认为由于“pie”变量,只有数据中的“值”被传递,而不是“文本”。尝试了多种方法来尝试将“文本”带入但没有运气。希望有一双新的眼睛能看出我的错误在哪里!

var margin = {top: 10, right: 30, bottom: 30, left: 60},
    width = 750 - margin.left - margin.right,
    height = 520 - margin.top - margin.bottom;

var r = height/3;

var aColor = [
    '#0652DD',
    '#C4E538',
    '#F79F1F', 
    '#5758BB',
    '#D980FA',
    "#EA2027"
]

var piedata = [
    {text:"Facebook", "value":76}, 
    {text:"Website", "value":13},
    {text:"HardwareZone", "value":4}, 
    {text:"YouTube", "value":5},
    {text:"Instagram", "value":1},
    {text:"Twitter","value":1},
];

var vis = d3.select('#chart2')
.append("svg:svg")
.data([piedata])
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("svg:g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");


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

// Declare an arc generator function
var arc = d3.svg.arc().innerRadius(r *0.5).outerRadius(r*0.8);

var outerArc = d3.svg.arc()
              .innerRadius(r*0.95)
              .outerRadius(r*0.95);

// Select paths, use arc generator to draw
var arcs = vis.selectAll("g.slice").data(pie).enter().append("svg:g").attr("class", "slice").attr("transform", "translate("  + width/2 + "," + height/2 + ")");

arcs.append("g:path")
    .attr("fill", function(d, i){return aColor[i];})
    .attr("d", function (d) {return arc(d);})
    .attr("stroke", "white")
    .style("stroke-width", "3px")
    .style("opacity", 0.7)  
;

  // Add the polylines between chart and labels:
arcs.append("g:polyline")
    .attr("stroke", "black")
    .style("fill", "none")
    .attr("stroke-width", "1px")
    .attr('points', function(d) {
      var posA = arc.centroid(d) // line insertion in the slice
      var posB = outerArc.centroid(d) + 5 // line break: we use the other arc generator that has been built only for that
      var posC = outerArc.centroid(d) + 5; // Label position = almost the same as posB
      var midangle = d.startAngle + (d.endAngle - d.startAngle) / 2 // we need the angle to see if the X position will be at the extreme right or extreme left
      posC[0] = r * 0.95 * (midangle < Math.PI ? 1 : -1); // multiply by 1 or -1 to put it on the right or on the left
      return [posA, posB, posC]
    });
  
    //Add text labels

    arcs.append("g:label")
      .attr('transform', function(d) {
      var pos = outerArc.centroid(d);
      var midangle = d.startAngle + (d.endAngle - d.startAngle) / 2
      pos[0] = r * 0.99 * (midangle < Math.PI ? 1 : -1);
      return 'translate(' + pos + ')';
      })
      .style('text-anchor', function(d) {
      var midangle = d.startAngle + (d.endAngle - d.startAngle) / 2
      return (midangle < Math.PI ? 'start' : 'end')
       })
      .text(function(d) { return d.text; }); //this is where the problem is!
    

【问题讨论】:

    标签: javascript svg d3.js


    【解决方案1】:

    以下是添加标签的方法:

    arcs.append('text')
      .text(d => d.data.text)
      .attr('dy', 4)
      .attr('text-anchor', d => (d.startAngle + d.endAngle) / 2 > Math.PI ? 'end' : 'start')
      .attr('x', d => outerArc.centroid(d)[0])
      .attr('y', d => outerArc.centroid(d)[1]);
    

    var margin = {top: 10, right: 30, bottom: 30, left: 60},
        width = 750 - margin.left - margin.right,
        height = 520 - margin.top - margin.bottom;
    
    var r = height/3;
    
    var aColor = [
        '#0652DD',
        '#C4E538',
        '#F79F1F', 
        '#5758BB',
        '#D980FA',
        "#EA2027"
    ]
    
    var piedata = [
        {text:"Facebook", "value":76}, 
        {text:"Website", "value":13},
        {text:"HardwareZone", "value":4}, 
        {text:"YouTube", "value":5},
        {text:"Instagram", "value":1},
        {text:"Twitter","value":1},
    ];
    
    var vis = d3.select('#chart2')
    .append("svg:svg")
    .data([piedata])
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("svg:g")
    .attr("transform",
    "translate(" + margin.left + "," + margin.top + ")");
    
    
    var pie = d3.layout.pie().sort(null).value(function(d){return d.value;});
    
    // Declare an arc generator function
    var arc = d3.svg.arc().innerRadius(r *0.5).outerRadius(r*0.8);
    
    var outerArc = d3.svg.arc()
                  .innerRadius(r*0.95)
                  .outerRadius(r*1.1);
    
    // Select paths, use arc generator to draw
    var arcs = vis.selectAll("g.slice").data(pie).enter().append("svg:g").attr("class", "slice").attr("transform", "translate("  + width/2 + "," + height/2 + ")");
    
    arcs.append("g:path")
        .attr("fill", function(d, i){return aColor[i];})
        .attr("d", function (d) {return arc(d);})
        .attr("stroke", "white")
        .style("stroke-width", "3px")
        .style("opacity", 0.7)  
    ;
    
      // Add the polylines between chart and labels:
    arcs.append("g:polyline")
        .attr("stroke", "black")
        .style("fill", "none")
        .attr("stroke-width", "1px")
        .attr('points', function(d) {
          var posA = arc.centroid(d) // line insertion in the slice
          var posB = outerArc.centroid(d) + 5 // line break: we use the other arc generator that has been built only for that
          var posC = outerArc.centroid(d) + 5; // Label position = almost the same as posB
          var midangle = d.startAngle + (d.endAngle - d.startAngle) / 2 // we need the angle to see if the X position will be at the extreme right or extreme left
          posC[0] = r * 0.95 * (midangle < Math.PI ? 1 : -1); // multiply by 1 or -1 to put it on the right or on the left
          return [posA, posB, posC]
        });
      
        //Add text labels
        arcs.append('text')
            .text(d => d.data.text)
          .attr('dy', 4)
          .each(d => console.log(d))
          .attr('text-anchor', d => (d.startAngle + d.endAngle) / 2 > Math.PI ? 'end' : 'start')
          .attr('x', d => outerArc.centroid(d)[0])
          .attr('y', d => outerArc.centroid(d)[1]);
          
    text {
      font-size: 16px;
      font-family: "Ubuntu";
      fill: black;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
    <div id="chart2" />

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多