radar.js 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. let width = 750; // canvas的宽
  2. let height = 750; // canvas的高
  3. let angleNum = 0; // 角数,即多少个数据项 【3,10】
  4. let angleAvg = 0; // 分角度平均值
  5. let angleOffset = 13; // 角度偏移量
  6. let layerNum = 10; // 层数,即环层数量
  7. let layerWidth = 0; // 层宽
  8. let bgLineColor = '#aaa'; // 背景线条颜色
  9. let bgLineWidth = 0; // 背景线条宽度
  10. let centerPoint = [0, 0]; // 中心点坐标
  11. let layerPoints = []; // 各层上的点
  12. let wordColor = '#aaa'; // 字体颜色
  13. let fontSize = 0; // 字体大小
  14. // let wordArr = ['定向搜索能力', '专项技能', '学习记忆能力', '抗挫力', '销售技能', '领导力', '人际沟通','111','2222','3333']; // 字体数组
  15. let wordArr = [];
  16. let wordOffset = [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]];
  17. let circleWidth = 0; // 圆点宽度
  18. // 绘制的雷达比例数据
  19. // let dataArr = [10, 8, 9, 10, 10, 10, 4, 7, 10, 4, 7, 10, 4, 7, 10, 4, 7];
  20. let dataArr = [];
  21. let context =null;
  22. let windowWidth = 0;
  23. let radar = {
  24. init: function(data) {
  25. centerPoint = [rpx(375), rpx(320)];
  26. layerWidth = rpx(24);
  27. bgLineWidth = rpx(1.6);
  28. fontSize = rpx(26);
  29. circleWidth = rpx(8);
  30. if(angleNum == 9){
  31. wordOffset = [
  32. [rpx(30), rpx(40)],
  33. [rpx(40), rpx(40)],
  34. [rpx(110), rpx(40)],
  35. [rpx(100), rpx(0)],
  36. [rpx(60), rpx(15)],
  37. [rpx(15), rpx(-5)],
  38. [rpx(10), rpx(15)],
  39. [rpx(-10), rpx(15)],
  40. [rpx(15), rpx(-5)],
  41. [rpx(10), rpx(15)],
  42. [rpx(-10), rpx(15)]
  43. ];
  44. }else if(angleNum == 10){
  45. wordOffset = [
  46. [rpx(30), rpx(40)],
  47. [rpx(40), rpx(40)],
  48. [rpx(110), rpx(40)],
  49. [rpx(100), rpx(0)],
  50. [rpx(100), rpx(15)],
  51. [rpx(95), rpx(-5)],
  52. [rpx(40), rpx(15)],
  53. [rpx(-10), rpx(15)],
  54. [rpx(15), rpx(-5)],
  55. [rpx(10), rpx(15)],
  56. [rpx(-10), rpx(15)]
  57. ];
  58. }else if(angleNum == 11){
  59. wordOffset = [
  60. [rpx(30), rpx(40)],
  61. [rpx(40), rpx(40)],
  62. [rpx(110), rpx(40)],
  63. [rpx(90), rpx(0)],
  64. [rpx(125), rpx(15)],
  65. [rpx(75), rpx(-5)],
  66. [rpx(30), rpx(15)],
  67. [rpx(-10), rpx(15)],
  68. [rpx(15), rpx(-5)],
  69. [rpx(10), rpx(15)],
  70. [rpx(-10), rpx(15)]
  71. ];
  72. }else{
  73. wordOffset = [
  74. [rpx(30), rpx(40)],
  75. [rpx(40), rpx(40)],
  76. [rpx(110), rpx(40)],
  77. [rpx(90), rpx(0)],
  78. [rpx(-25), rpx(15)],
  79. [rpx(15), rpx(-5)],
  80. [rpx(10), rpx(15)],
  81. [rpx(-10), rpx(15)],
  82. [rpx(15), rpx(-5)],
  83. [rpx(10), rpx(15)],
  84. [rpx(-10), rpx(15)]
  85. ];
  86. }
  87. },
  88. draw: function(data,canvasId,grades) {
  89. var obj_grades = {};
  90. if(grades){
  91. obj_grades = JSON.parse(grades);
  92. wordArr = Object.keys(obj_grades);
  93. angleNum = wordArr.length;
  94. angleAvg = 360 / angleNum;
  95. dataArr = data;
  96. }
  97. let n = 0, m = 0, k = 0;
  98. this.init(data);
  99. //画背景线条
  100. context = wx.createContext();
  101. context.setLineWidth(bgLineWidth);
  102. context.setStrokeStyle(bgLineColor);
  103. context.beginPath();
  104. context.setFontSize(fontSize);
  105. context.setFillStyle(wordColor);
  106. for(n = 0; n < layerNum; n++) {
  107. layerPoints[n] = [];
  108. for(k = 0; k < angleNum; k++) {
  109. context.moveTo(centerPoint[0], centerPoint[1]);
  110. let offsetX = layerWidth * (n + 1) * getXParam(angleAvg * (k + 1) + angleOffset);
  111. let offsetY = layerWidth * (n + 1) * getYParam(angleAvg * (k + 1) + angleOffset);
  112. let distX = centerPoint[0] + offsetX;
  113. let distY = centerPoint[1] + offsetY;
  114. if(n == layerNum - 1) {
  115. context.lineTo(distX, distY);
  116. if(wordArr[k]) {
  117. // console.log(k,offsetX)
  118. let wordOffsetX = offsetX >= 0 ? 1 : -1;
  119. wordOffsetX = distX + wordOffsetX * wordOffset[k][0];
  120. // console.log('wordOffsetX',wordOffsetX)
  121. let wordOffsetY = offsetY >= 0 ? 1 : -1;
  122. wordOffsetY = distY + wordOffsetY * wordOffset[k][1];
  123. context.fillText(wordArr[k], wordOffsetX, wordOffsetY);
  124. }
  125. }
  126. layerPoints[n][k] = [distX, distY];
  127. }
  128. }
  129. for(m = 0; m < layerPoints.length; m++) {
  130. for(n = 0; n < layerPoints[m].length; n++) {
  131. context.moveTo(layerPoints[m][n][0], layerPoints[m][n][1]);
  132. if(n < layerPoints[m].length - 1) {
  133. context.lineTo(layerPoints[m][n + 1][0], layerPoints[m][n + 1][1]);
  134. } else {
  135. context.moveTo(layerPoints[m][n][0], layerPoints[m][n][1]);
  136. context.lineTo(layerPoints[m][0][0], layerPoints[m][0][1]);
  137. }
  138. }
  139. }
  140. context.stroke();
  141. // 绘制比例:
  142. context.beginPath();
  143. context.setStrokeStyle("rgba(238,58,67,0.7)");
  144. context.setFillStyle("rgba(238,58,67,0.7)");
  145. let isFirstPoint = true;
  146. let tmpPoints = [];
  147. for(m = 0; m < angleNum; m++) {
  148. tmpPoints = centerPoint;
  149. if(dataArr[m] > 0) {
  150. for(n = 0; n < layerNum; n++) {
  151. if(dataArr[m] == (n + 1)) {
  152. tmpPoints = layerPoints[n][m];
  153. break;
  154. }
  155. }
  156. }
  157. if(isFirstPoint) {
  158. context.moveTo(tmpPoints[0], tmpPoints[1]);
  159. isFirstPoint = false;
  160. } else {
  161. context.lineTo(tmpPoints[0], tmpPoints[1]);
  162. }
  163. }
  164. context.fill();
  165. context.stroke();
  166. context.closePath();
  167. // 绘制圆点:
  168. for(m = 0; m < angleNum; m++) {
  169. tmpPoints = centerPoint;
  170. if(dataArr[m] > 0) {
  171. for(n = 0; n < layerNum; n++) {
  172. if(dataArr[m] == (n + 1)) {
  173. tmpPoints = layerPoints[n][m];
  174. break;
  175. }
  176. }
  177. }
  178. context.beginPath();
  179. context.setStrokeStyle("rgba(238,58,67,0.9)");
  180. context.setFillStyle("rgba(238,58,67,0.9)");
  181. context.closePath();
  182. context.arc(tmpPoints[0], tmpPoints[1], circleWidth, 0, 2 * Math.PI, false);
  183. context.closePath();
  184. context.fill();
  185. context.stroke();
  186. }
  187. wx.drawCanvas({
  188. canvasId: canvasId,
  189. actions: context.getActions()
  190. });
  191. },
  192. };
  193. let rpx = (param) => {
  194. if(windowWidth == 0) {
  195. wx.getSystemInfo({
  196. success: function (res) {
  197. windowWidth = res.windowWidth - 60 / (750 / res.screenWidth);
  198. }
  199. });
  200. }
  201. return Number((windowWidth / 750 * param).toFixed(2));
  202. };
  203. let getXParam = (angle) => {
  204. let param = 1;
  205. if(angle >= 0 && angle < 90) {
  206. param = 1;
  207. } else if(angle >= 90 && angle < 180) {
  208. param = -1;
  209. angle = 180 - angle;
  210. } else if(angle >= 180 && angle < 270) {
  211. param = -1;
  212. angle = angle - 180;
  213. } else if(angle >= 270 && angle <= 360) {
  214. param = 1;
  215. angle = 360 - angle;
  216. }
  217. let angleCos = Math.cos(Math.PI / 180 * angle);
  218. if(angleCos < 0) {
  219. angleCos = angleCos * -1;
  220. }
  221. return angleCos * param;
  222. };
  223. let getYParam = (angle) => {
  224. let param = 1;
  225. if(angle >= 0 && angle < 90) {
  226. param = 1;
  227. } else if(angle >= 90 && angle < 180) {
  228. param = 1;
  229. angle = 180 - angle;
  230. } else if(angle >= 180 && angle < 270) {
  231. param = -1;
  232. angle = angle - 180;
  233. } else if(angle >= 270 && angle <= 360) {
  234. param = -1;
  235. angle = 360 - angle;
  236. }
  237. let angleSin = Math.sin(Math.PI / 180 * angle);
  238. if(angleSin < 0) {
  239. angleSin = angleSin * -1;
  240. }
  241. return angleSin * param;
  242. };
  243. module.exports = {
  244. radar
  245. };