我这里有一个简单的饼图:
https://jsfiddle.net/5dexn2kn/1/
我尝试将图像附加到每个标签组
https://jsfiddle.net/5dexn2kn/2/
如你所见,因为text-anchor
可能是start
或end
,而且每个label的文本长度不同,我不知道如何找到图像并将其放置到正确的位置。
我怎样才能做到这一点?
最佳答案
您可以使用 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>
关于javascript - SVG/D3.js 在饼图标签前添加图片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40341138/