mirror of
https://github.com/grafana/grafana.git
synced 2025-08-06 16:09:38 +08:00
Render svg instead of canvas
This commit is contained in:
@ -26,7 +26,7 @@ export interface Props extends Themeable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Piechart extends PureComponent<Props> {
|
export class Piechart extends PureComponent<Props> {
|
||||||
canvasElement: any;
|
containerElement: any;
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
pieType: 'pie',
|
pieType: 'pie',
|
||||||
@ -50,46 +50,51 @@ export class Piechart extends PureComponent<Props> {
|
|||||||
const data = datapoints.map(datapoint => datapoint.value);
|
const data = datapoints.map(datapoint => datapoint.value);
|
||||||
const colors = datapoints.map(datapoint => datapoint.color);
|
const colors = datapoints.map(datapoint => datapoint.color);
|
||||||
|
|
||||||
const width = this.canvasElement.width;
|
const width = this.containerElement.offsetWidth;
|
||||||
const height = this.canvasElement.height;
|
const height = this.containerElement.offsetHeight;
|
||||||
const radius = Math.min(width, height) / 2;
|
const radius = Math.min(width, height) / 2;
|
||||||
|
|
||||||
const innerRadius = pieType === PiechartType.PIE ? 0 : radius;
|
const innerRadius = pieType === PiechartType.PIE ? 0 : radius;
|
||||||
|
|
||||||
const context = this.canvasElement.getContext('2d');
|
d3.select('.piechart-container svg').remove();
|
||||||
context.translate(width / 2, height / 2);
|
const svg = d3.select('.piechart-container')
|
||||||
context.globalAlpha = 0.5;
|
.append('svg')
|
||||||
|
.attr('width', width)
|
||||||
|
.attr('height', height)
|
||||||
|
.attr('class', 'shadow')
|
||||||
|
.append('g')
|
||||||
|
.attr('transform', `translate(${width / 2},${height / 2})`);
|
||||||
|
|
||||||
const pie = d3.pie();
|
|
||||||
|
|
||||||
const arcs = pie(data);
|
|
||||||
const arc = d3
|
const arc = d3
|
||||||
.arc()
|
.arc()
|
||||||
.outerRadius(radius - 10)
|
.outerRadius(radius - 10)
|
||||||
.innerRadius(innerRadius)
|
.innerRadius(innerRadius)
|
||||||
.padAngle(0.03)
|
.padAngle(0);
|
||||||
.context(context);
|
|
||||||
|
|
||||||
arcs.forEach((d, idx) => {
|
const pie = d3.pie();
|
||||||
context.beginPath();
|
|
||||||
arc(d as any);
|
|
||||||
context.fillStyle = colors[idx];
|
|
||||||
context.fill();
|
|
||||||
});
|
|
||||||
|
|
||||||
context.globalAlpha = 1;
|
svg.selectAll('path')
|
||||||
context.beginPath();
|
.data(pie(data))
|
||||||
arcs.forEach(arc as any);
|
.enter()
|
||||||
context.lineWidth = strokeWidth;
|
.append('path')
|
||||||
context.stroke();
|
.attr('d', arc as any)
|
||||||
|
.attr('fill', (d: any, i: any) => {
|
||||||
|
return colors[i];
|
||||||
|
})
|
||||||
|
.style('fill-opacity', 0.15)
|
||||||
|
.style('stroke', (d: any, i: any) => {
|
||||||
|
return colors[i];
|
||||||
|
})
|
||||||
|
.style('stroke-width', `${strokeWidth}px`);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { height, width } = this.props;
|
const { height, width } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="piechart-panel">
|
<div className='piechart-panel'>
|
||||||
<div
|
<div
|
||||||
|
ref={element => (this.containerElement = element)}
|
||||||
|
className='piechart-container'
|
||||||
style={{
|
style={{
|
||||||
height: `${height * 0.9}px`,
|
height: `${height * 0.9}px`,
|
||||||
width: `${Math.min(width, height * 1.3)}px`,
|
width: `${Math.min(width, height * 1.3)}px`,
|
||||||
@ -97,7 +102,6 @@ export class Piechart extends PureComponent<Props> {
|
|||||||
margin: 'auto',
|
margin: 'auto',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<canvas ref={element => (this.canvasElement = element)} />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
canvas {
|
svg {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user