查看: 2146|回复: 0

[DIV/CSS] js封装成插件-------Canvas统计图插件编写

发表于 2017-9-24 08:00:05
句号论坛

之前就说过,我想写一个canvas画统计图的插件,现在写好了

先说下实现的功能吧:

  1.可以通过自定义X轴坐标属性和Y轴坐标属性按比例画出统计图

  2.可以选择画折现图还是柱形统计图,或者两者都实现

  3.可以自由定义折现颜色,坐标颜色,柱形图颜色 和canvas边框颜色,当然边框你也可以选择要或者不要

  4.可以选择是否实现柱形图和折现图的动画实现

实现过程

画坐标——画箭头——做X轴和Y轴的标注——画柱形图——画折现图

  1. 1 (function(window,document){
  2. 2 var ChartDraws = function(options){
  3. 3 if(!(this instanceof ChartDraws))return new ChartDraws(options);
  4. 4 this.options = $.extend({
  5. 5 //报表所需的参数
  6. 6 "containerId" : "", //canvas所在容器id
  7. 7 "canvasWidth" : 400,
  8. 8 "canvasHeight" : 300,
  9. 9 "paddingLeft" : 20,
  10. 10 "paddingTop" : 20,
  11. 11 "columnChartData" :[], //柱形图的数量和对应得名称以及百分比
  12. 12 "yChartData" :[], //y轴的数量及名称
  13. 13 "axisColor" : "white", //坐标轴颜色
  14. 14 "columnChartColor" : "#EEE685", //柱形图颜色
  15. 15 "isNeedAnimation" : true, //是否需要动画
  16. 16 "isNeedLineChart" : true, //是否需要折线图
  17. 17 "isNeedColumnChart" : true, //是否需要柱形图
  18. 18 "lineChartColor" : "#90EE90", //折线图颜色,当isNeedLineChart=true时有效
  19. 19 "isNeedBorder" : false, //canvas是否需要外边框
  20. 20 "borderColor" : "white" //外边框颜色
  21. 21 },options);
  22. 22 if(this.options.canvasWidth<=500)
  23. 23 {
  24. 24 this.axisBorderWidth = 3;
  25. 25 this.fontSize = 8;
  26. 26 }
  27. 27 else if(this.options.canvasWidth<=800){
  28. 28 this.axisBorderWidth = 4;
  29. 29 this.fontSize = 12;
  30. 30 }
  31. 31 else{
  32. 32 this.axisBorderWidth = 5;
  33. 33 this.fontSize = 16;
  34. 34 }
  35. 35 var self = this;
  36. 36 _init();
  37. 37 function _init(){
  38. 38 var canvasDom = document.createElement("canvas");
  39. 39 canvasDom.id = self.options.containerId+"_"+"canvas";
  40. 40 canvasDom.width = self.options.canvasWidth;
  41. 41 canvasDom.height = self.options.canvasHeight;
  42. 42 if(self.options.isNeedBorder){
  43. 43 canvasDom.style.borderWidth = 1;
  44. 44 canvasDom.style.borderStyle = "solid";
  45. 45 canvasDom.style.borderColor = self.options.borderColor;
  46. 46 }
  47. 47 document.getElementById(self.options.containerId).appendChild(canvasDom);
  48. 48 self.context = document.getElementById(self.options.containerId+"_"+"canvas");
  49. 49 self.ctx = self.context.getContext("2d");
  50. 50 _drawAxis();
  51. 51 }
  52. 52
  53. 53 function _drawAxis(){
  54. 54 var XYData =transformAxis( [{x:self.options.paddingLeft,y:self.options.canvasHeight-self.options.paddingTop},{x:self.options.paddingLeft,y:self.options.paddingTop},{x:self.options.canvasWidth-self.options.paddingLeft,y:self.options.paddingTop}]);
  55. 55 self.ctx.strokeStyle=self.options.axisColor;
  56. 56 drawLine(self.ctx,XYData,self.axisBorderWidth);
  57. 57 //画三角箭头
  58. 58 //画y轴三角箭头
  59. 59 drawLine(self.ctx,transformAxis([{x:self.options.paddingLeft-self.axisBorderWidth,y:self.options.canvasHeight-self.options.paddingTop-self.axisBorderWidth*2},{x:self.options.paddingLeft,y:self.options.canvasHeight-self.options.paddingTop},{x:self.options.paddingLeft+self.axisBorderWidth,y:self.options.canvasHeight-self.options.paddingTop-self.axisBorderWidth*2}]),self.axisBorderWidth);
  60. 60 //画x轴三角箭头
  61. 61 drawLine(self.ctx,transformAxis([{x:self.options.canvasWidth-self.options.paddingLeft-self.axisBorderWidth*2,y:self.options.paddingTop+self.axisBorderWidth},{x:self.options.canvasWidth-self.options.paddingLeft,y:self.options.paddingTop},{x:self.options.canvasWidth-self.options.paddingLeft-self.axisBorderWidth*2,y:self.options.paddingTop-self.axisBorderWidth}]),self.axisBorderWidth);
  62. 62 _drawCoordinatePoints();
  63. 63 }
  64. 64
  65. 65 function _drawCoordinatePoints(){
  66. 66 self.reactAngleWidth = (1-2*0.04)*(self.options.canvasWidth-(2*self.options.paddingLeft))/(self.options.columnChartData.length*2-1);
  67. 67 self.lineDataList = [];
  68. 68 for(var i = 0;i<self.options.columnChartData.length;i++)
  69. 69 {
  70. 70 drawXText(self.ctx,2*self.options.columnChartData[i].NO*self.reactAngleWidth+self.options.paddingLeft+0.04*(self.options.canvasWidth-(2*self.options.paddingLeft))+self.reactAngleWidth/2,self.options.paddingTop/2,self.options.columnChartData[i].Name);
  71. 71 self.lineDataList.push({
  72. 72 x:2*self.options.columnChartData[i].NO*self.reactAngleWidth+self.options.paddingLeft+0.04*(self.options.canvasWidth-(2*self.options.paddingLeft))+self.reactAngleWidth/2,
  73. 73 y:self.options.canvasHeight-(self.options.paddingTop+(self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[i].PT)
  74. 74 })
  75. 75 }
  76. 76
  77. 77 //画Y轴title 画y轴虚线
  78. 78 self.reactAngleHeight = (self.options.canvasHeight-2*self.options.paddingTop)/(self.options.yChartData.length+1);
  79. 79 for(var j = 0;j<self.options.yChartData.length;j++)
  80. 80 {
  81. 81 drawYText(self.ctx,3*self.options.paddingLeft/4,self.options.paddingTop+self.reactAngleHeight*(j+1),self.options.yChartData[j].Name);
  82. 82 //画虚线
  83. 83 drawDottedLine(self.ctx,self.options.paddingLeft,self.options.paddingTop+self.reactAngleHeight*(j+1),self.options.canvasWidth-self.options.paddingLeft,self.options.paddingTop+self.reactAngleHeight*(j+1),self.options.canvasWidth-2*self.options.paddingLeft,10,self.axisBorderWidth/2);
  84. 84 }
  85. 85 _drawColumnChart();
  86. 86 }
  87. 87
  88. 88 function _drawColumnChart(){
  89. 89 //柱形图循环
  90. 90 var reactAngleTimer = 1;
  91. 91 function loopColumnChart()
  92. 92 {
  93. 93 var columnChartLooped = window.requestAnimationFrame(loopColumnChart);
  94. 94 if(reactAngleTimer<=100)
  95. 95 {
  96. 96 for(var k=0;k<self.options.columnChartData.length;k++)
  97. 97 {
  98. 98 self.ctx.fillStyle =self.options.columnChartColor;
  99. 99 drawRectangle(self.ctx,self.lineDataList[k].x-self.reactAngleWidth/2,self.options.canvasHeight-((self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT*reactAngleTimer/100+self.options.paddingTop),self.reactAngleWidth,(self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT*reactAngleTimer/100);
  100. 100 }
  101. 101 reactAngleTimer++;
  102. 102 }
  103. 103 else
  104. 104 {
  105. 105 window.cancelAnimationFrame(columnChartLooped);
  106. 106 columnChartLooped = null;
  107. 107 reactAngleTimer = 1;
  108. 108 if(self.options.isNeedLineChart)
  109. 109 {
  110. 110 loopLineChart();
  111. 111 }
  112. 112 }
  113. 113 }
  114. 114 //折线图循环
  115. 115 var lineTimer = 0;
  116. 116 function loopLineChart()
  117. 117 {
  118. 118 var lineChartLooped = window.requestAnimationFrame(loopLineChart);
  119. 119 if(lineTimer<self.lineDataList.length-1)
  120. 120 {
  121. 121 self.ctx.lineWidth = 2*self.axisBorderWidth/3;
  122. 122 if(lineTimer == 0)
  123. 123 {
  124. 124 drawCircle(self.ctx,self.lineDataList[lineTimer].x,self.lineDataList[lineTimer].y);
  125. 125 }
  126. 126 drawCircle(self.ctx,self.lineDataList[lineTimer+1].x,self.lineDataList[lineTimer+1].y);
  127. 127 self.ctx.beginPath();
  128. 128 self.ctx.moveTo(self.lineDataList[lineTimer].x,self.lineDataList[lineTimer].y);
  129. 129 self.ctx.lineTo(self.lineDataList[lineTimer+1].x,self.lineDataList[lineTimer+1].y);
  130. 130 self.ctx.strokeStyle = self.options.lineChartColor;
  131. 131 self.ctx.lineWidth = 2*self.axisBorderWidth/3;
  132. 132 self.ctx.stroke();
  133. 133 lineTimer++;
  134. 134 }
  135. 135 else
  136. 136 {
  137. 137 window.cancelAnimationFrame(lineChartLooped);
  138. 138 lineChartLooped = null;
  139. 139 lineTimer = 0;
  140. 140 }
  141. 141 }
  142. 142 //画柱形图
  143. 143 function drawRectangle(context,x,y,width,height){
  144. 144 context.beginPath();
  145. 145 context.fillRect(x,y,width,height);
  146. 146 }
  147. 147 //画圆
  148. 148 function drawCircle(context,x,y){
  149. 149 context.beginPath();
  150. 150 context.arc(x,y,self.axisBorderWidth/2,0,2*Math.PI,true);
  151. 151 context.strokeStyle=self.options.lineChartColor;
  152. 152 context.stroke();
  153. 153 context.closePath();
  154. 154 }
  155. 155 if(self.options.isNeedAnimation)
  156. 156 {
  157. 157 if(self.options.isNeedColumnChart)
  158. 158 {
  159. 159 loopColumnChart();
  160. 160 }
  161. 161 else
  162. 162 {
  163. 163 if(self.options.isNeedLineChart) {
  164. 164 loopLineChart();
  165. 165 }
  166. 166 }
  167. 167 }
  168. 168 else
  169. 169 {
  170. 170 if(self.options.isNeedColumnChart)
  171. 171 {
  172. 172 for(var k=0;k<self.options.columnChartData.length;k++)
  173. 173 {
  174. 174 self.ctx.fillStyle =self.options.columnChartColor;
  175. 175 drawRectangle(self.ctx,self.lineDataList[k].x-self.reactAngleWidth/2,self.options.canvasHeight-((self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT+self.options.paddingTop),self.reactAngleWidth,(self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT);
  176. 176 }
  177. 177 }
  178. 178 if(self.options.isNeedLineChart) {
  179. 179 for (var l = 0; l < self.lineDataList.length - 1; l++) {
  180. 180 self.ctx.lineWidth = 4;
  181. 181 if (l == 0) {
  182. 182 drawCircle(self.ctx, self.lineDataList[l].x, self.lineDataList[l].y);
  183. 183 }
  184. 184 drawCircle(self.ctx, self.lineDataList[l + 1].x, self.lineDataList[l + 1].y);
  185. 185 self.ctx.beginPath();
  186. 186 self.ctx.moveTo(self.lineDataList[l].x, self.lineDataList[l].y);
  187. 187 self.ctx.lineTo(self.lineDataList[l + 1].x, self.lineDataList[l + 1].y);
  188. 188 self.ctx.strokeStyle = self.options.lineChartColor;
  189. 189 self.ctx.lineWidth = 2*self.axisBorderWidth/3;
  190. 190 self.ctx.stroke();
  191. 191 }
  192. 192 }
  193. 193 }
  194. 194 }
  195. 195
  196. 196
  197. 197 function transformAxis(data)
  198. 198 {
  199. 199 var newData=[];
  200. 200 for(var i=0;i<data.length;i++){
  201. 201 newData.push({
  202. 202 x:data[i].x,
  203. 203 y:self.options.canvasHeight-data[i].y
  204. 204 })
  205. 205 }
  206. 206 return newData;
  207. 207 }
  208. 208
  209. 209 function drawLine(context,point,width){
  210. 210 context.beginPath();
  211. 211 context.moveTo(point[0].x,point[0].y);
  212. 212 if(point.length>2)
  213. 213 {
  214. 214 for(var i=1;i<point.length;i++)
  215. 215 {
  216. 216 context.lineTo(point[i].x,point[i].y);
  217. 217 }
  218. 218 }
  219. 219 context.lineWidth = width;
  220. 220 context.lineJoin='round';
  221. 221 context.stroke();
  222. 222 context.closePath();
  223. 223 }
  224. 224
  225. 225 //画y轴title
  226. 226 function drawYText(context,x,y,str) {
  227. 227 context.beginPath();
  228. 228 context.font = '{fontSize} Microsoft Yahei'.replace("{fontSize}",self.fontSize+"px");
  229. 229 context.fillStyle = 'white';
  230. 230 context.textAlign = 'right';
  231. 231 context.fillText(str,x,self.options.canvasHeight-y);
  232. 232 context.closePath();
  233. 233 }
  234. 234 //画x轴title
  235. 235 function drawXText(context,x,y,str) {
  236. 236 context.beginPath();
  237. 237 context.font = '{fontSize} Microsoft Yahei'.replace("{fontSize}",self.fontSize+"px");
  238. 238 context.fillStyle = 'white';
  239. 239 context.textAlign = 'center';
  240. 240 context.fillText(str,x,self.options.canvasHeight-y);
  241. 241 context.closePath();
  242. 242 }
  243. 243 function drawDottedLine(context,x1,y1,x2,y2,totalLength,length,lineWidth){
  244. 244 y1 = self.options.canvasHeight-y1;
  245. 245 y2 = self.options.canvasHeight-y2;
  246. 246 var dashLen = length === undefined ? 5 : length;
  247. 247 //计算有多少个线段
  248. 248 context.beginPath();
  249. 249 var num = Math.floor(totalLength/dashLen);
  250. 250 context.lineWidth = lineWidth;
  251. 251 for(var i = 0 ; i < num; i++)
  252. 252 {
  253. 253 context[i%2==0 ? 'moveTo' : 'lineTo'](x1+(x2-x1)/num*i,y1+(y2-y1)/num*i);
  254. 254 }
  255. 255 context.stroke();
  256. 256 }
  257. 257 };
  258. 258 window.ChartDraws = ChartDraws;
  259. 259 }(window,document)
复制代码

话不多说,上代码

  1. 1 (function(window,document){
  2. 2 var ChartDraws = function(options){
  3. 3 if(!(this instanceof ChartDraws))return new ChartDraws(options);
  4. 4 this.options = $.extend({
  5. 5 //报表所需的参数
  6. 6 "containerId" : "", //canvas所在容器id
  7. 7 "canvasWidth" : 400,
  8. 8 "canvasHeight" : 300,
  9. 9 "paddingLeft" : 20,
  10. 10 "paddingTop" : 20,
  11. 11 "columnChartData" :[], //柱形图的数量和对应得名称以及百分比
  12. 12 "yChartData" :[], //y轴的数量及名称
  13. 13 "axisColor" : "white", //坐标轴颜色
  14. 14 "columnChartColor" : "#EEE685", //柱形图颜色
  15. 15 "isNeedAnimation" : true, //是否需要动画
  16. 16 "isNeedLineChart" : true, //是否需要折线图
  17. 17 "isNeedColumnChart" : true, //是否需要柱形图
  18. 18 "lineChartColor" : "#90EE90", //折线图颜色,当isNeedLineChart=true时有效
  19. 19 "isNeedBorder" : false, //canvas是否需要外边框
  20. 20 "borderColor" : "white" //外边框颜色
  21. 21 },options);
  22. 22 if(this.options.canvasWidth<=500)
  23. 23 {
  24. 24 this.axisBorderWidth = 3;
  25. 25 this.fontSize = 8;
  26. 26 }
  27. 27 else if(this.options.canvasWidth<=800){
  28. 28 this.axisBorderWidth = 4;
  29. 29 this.fontSize = 12;
  30. 30 }
  31. 31 else{
  32. 32 this.axisBorderWidth = 5;
  33. 33 this.fontSize = 16;
  34. 34 }
  35. 35 var self = this;
  36. 36 _init();
  37. 37 function _init(){
  38. 38 var canvasDom = document.createElement("canvas");
  39. 39 canvasDom.id = self.options.containerId+"_"+"canvas";
  40. 40 canvasDom.width = self.options.canvasWidth;
  41. 41 canvasDom.height = self.options.canvasHeight;
  42. 42 if(self.options.isNeedBorder){
  43. 43 canvasDom.style.borderWidth = 1;
  44. 44 canvasDom.style.borderStyle = "solid";
  45. 45 canvasDom.style.borderColor = self.options.borderColor;
  46. 46 }
  47. 47 document.getElementById(self.options.containerId).appendChild(canvasDom);
  48. 48 self.context = document.getElementById(self.options.containerId+"_"+"canvas");
  49. 49 self.ctx = self.context.getContext("2d");
  50. 50 _drawAxis();
  51. 51 }
  52. 52
  53. 53 function _drawAxis(){
  54. 54 var XYData =transformAxis( [{x:self.options.paddingLeft,y:self.options.canvasHeight-self.options.paddingTop},<br>                          {x:self.options.paddingLeft,y:self.options.paddingTop},{x:self.options.canvasWidth-self.options.paddingLeft,y:self.options.paddingTop}]);
  55. 55 self.ctx.strokeStyle=self.options.axisColor;
  56. 56 drawLine(self.ctx,XYData,self.axisBorderWidth);
  57. 57 //画三角箭头
  58. 58 //画y轴三角箭头
  59. 59 drawLine(self.ctx,transformAxis([{x:self.options.paddingLeft-self.axisBorderWidth,y:self.options.canvasHeight-self.options.paddingTop-self.axisBorderWidth*2},<br>                                            {x:self.options.paddingLeft,y:self.options.canvasHeight-self.options.paddingTop},<br>                                            {x:self.options.paddingLeft+self.axisBorderWidth,y:self.options.canvasHeight-self.options.paddingTop-self.axisBorderWidth*2}]),<br>                                            self.axisBorderWidth);
  60. 60 //画x轴三角箭头
  61. 61 drawLine(self.ctx,transformAxis([{x:self.options.canvasWidth-self.options.paddingLeft-self.axisBorderWidth*2,y:self.options.paddingTop+self.axisBorderWidth},<br>                            {x:self.options.canvasWidth-self.options.paddingLeft,y:self.options.paddingTop},<br>                            {x:self.options.canvasWidth-self.options.paddingLeft-self.axisBorderWidth*2,y:self.options.paddingTop-self.axisBorderWidth}]),<br>                            self.axisBorderWidth);
  62. 62 _drawCoordinatePoints();
  63. 63 }
  64. 64
  65. 65 function _drawCoordinatePoints(){
  66. 66 self.reactAngleWidth = (1-2*0.04)*(self.options.canvasWidth-(2*self.options.paddingLeft))/(self.options.columnChartData.length*2-1);
  67. 67 self.lineDataList = [];
  68. 68 for(var i = 0;i<self.options.columnChartData.length;i++)
  69. 69 {
  70. 70 drawXText(self.ctx,2*self.options.columnChartData[i].NO*self.reactAngleWidth+self.options.paddingLeft+0.04*(self.options.canvasWidth-(2*self.options.paddingLeft))<br>                                                +self.reactAngleWidth/2,self.options.paddingTop/2,self.options.columnChartData[i].Name);
  71. 71 self.lineDataList.push({
  72. 72 x:2*self.options.columnChartData[i].NO*self.reactAngleWidth+self.options.paddingLeft+0.04*(self.options.canvasWidth-(2*self.options.paddingLeft))+self.reactAngleWidth/2,
  73. 73 y:self.options.canvasHeight-(self.options.paddingTop+(self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[i].PT)
  74. 74 })
  75. 75 }
  76. 76
  77. 77 //画Y轴title 画y轴虚线
  78. 78 self.reactAngleHeight = (self.options.canvasHeight-2*self.options.paddingTop)/(self.options.yChartData.length+1);
  79. 79 for(var j = 0;j<self.options.yChartData.length;j++)
  80. 80 {
  81. 81 drawYText(self.ctx,3*self.options.paddingLeft/4,self.options.paddingTop+self.reactAngleHeight*(j+1),self.options.yChartData[j].Name);
  82. 82 //画虚线
  83. 83 drawDottedLine(self.ctx,self.options.paddingLeft,self.options.paddingTop+self.reactAngleHeight*(j+1),self.options.canvasWidth-self.options.paddingLeft,self.options.paddingTop<br>                                                    +self.reactAngleHeight*(j+1),self.options.canvasWidth-2*self.options.paddingLeft,10,self.axisBorderWidth/2);
  84. 84 }
  85. 85 _drawColumnChart();
  86. 86 }
  87. 87
  88. 88 function _drawColumnChart(){
  89. 89 //柱形图循环
  90. 90 var reactAngleTimer = 1;
  91. 91 function loopColumnChart()
  92. 92 {
  93. 93 var columnChartLooped = window.requestAnimationFrame(loopColumnChart);
  94. 94 if(reactAngleTimer<=100)
  95. 95 {
  96. 96 for(var k=0;k<self.options.columnChartData.length;k++)
  97. 97 {
  98. 98 self.ctx.fillStyle =self.options.columnChartColor;
  99. 99 drawRectangle(self.ctx,self.lineDataList[k].x-self.reactAngleWidth/2,self.options.canvasHeight-((self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT*reactAngleTimer/100<br>                                      +self.options.paddingTop),self.reactAngleWidth,(self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT*reactAngleTimer/100);
  100. 100 }
  101. 101 reactAngleTimer++;
  102. 102 }
  103. 103 else
  104. 104 {
  105. 105 window.cancelAnimationFrame(columnChartLooped);
  106. 106 columnChartLooped = null;
  107. 107 reactAngleTimer = 1;
  108. 108 if(self.options.isNeedLineChart)
  109. 109 {
  110. 110 loopLineChart();
  111. 111 }
  112. 112 }
  113. 113 }
  114. 114 //折线图循环
  115. 115 var lineTimer = 0;
  116. 116 function loopLineChart()
  117. 117 {
  118. 118 var lineChartLooped = window.requestAnimationFrame(loopLineChart);
  119. 119 if(lineTimer<self.lineDataList.length-1)
  120. 120 {
  121. 121 self.ctx.lineWidth = 2*self.axisBorderWidth/3;
  122. 122 if(lineTimer == 0)
  123. 123 {
  124. 124 drawCircle(self.ctx,self.lineDataList[lineTimer].x,self.lineDataList[lineTimer].y);
  125. 125 }
  126. 126 drawCircle(self.ctx,self.lineDataList[lineTimer+1].x,self.lineDataList[lineTimer+1].y);
  127. 127 self.ctx.beginPath();
  128. 128 self.ctx.moveTo(self.lineDataList[lineTimer].x,self.lineDataList[lineTimer].y);
  129. 129 self.ctx.lineTo(self.lineDataList[lineTimer+1].x,self.lineDataList[lineTimer+1].y);
  130. 130 self.ctx.strokeStyle = self.options.lineChartColor;
  131. 131 self.ctx.lineWidth = 2*self.axisBorderWidth/3;
  132. 132 self.ctx.stroke();
  133. 133 lineTimer++;
  134. 134 }
  135. 135 else
  136. 136 {
  137. 137 window.cancelAnimationFrame(lineChartLooped);
  138. 138 lineChartLooped = null;
  139. 139 lineTimer = 0;
  140. 140 }
  141. 141 }
  142. 142 //画柱形图
  143. 143 function drawRectangle(context,x,y,width,height){
  144. 144 context.beginPath();
  145. 145 context.fillRect(x,y,width,height);
  146. 146 }
  147. 147 //画圆
  148. 148 function drawCircle(context,x,y){
  149. 149 context.beginPath();
  150. 150 context.arc(x,y,self.axisBorderWidth/2,0,2*Math.PI,true);
  151. 151 context.strokeStyle=self.options.lineChartColor;
  152. 152 context.stroke();
  153. 153 context.closePath();
  154. 154 }
  155. 155 if(self.options.isNeedAnimation)
  156. 156 {
  157. 157 if(self.options.isNeedColumnChart)
  158. 158 {
  159. 159 loopColumnChart();
  160. 160 }
  161. 161 else
  162. 162 {
  163. 163 if(self.options.isNeedLineChart) {
  164. 164 loopLineChart();
  165. 165 }
  166. 166 }
  167. 167 }
  168. 168 else
  169. 169 {
  170. 170 if(self.options.isNeedColumnChart)
  171. 171 {
  172. 172 for(var k=0;k<self.options.columnChartData.length;k++)
  173. 173 {
  174. 174 self.ctx.fillStyle =self.options.columnChartColor;
  175. 175 drawRectangle(self.ctx,self.lineDataList[k].x-self.reactAngleWidth/2,self.options.canvasHeight-((self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT<br>                                          +self.options.paddingTop),self.reactAngleWidth,(self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT);
  176. 176 }
  177. 177 }
  178. 178 if(self.options.isNeedLineChart) {
  179. 179 for (var l = 0; l < self.lineDataList.length - 1; l++) {
  180. 180 self.ctx.lineWidth = 4;
  181. 181 if (l == 0) {
  182. 182 drawCircle(self.ctx, self.lineDataList[l].x, self.lineDataList[l].y);
  183. 183 }
  184. 184 drawCircle(self.ctx, self.lineDataList[l + 1].x, self.lineDataList[l + 1].y);
  185. 185 self.ctx.beginPath();
  186. 186 self.ctx.moveTo(self.lineDataList[l].x, self.lineDataList[l].y);
  187. 187 self.ctx.lineTo(self.lineDataList[l + 1].x, self.lineDataList[l + 1].y);
  188. 188 self.ctx.strokeStyle = self.options.lineChartColor;
  189. 189 self.ctx.lineWidth = 2*self.axisBorderWidth/3;
  190. 190 self.ctx.stroke();
  191. 191 }
  192. 192 }
  193. 193 }
  194. 194 }
  195. 195
  196. 196
  197. 197 function transformAxis(data)
  198. 198 {
  199. 199 var newData=[];
  200. 200 for(var i=0;i<data.length;i++){
  201. 201 newData.push({
  202. 202 x:data[i].x,
  203. 203 y:self.options.canvasHeight-data[i].y
  204. 204 })
  205. 205 }
  206. 206 return newData;
  207. 207 }
  208. 208
  209. 209 function drawLine(context,point,width){
  210. 210 context.beginPath();
  211. 211 context.moveTo(point[0].x,point[0].y);
  212. 212 if(point.length>2)
  213. 213 {
  214. 214 for(var i=1;i<point.length;i++)
  215. 215 {
  216. 216 context.lineTo(point[i].x,point[i].y);
  217. 217 }
  218. 218 }
  219. 219 context.lineWidth = width;
  220. 220 context.lineJoin='round';
  221. 221 context.stroke();
  222. 222 context.closePath();
  223. 223 }
  224. 224
  225. 225 //画y轴title
  226. 226 function drawYText(context,x,y,str) {
  227. 227 context.beginPath();
  228. 228 context.font = '{fontSize} Microsoft Yahei'.replace("{fontSize}",self.fontSize+"px");
  229. 229 context.fillStyle = 'white';
  230. 230 context.textAlign = 'right';
  231. 231 context.fillText(str,x,self.options.canvasHeight-y);
  232. 232 context.closePath();
  233. 233 }
  234. 234 //画x轴title
  235. 235 function drawXText(context,x,y,str) {
  236. 236 context.beginPath();
  237. 237 context.font = '{fontSize} Microsoft Yahei'.replace("{fontSize}",self.fontSize+"px");
  238. 238 context.fillStyle = 'white';
  239. 239 context.textAlign = 'center';
  240. 240 context.fillText(str,x,self.options.canvasHeight-y);
  241. 241 context.closePath();
  242. 242 }
  243. 243 function drawDottedLine(context,x1,y1,x2,y2,totalLength,length,lineWidth){
  244. 244 y1 = self.options.canvasHeight-y1;
  245. 245 y2 = self.options.canvasHeight-y2;
  246. 246 var dashLen = length === undefined ? 5 : length;
  247. 247 //计算有多少个线段
  248. 248 context.beginPath();
  249. 249 var num = Math.floor(totalLength/dashLen);
  250. 250 context.lineWidth = lineWidth;
  251. 251 for(var i = 0 ; i < num; i++)
  252. 252 {
  253. 253 context[i%2==0 ? 'moveTo' : 'lineTo'](x1+(x2-x1)/num*i,y1+(y2-y1)/num*i);
  254. 254 }
  255. 255 context.stroke();
  256. 256 }
  257. 257 };
  258. 258 window.ChartDraws = ChartDraws;
  259. 259 }(window,document));
复制代码

下面还有一个是实现requestAnimationFrame浏览器兼容的

  1. 1 (function(){
  2. 2 var lastTime = 0;
  3. 3 var prefixes = ['ms','webkit','o','moz']; //各浏览器前缀
  4. 4
  5. 5 var requestAnimationFrame = window.requestAnimationFrame;
  6. 6 var cancelAnimationFrame = window.cancelAnimationFrame;
  7. 7
  8. 8 var prefix;
  9. 9 //通过遍历各浏览器前缀,来得到requestAnimationFrame和cancelAnimationFrame在当前浏览器的实现形式
  10. 10 for( var i = 0; i < prefixes.length; i++ ) {
  11. 11 if ( requestAnimationFrame && cancelAnimationFrame ) {
  12. 12 break;
  13. 13 }
  14. 14 prefix = prefixes[i];
  15. 15 requestAnimationFrame = requestAnimationFrame || window[ prefix + 'RequestAnimationFrame' ];
  16. 16 cancelAnimationFrame = cancelAnimationFrame || window[ prefix + 'CancelAnimationFrame' ] || window[ prefix + 'CancelRequestAnimationFrame' ];
  17. 17 }
  18. 18
  19. 19 //如果当前浏览器不支持requestAnimationFrame和cancelAnimationFrame,则会退到setTimeout
  20. 20 if ( !requestAnimationFrame || !cancelAnimationFrame ) {
  21. 21 requestAnimationFrame = function( callback, element ) {
  22. 22 var currTime = new Date().getTime();
  23. 23 //为了使setTimteout的尽可能的接近每秒60帧的效果
  24. 24 var timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
  25. 25 var id = window.setTimeout( function() {
  26. 26 callback( currTime + timeToCall );
  27. 27 }, timeToCall );
  28. 28 lastTime = currTime + timeToCall;
  29. 29 return id;
  30. 30 };
  31. 31 cancelAnimationFrame = function( id ) {
  32. 32 window.clearTimeout( id );
  33. 33 };
  34. 34 }
  35. 35
  36. 36 window.requestAnimationFrame = requestAnimationFrame;
  37. 37 window.cancelAnimationFrame = cancelAnimationFrame;
  38. 38 }());
复制代码

附上

关闭

站长推荐上一条 /1 下一条