2015-08-30 4 views
1

Я создал круговую диаграмму, и она отлично показывается.Как правильно нарисовать текст над круговой диаграммой?

Только я заметил, что какой-то текст скрыт в кусочке пирога. Посмотрев внимательно, я заметил, что каждый текст может быть нарисован следующим фрагментом.

поэтому порядок рендеринга выглядит следующим образом: 1 ломтик, текст 1, ломтик 2, текст 2, 3 ломтика, текст 3, и т.д. ...

Как я могу сделать это так, порядок рендеринга срез 1 , срез 2, срез 3 ... срез n. Затем текст 1, текст 2, текст 3 ... текст n

, а затем текст всегда будет отображаться, так как он будет нарисован поверх каждого фрагмента пирога.

Спасибо, вот мой код

function createChart(dom, newData, title) { 

     d3.select(dom).selectAll("*").remove(); 

     // Define size & radius of donut pie chart 
     var width = 450, 
     height = 800, 
     radius = Math.min(width, height)/2; 

     // Define arc colours 
     var colour = d3.scale.category20(); 

     // Define arc ranges 
     var arcText = d3.scale.ordinal() 
       .rangeRoundBands([0, width], .1, .3); 

     // Determine size of arcs 
     var arc = d3.svg.arc() 
     .innerRadius(radius - 130) 
     .outerRadius(radius - 10); 

     // Create the donut pie chart layout 
     var pie = d3.layout.pie() 
      .value(function (d) { return d.count; }) 
     .sort(null); 

     // Append SVG attributes and append g to the SVG 
     var mySvg = d3.select(dom).append("svg") 
     .attr("width", width) 
     .attr("height", height); 

     var svg = mySvg 
      .append("g") 
      .attr("transform", "translate(" + radius + "," + radius + ")"); 

     var svgText = mySvg 
      .append("g") 
      .attr("transform", "translate(" + radius + "," + radius + ")"); 

     // Define inner circle 
     svg.append("circle") 
     .attr("cx", 0) 
     .attr("cy", 0) 
     .attr("r", 100) 
     .attr("fill", "#fff") ; 

     // Calculate SVG paths and fill in the colours 
     var g = svg.selectAll(".arc") 
       .data(pie(newData)) 
       .enter().append("g") 
       .attr("class", "arc"); 

      // Append the path to each g 
      g.append("path") 
      .attr("d", arc) 
      //.attr("data-legend", function(d, i){ return parseInt(newData[i].count) + ' ' + newData[i].emote; }) 
      .attr("fill", function(d, i) { 
       return colour(i); 
      }); 

      // Append text labels to each arc 
      g.append("text") 
      .attr("transform", function(d) { 
       return "translate(" + arc.centroid(d) + ")"; 
      }) 
      .attr("dy", ".35em") 
      .style("text-anchor", "middle") 
      .attr("fill", "#fff") 
       .text(function(d,i) { return newData[i].count > 0 ? newData[i].emote : ''; }) 

      // Append text to the inner circle 
      svg.append("text") 
      .style("text-anchor", "middle") 
       .attr("fill", "#36454f") 
      .text(function(d) { return title; }) 
      .style("font-size","16px") 
      .style("font-weight", "bold"); 
    } 

ответ

1

Простейшее подход дать text этикетки там собственный g и пересвязать данные:

// there own g 
var textG = svg.selectAll(".labels") 
    .data(pie(newData)) 
    .enter().append("g") 
    .attr("class", "labels"); 

// Append text labels to each arc 
textG.append("text") 
    .attr("transform", function(d) { 
    return "translate(" + arc.centroid(d) + ")"; 
    }) 
    .attr("dy", ".35em") 
    .style("text-anchor", "middle") 
    .attr("fill", "#fff") 
    .text(function(d, i) { 
    return d.data.count > 0 ? d.data.emote : ''; // you can use d.data instead of indexing 
    }); 

Полный пример:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script> 
 
</head> 
 

 
<body> 
 
    <script> 
 
    var newData = [{ 
 
     count: 1, 
 
     emote: "OneTwoThree" 
 
     }, { 
 
     count: 1, 
 
     emote: "FourFiveSix" 
 
     }, { 
 
     count: 1, 
 
     emote: "SevenEightNine" 
 
     }, { 
 
     count: 15, 
 
     emote: "TenElevenTwelve" 
 
     }, 
 

 
    ] 
 

 
    // Define size & radius of donut pie chart 
 
    var width = 450, 
 
     height = 800, 
 
     radius = Math.min(width, height)/2; 
 

 
    // Define arc colours 
 
    var colour = d3.scale.category20(); 
 

 
    // Define arc ranges 
 
    var arcText = d3.scale.ordinal() 
 
     .rangeRoundBands([0, width], .1, .3); 
 

 
    // Determine size of arcs 
 
    var arc = d3.svg.arc() 
 
     .innerRadius(radius - 130) 
 
     .outerRadius(radius - 10); 
 

 
    // Create the donut pie chart layout 
 
    var pie = d3.layout.pie() 
 
     .value(function(d) { 
 
     return d.count; 
 
     }) 
 
     .sort(null); 
 

 
    // Append SVG attributes and append g to the SVG 
 
    var mySvg = d3.select('body').append("svg") 
 
     .attr("width", width) 
 
     .attr("height", height); 
 

 
    var svg = mySvg 
 
     .append("g") 
 
     .attr("transform", "translate(" + radius + "," + radius + ")"); 
 

 
    var svgText = mySvg 
 
     .append("g") 
 
     .attr("transform", "translate(" + radius + "," + radius + ")"); 
 

 
    // Define inner circle 
 
    svg.append("circle") 
 
     .attr("cx", 0) 
 
     .attr("cy", 0) 
 
     .attr("r", 100) 
 
     .attr("fill", "#fff"); 
 

 
    // Calculate SVG paths and fill in the colours 
 
    var g = svg.selectAll(".arc") 
 
     .data(pie(newData)) 
 
     .enter().append("g") 
 
     .attr("class", "arc"); 
 

 
    // Append the path to each g 
 
    g.append("path") 
 
     .attr("d", arc) 
 
     //.attr("data-legend", function(d, i){ return parseInt(newData[i].count) + ' ' + newData[i].emote; }) 
 
     .attr("fill", function(d, i) { 
 
     return colour(i); 
 
     }); 
 

 
    var textG = svg.selectAll(".labels") 
 
     .data(pie(newData)) 
 
     .enter().append("g") 
 
     .attr("class", "labels"); 
 

 
    // Append text labels to each arc 
 
    textG.append("text") 
 
     .attr("transform", function(d) { 
 
     return "translate(" + arc.centroid(d) + ")"; 
 
     }) 
 
     .attr("dy", ".35em") 
 
     .style("text-anchor", "middle") 
 
     .attr("fill", "#fff") 
 
     .text(function(d, i) { 
 
     return d.data.count > 0 ? d.data.emote : ''; 
 
     }); 
 
    </script> 
 
</body> 
 

 
</html>

Смежные вопросы