Circle.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /**
  2. * 双环形图
  3. *
  4. * @author hanyaolong
  5. */
  6. export class SCircle {
  7. /**
  8. * 构造函数
  9. *
  10. * @param {canvasid} id
  11. */
  12. constructor(id,radius =60) {
  13. const canvas = document.getElementById(id);
  14. this.ctx = canvas.getContext("2d");
  15. this.percent = 100; //最终百分比
  16. this.circleX = canvas.width / 2; //中心x坐标
  17. this.circleY = canvas.height / 2; //中心y坐标
  18. this.radius = radius; //圆环半径
  19. this.lineWidth = 5; //圆形线条的宽度
  20. this.fontSize = radius *3/4; //字体大小
  21. this.baseName = '本月总任务'
  22. }
  23. /**
  24. * 绘制圆
  25. *
  26. * @param {x} cx
  27. * @param {y} cy
  28. * @param {半径} r
  29. */
  30. circle(cx, cy, r) {
  31. this.ctx.beginPath();
  32. this.ctx.lineWidth = this.lineWidth;
  33. this.ctx.strokeStyle = '#2a4886';
  34. this.ctx.arc(cx, cy, r, 0, (Math.PI * 2), true);
  35. this.ctx.stroke();
  36. }
  37. /**
  38. * 设置中心文字
  39. *
  40. * @param {文本} text
  41. */
  42. setText(text) {
  43. this.ctx.beginPath();
  44. //中间的字
  45. this.ctx.font = this.fontSize + 'px April';
  46. this.ctx.textAlign = 'center';
  47. this.ctx.textBaseline = 'middle';
  48. this.ctx.fillStyle = '#ffffff';
  49. this.ctx.fillText(text, this.circleX, this.circleY);
  50. this.ctx.stroke();
  51. this.ctx.beginPath()
  52. this.ctx.font = this.fontSize / 3 + 'px April';
  53. this.ctx.textAlign = 'center';
  54. this.ctx.textBaseline = 'middle';
  55. this.ctx.fillStyle = '#ffffff';
  56. this.ctx.fillText(this.baseName, this.circleX, this.circleY + this.fontSize * 3 / 4);
  57. this.ctx.stroke();
  58. }
  59. /**
  60. * 绘制圆弧
  61. *
  62. * @param {x} cx
  63. * @param {y} cy
  64. * @param {半径} r
  65. */
  66. sector(cx, cy, r, endAngle, strokeStyle = "#c81d39") {
  67. this.ctx.beginPath();
  68. this.ctx.lineWidth = this.lineWidth;
  69. this.ctx.strokeStyle = strokeStyle ? strokeStyle : '#c81d39';
  70. //圆弧两端的样式
  71. this.ctx.lineCap = 'round';
  72. if(endAngle == 0){
  73. this.ctx.lineCap = 'butt'
  74. }
  75. this.ctx.arc(
  76. cx, cy, r,
  77. (Math.PI * -1 / 2),
  78. (Math.PI * -1 / 2) + endAngle / 100 * (Math.PI * 2),
  79. false
  80. );
  81. this.ctx.stroke();
  82. }
  83. /**
  84. * 初始化
  85. *
  86. * @param {x} x
  87. * @param {y} y
  88. * @param {半径} r
  89. */
  90. init(x, y, r) {
  91. //清除canvas内容
  92. this.ctx.clearRect(0, 0, x * 2, y * 2);
  93. this.circle(x, y, r);
  94. this.circle(x, y, r * 1.2);
  95. }
  96. /**
  97. * 设置百分比
  98. *
  99. * @param {内环百分比(100最大)} p1
  100. * @param {外环百分比(100最大)} p2
  101. */
  102. setPersent(p1, p2) {
  103. this.init(this.circleX, this.circleY, this.radius);
  104. //圆弧
  105. this.sector(this.circleX, this.circleY, this.radius, p1);
  106. this.sector(this.circleX, this.circleY, this.radius * 1.2, p2, '#FFA34A');
  107. }
  108. // 内外环百分比换算
  109. persentTransform(total, p1, p2) {
  110. const r1 = Math.floor(p1 / total * 100)
  111. const r2 = Math.floor(p2 / total * 100)
  112. this.setPersent(r1, r2)
  113. }
  114. }