繁体   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