簡體   English   中英

SVG / D3.js在餅圖的標簽前面添加圖像

[英]SVG / D3.js Add image in front of labels of a pie chart

我在這里有一個簡單的餅圖:
https://jsfiddle.net/5dexn2kn/1/

現在,我想每個標簽前面添加一個圖標,如下所示:
在此處輸入圖片說明

我嘗試將圖像附加到每個標簽組
https://jsfiddle.net/5dexn2kn/2/

如您所見,由於text-anchor可能是startend ,而且每個標簽的文本長度也不同,所以我不知道如何查找圖像並將其放置在正確的位置。

我該如何實現?

也許這會有所幫助: https : //jsfiddle.net/5dexn2kn/3/

輸入文字ID:

labelG.append('text')
  .attr('id', function(d) {
    return d.data.label + '_text'
  })

這必須是唯一的。 在這種情況下,它可以工作,但是如果您有時使用相同的標簽,則不會。

然后獲得相應標簽文本的寬度,如下所示:

var thisText = document.getElementById(d.data.label + '_text') //select based on data, as id above is given from data
var thisTextWidth = thisText.clientWidth;

然后使用相同的邏輯來確定您是希望文本錨點start還是end來確定圖像的位置:

    if ((d.endAngle + d.startAngle) / 2 > Math.PI) {
      return -35 - thisTextWidth;
    } else {
      return -25;
    }

您可以使用getBoundingBox()函數來實現此目的。

代碼

labelG.append('image')
  .attr('xlink:href', 'https://placekitten.com/20/20?.jpg')
  .attr('height', 20)
  .attr('width', 20)
  .attr("x", function(d) {
    var bbox = this.parentNode.getBBox();
    return bbox.x;
  })
  .attr("y", function() {
    var bbox = this.parentNode.getBBox();
    return bbox.y;
  });

labelG.selectAll("text").attr("dx", 25);

完整片段

 const width = 400 const height = 400 const labelSpace = 50 const donutRadius = Math.min(width, height) / 2 const maxRadius = donutRadius + labelSpace const colorScheme = d3.scaleOrdinal(d3.schemeCategory20) const innerRadius = 20 const svgTranslate = [width / 2 + labelSpace * 2, height / 2 + labelSpace * 2] function getPercent(value, total) { return Math.round(value / total * 100) } const data = [{ label: 'aaaaaaa', value: 19 }, { label: 'bbb', value: 31 }, { label: 'c', value: 31 }, { label: 'ddddddddddd', value: 8 }, { label: 'eeee', value: 10 }] const total = data.map(d => d.value).reduce((a, b) => a + b) const svg = d3.select('#donutchart') .append('svg') .attr('width', width + maxRadius) .attr('height', height + maxRadius) .append('g') .attr('transform', `translate(${svgTranslate[0]}, ${svgTranslate[1]})`) const arc = d3.arc() .innerRadius(innerRadius) .outerRadius(donutRadius) const donut = d3.pie() .sort(null) .value(d => d.value) const arcG = svg.selectAll('g.arc-g') .data(donut(data)) .enter() .append('g') arcG.append('path') .attr('d', arc) .attr('fill', d => colorScheme(d.data.label)) const labelG = arcG.append('g') .attr('transform', d => { const c = arc.centroid(d) const x = c[0] * 2 const y = c[1] * 2 return `translate(${x}, ${y})` }) labelG.append('text') .attr('dy', '.35em') .html(d => `${d.data.label}<tspan class="label-percent"> ${getPercent(d.data.value, total)}%</tspan>` ) .attr('text-anchor', d => (d.endAngle + d.startAngle) / 2 > Math.PI ? 'end' : 'start' ) labelG.append('image') .attr('xlink:href', 'https://placekitten.com/20/20?.jpg') .attr('height', 20) .attr('width', 20) .attr("x", function(d) { var bbox = this.parentNode.getBBox(); return bbox.x; }) .attr("y", function() { var bbox = this.parentNode.getBBox(); return bbox.y; }); labelG.selectAll("text").attr("dx", 25); 
 body { font-family: San Francisco Display, sans-serif; } .label-percent { font-weight: bold; } 
 <div id="donutchart"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.min.js"></script> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM