第二节画上图红线标准的部分
- 思路解析
上图标注的图形可以看出,需要 4 个点的位置分别为p1,p2,p3,p4.通过圆的定理可知道 x= Math.sin(ø) *r
y = Math.cos(ø) *r.我们在类中定义个方法分别计算 4 个点的位置
// 设置引导文字
updatePoints(){
const {radius,startAngle,endAngle,x,y,p1,p2,p3,p4} = this
const dir = (startAngle +endAngle)/2
// p1 点
const p1R = radius +p1.d
p1.x = Math.cos(dir) *p1R +x
p1.y = Math.sin(dir) *p1R +y
// p2 点
const p2R = radius +p2.d
p2.x = Math.cos(dir) *p2R +x
p2.y = Math.sin(dir) *p2R +y
// p3 点
let n = 1
if (p1.x < x){
// 说明线条在左侧, 在左侧
this.textAlign = "right"
n=-1
}
p3.x = p2.x + p3.d *n
p3.y = p2.y
p4.x = p3.x + p4.d *n
p4.y = p3.y
}
饼图完整代码如下
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>饼图</title>
<style>
body {
margin: 0;
overflow: hidden
}
#canvas {
background: antiquewhite;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
<script>
const [width,height]=[window.innerWidth,window.innerHeight];
const canvas = document.getElementById("canvas")
canvas.width = width
canvas.height = height
const ctx = canvas.getContext("2d")
class Sector {
constructor(radius = 200, startAngle = 0, endAngle = Math.PI / 2, color = 'chocolate') {
this.radius = radius //半径
this.startAngle = startAngle
this.endAngle = endAngle
this.color = color
this.x = 0
this.y = 0
this.text = "标签文字"
this.data = 1000
this.textAlign = 'left'
this.p1 = {
x: 0,
y: 0,
d: 20
};
this.p2 = {
x: 0,
y: 0,
d: 70
};
this.p3 = {
x: 0,
y: 0,
d: 20
};
this.p4 = {
x: 0,
y: 0,
d: 10
};
}
// 画线
draw(ctx) {
const {
x,
y,
radius,
startAngle,
endAngle,
textAlign,
color,
text,
p1,
p2,
p3,
p4
} = this
ctx.save()
ctx.beginPath()
ctx.fillStyle = color
ctx.moveTo(x,y)
ctx.arc(x, y, radius, startAngle, endAngle)
ctx.fill()
// 开始画引导线
ctx.beginPath()
ctx.moveTo(p1.x,p1.y) //首先把光标移动到这个点上面
ctx.lineTo(p2.x,p2.y) //画p2点
ctx.lineTo(p3.x,p3.y)//画p3点
ctx.stroke() //画线结束掉
ctx.save()
//开始画文字
ctx.fillStyle = "000"
ctx.font = "14px arail" //文字大小和字体
ctx.textAlign = textAlign//对齐方式
ctx.textBaseline ='middle'//文字基线
ctx.fillText(text,p4.x,p4.y)//绘制文字和文字的位置
ctx.restore()
}
// 设置引导文字
updatePoints(){
const {radius,startAngle,endAngle,x,y,p1,p2,p3,p4} = this
const dir = (startAngle +endAngle)/2
// p1 点
const p1R = radius +p1.d
p1.x = Math.cos(dir) *p1R +x
p1.y = Math.sin(dir) *p1R +y
// p2 点
const p2R = radius +p2.d
p2.x = Math.cos(dir) *p2R +x
p2.y = Math.sin(dir) *p2R +y
// p3 点
let n = 1
if (p1.x < x){
// 说明线条在左侧, 在左侧
this.textAlign = "right"
n=-1
}
p3.x = p2.x + p3.d *n
p3.y = p2.y
p4.x = p3.x + p4.d *n
p4.y = p3.y
}
}
const item = new Sector()
item.x = 400
item.y = 300
item.radius =100
// item.endAngle = Math.PI *3/ 2
item.updatePoints()
item.draw(ctx)
</script>
</html>
网友评论