Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

705 строки
22 KiB

  1. /**
  2. * jqPlot
  3. * Pure JavaScript plotting plugin using jQuery
  4. *
  5. * Version: 1.0.0b2_r792
  6. *
  7. * Copyright (c) 2009-2011 Chris Leonello
  8. * jqPlot is currently available for use in all personal or commercial projects
  9. * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
  10. * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
  11. * choose the license that best suits your project and use it accordingly.
  12. *
  13. * Although not required, the author would appreciate an email letting him
  14. * know of any substantial use of jqPlot. You can reach the author at:
  15. * chris at jqplot dot com or see http://www.jqplot.com/info.php .
  16. *
  17. * If you are feeling kind and generous, consider supporting the project by
  18. * making a donation at: http://www.jqplot.com/donate.php .
  19. *
  20. * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
  21. *
  22. * version 2007.04.27
  23. * author Ash Searle
  24. * http://hexmen.com/blog/2007/03/printf-sprintf/
  25. * http://hexmen.com/js/sprintf.js
  26. * The author (Ash Searle) has placed this code in the public domain:
  27. * "This code is unrestricted: you are free to use it however you like."
  28. *
  29. */
  30. (function($) {
  31. // class: $.jqplot.CanvasOverlay
  32. $.jqplot.CanvasOverlay = function(opts){
  33. var options = opts || {};
  34. this.options = {
  35. show: $.jqplot.config.enablePlugins,
  36. deferDraw: false
  37. };
  38. // prop: objects
  39. this.objects = [];
  40. this.objectNames = [];
  41. this.canvas = null;
  42. this.markerRenderer = new $.jqplot.MarkerRenderer({style:'line'});
  43. this.markerRenderer.init();
  44. if (options.objects) {
  45. var objs = options.objects,
  46. obj;
  47. for (var i=0; i<objs.length; i++) {
  48. obj = objs[i];
  49. for (var n in obj) {
  50. switch (n) {
  51. case 'line':
  52. this.addLine(obj[n]);
  53. break;
  54. case 'horizontalLine':
  55. this.addHorizontalLine(obj[n]);
  56. break;
  57. case 'dashedHorizontalLine':
  58. this.addDashedHorizontalLine(obj[n]);
  59. break;
  60. case 'verticalLine':
  61. this.addVerticalLine(obj[n]);
  62. break;
  63. case 'dashedVerticalLine':
  64. this.addDashedVerticalLine(obj[n]);
  65. break;
  66. default:
  67. break;
  68. }
  69. }
  70. }
  71. }
  72. $.extend(true, this.options, options);
  73. };
  74. // called with scope of a plot object
  75. $.jqplot.CanvasOverlay.postPlotInit = function (target, data, opts) {
  76. var options = opts || {};
  77. // add a canvasOverlay attribute to the plot
  78. this.plugins.canvasOverlay = new $.jqplot.CanvasOverlay(options.canvasOverlay);
  79. };
  80. /**
  81. * Class: Line
  82. * A straight line.
  83. */
  84. function Line(options) {
  85. this.type = 'line';
  86. this.options = {
  87. // prop: name
  88. // Optional name for this overlay object.
  89. // Can be later used to retrieve the object by name.
  90. name: null,
  91. // prop: show
  92. // true to show (draw), false to not draw.
  93. show: true,
  94. // prop: lineWidth
  95. // Width of the line.
  96. lineWidth: 2,
  97. // prop: lineCap
  98. // Type of ending placed on the line ['round', 'butt', 'square']
  99. lineCap: 'round',
  100. // prop: color
  101. // color of the line
  102. color: '#666666',
  103. // prop: shadow
  104. // wether or not to draw a shadow on the line
  105. shadow: true,
  106. // prop: shadowAngle
  107. // Shadow angle in degrees
  108. shadowAngle: 45,
  109. // prop: shadowOffset
  110. // Shadow offset from line in pixels
  111. shadowOffset: 1,
  112. // prop: shadowDepth
  113. // Number of times shadow is stroked, each stroke offset shadowOffset from the last.
  114. shadowDepth: 3,
  115. // prop: shadowAlpha
  116. // Alpha channel transparency of shadow. 0 = transparent.
  117. shadowAlpha: '0.07',
  118. // prop: xaxis
  119. // X axis to use for positioning/scaling the line.
  120. xaxis: 'xaxis',
  121. // prop: yaxis
  122. // Y axis to use for positioning/scaling the line.
  123. yaxis: 'yaxis',
  124. // prop: start
  125. // [x, y] coordinates for the start of the line.
  126. start: [],
  127. // prop: stop
  128. // [x, y] coordinates for the end of the line.
  129. stop: []
  130. };
  131. $.extend(true, this.options, options);
  132. }
  133. /**
  134. * Class: HorizontalLine
  135. * A straight horizontal line.
  136. */
  137. function HorizontalLine(options) {
  138. this.type = 'horizontalLine';
  139. this.options = {
  140. // prop: name
  141. // Optional name for this overlay object.
  142. // Can be later used to retrieve the object by name.
  143. name: null,
  144. // prop: show
  145. // true to show (draw), false to not draw.
  146. show: true,
  147. // prop: lineWidth
  148. // Width of the line.
  149. lineWidth: 2,
  150. // prop: lineCap
  151. // Type of ending placed on the line ['round', 'butt', 'square']
  152. lineCap: 'round',
  153. // prop: color
  154. // color of the line
  155. color: '#666666',
  156. // prop: shadow
  157. // wether or not to draw a shadow on the line
  158. shadow: true,
  159. // prop: shadowAngle
  160. // Shadow angle in degrees
  161. shadowAngle: 45,
  162. // prop: shadowOffset
  163. // Shadow offset from line in pixels
  164. shadowOffset: 1,
  165. // prop: shadowDepth
  166. // Number of times shadow is stroked, each stroke offset shadowOffset from the last.
  167. shadowDepth: 3,
  168. // prop: shadowAlpha
  169. // Alpha channel transparency of shadow. 0 = transparent.
  170. shadowAlpha: '0.07',
  171. // prop: xaxis
  172. // X axis to use for positioning/scaling the line.
  173. xaxis: 'xaxis',
  174. // prop: yaxis
  175. // Y axis to use for positioning/scaling the line.
  176. yaxis: 'yaxis',
  177. // prop: y
  178. // y value to position the line
  179. y: null,
  180. // prop: xmin
  181. // x value for the start of the line, null to scale to axis min.
  182. xmin: null,
  183. // prop: xmax
  184. // x value for the end of the line, null to scale to axis max.
  185. xmax: null,
  186. // prop xOffset
  187. // offset ends of the line inside the grid. Number
  188. xOffset: '6px', // number or string. Number interpreted as units, string as pixels.
  189. xminOffset: null,
  190. xmaxOffset: null
  191. };
  192. $.extend(true, this.options, options);
  193. }
  194. /**
  195. * Class: DashedHorizontalLine
  196. * A straight dashed horizontal line.
  197. */
  198. function DashedHorizontalLine(options) {
  199. this.type = 'dashedHorizontalLine';
  200. this.options = {
  201. // prop: name
  202. // Optional name for this overlay object.
  203. // Can be later used to retrieve the object by name.
  204. name: null,
  205. // prop: show
  206. // true to show (draw), false to not draw.
  207. show: true,
  208. // prop: lineWidth
  209. // Width of the line.
  210. lineWidth: 2,
  211. // prop: lineCap
  212. // Type of ending placed on the line ['round', 'butt', 'square']
  213. lineCap: 'butt',
  214. // prop: color
  215. // color of the line
  216. color: '#666666',
  217. // prop: shadow
  218. // wether or not to draw a shadow on the line
  219. shadow: true,
  220. // prop: shadowAngle
  221. // Shadow angle in degrees
  222. shadowAngle: 45,
  223. // prop: shadowOffset
  224. // Shadow offset from line in pixels
  225. shadowOffset: 1,
  226. // prop: shadowDepth
  227. // Number of times shadow is stroked, each stroke offset shadowOffset from the last.
  228. shadowDepth: 3,
  229. // prop: shadowAlpha
  230. // Alpha channel transparency of shadow. 0 = transparent.
  231. shadowAlpha: '0.07',
  232. // prop: xaxis
  233. // X axis to use for positioning/scaling the line.
  234. xaxis: 'xaxis',
  235. // prop: yaxis
  236. // Y axis to use for positioning/scaling the line.
  237. yaxis: 'yaxis',
  238. y: null,
  239. xmin: null,
  240. xmax: null,
  241. xOffset: '6px', // number or string. Number interpreted as units, string as pixels.
  242. xminOffset: null,
  243. xmaxOffset: null,
  244. // prop: dashPattern
  245. // Array of line, space settings in pixels.
  246. // Default is 8 pixel of line, 8 pixel of space.
  247. // Note, limit to a 2 element array b/c of bug with higher order arrays.
  248. dashPattern: [8,8]
  249. };
  250. $.extend(true, this.options, options);
  251. }
  252. /**
  253. * Class: VerticalLine
  254. * A straight vertical line.
  255. */
  256. function VerticalLine(options) {
  257. this.type = 'verticalLine';
  258. this.options = {
  259. // prop: name
  260. // Optional name for this overlay object.
  261. // Can be later used to retrieve the object by name.
  262. name: null,
  263. // prop: show
  264. // true to show (draw), false to not draw.
  265. show: true,
  266. // prop: lineWidth
  267. // Width of the line.
  268. lineWidth: 2,
  269. // prop: lineCap
  270. // Type of ending placed on the line ['round', 'butt', 'square']
  271. lineCap: 'round',
  272. // prop: color
  273. // color of the line
  274. color: '#666666',
  275. // prop: shadow
  276. // wether or not to draw a shadow on the line
  277. shadow: true,
  278. // prop: shadowAngle
  279. // Shadow angle in degrees
  280. shadowAngle: 45,
  281. // prop: shadowOffset
  282. // Shadow offset from line in pixels
  283. shadowOffset: 1,
  284. // prop: shadowDepth
  285. // Number of times shadow is stroked, each stroke offset shadowOffset from the last.
  286. shadowDepth: 3,
  287. // prop: shadowAlpha
  288. // Alpha channel transparency of shadow. 0 = transparent.
  289. shadowAlpha: '0.07',
  290. // prop: xaxis
  291. // X axis to use for positioning/scaling the line.
  292. xaxis: 'xaxis',
  293. // prop: yaxis
  294. // Y axis to use for positioning/scaling the line.
  295. yaxis: 'yaxis',
  296. x: null,
  297. ymin: null,
  298. ymax: null,
  299. yOffset: '6px', // number or string. Number interpreted as units, string as pixels.
  300. yminOffset: null,
  301. ymaxOffset: null
  302. };
  303. $.extend(true, this.options, options);
  304. }
  305. /**
  306. * Class: DashedVerticalLine
  307. * A straight dashed vertical line.
  308. */
  309. function DashedVerticalLine(options) {
  310. this.type = 'dashedVerticalLine';
  311. this.options = {
  312. // prop: name
  313. // Optional name for this overlay object.
  314. // Can be later used to retrieve the object by name.
  315. name: null,
  316. // prop: show
  317. // true to show (draw), false to not draw.
  318. show: true,
  319. // prop: lineWidth
  320. // Width of the line.
  321. lineWidth: 2,
  322. // prop: lineCap
  323. // Type of ending placed on the line ['round', 'butt', 'square']
  324. lineCap: 'butt',
  325. // prop: color
  326. // color of the line
  327. color: '#666666',
  328. // prop: shadow
  329. // wether or not to draw a shadow on the line
  330. shadow: true,
  331. // prop: shadowAngle
  332. // Shadow angle in degrees
  333. shadowAngle: 45,
  334. // prop: shadowOffset
  335. // Shadow offset from line in pixels
  336. shadowOffset: 1,
  337. // prop: shadowDepth
  338. // Number of times shadow is stroked, each stroke offset shadowOffset from the last.
  339. shadowDepth: 3,
  340. // prop: shadowAlpha
  341. // Alpha channel transparency of shadow. 0 = transparent.
  342. shadowAlpha: '0.07',
  343. // prop: xaxis
  344. // X axis to use for positioning/scaling the line.
  345. xaxis: 'xaxis',
  346. // prop: yaxis
  347. // Y axis to use for positioning/scaling the line.
  348. yaxis: 'yaxis',
  349. x: null,
  350. ymin: null,
  351. ymax: null,
  352. yOffset: '6px', // number or string. Number interpreted as units, string as pixels.
  353. yminOffset: null,
  354. ymaxOffset: null,
  355. // prop: dashPattern
  356. // Array of line, space settings in pixels.
  357. // Default is 8 pixel of line, 8 pixel of space.
  358. // Note, limit to a 2 element array b/c of bug with higher order arrays.
  359. dashPattern: [8,8]
  360. };
  361. $.extend(true, this.options, options);
  362. }
  363. $.jqplot.CanvasOverlay.prototype.addLine = function(opts) {
  364. var line = new Line(opts);
  365. this.objects.push(line);
  366. this.objectNames.push(line.options.name);
  367. };
  368. $.jqplot.CanvasOverlay.prototype.addHorizontalLine = function(opts) {
  369. var line = new HorizontalLine(opts);
  370. this.objects.push(line);
  371. this.objectNames.push(line.options.name);
  372. };
  373. $.jqplot.CanvasOverlay.prototype.addDashedHorizontalLine = function(opts) {
  374. var line = new DashedHorizontalLine(opts);
  375. this.objects.push(line);
  376. this.objectNames.push(line.options.name);
  377. };
  378. $.jqplot.CanvasOverlay.prototype.addVerticalLine = function(opts) {
  379. var line = new VerticalLine(opts);
  380. this.objects.push(line);
  381. this.objectNames.push(line.options.name);
  382. };
  383. $.jqplot.CanvasOverlay.prototype.addDashedVerticalLine = function(opts) {
  384. var line = new DashedVerticalLine(opts);
  385. this.objects.push(line);
  386. this.objectNames.push(line.options.name);
  387. };
  388. $.jqplot.CanvasOverlay.prototype.removeObject = function(idx) {
  389. // check if integer, remove by index
  390. if ($.type(idx) == 'number') {
  391. this.objects.splice(idx, 1);
  392. this.objectNames.splice(idx, 1);
  393. }
  394. // if string, remove by name
  395. else {
  396. var id = $.inArray(idx, this.objectNames);
  397. if (id != -1) {
  398. this.objects.splice(id, 1);
  399. this.objectNames.splice(id, 1);
  400. }
  401. }
  402. };
  403. $.jqplot.CanvasOverlay.prototype.getObject = function(idx) {
  404. // check if integer, remove by index
  405. if ($.type(idx) == 'number') {
  406. return this.objects[idx];
  407. }
  408. // if string, remove by name
  409. else {
  410. var id = $.inArray(idx, this.objectNames);
  411. if (id != -1) {
  412. return this.objects[id];
  413. }
  414. }
  415. };
  416. // Set get as alias for getObject.
  417. $.jqplot.CanvasOverlay.prototype.get = $.jqplot.CanvasOverlay.prototype.getObject;
  418. $.jqplot.CanvasOverlay.prototype.clear = function(plot) {
  419. this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight());
  420. };
  421. $.jqplot.CanvasOverlay.prototype.draw = function(plot) {
  422. var obj,
  423. objs = this.objects,
  424. mr = this.markerRenderer,
  425. start,
  426. stop;
  427. if (this.options.show) {
  428. this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight());
  429. for (var k=0; k<objs.length; k++) {
  430. obj = objs[k];
  431. var opts = $.extend(true, {}, obj.options);
  432. if (obj.options.show) {
  433. // style and shadow properties should be set before
  434. // every draw of marker renderer.
  435. mr.shadow = obj.options.shadow;
  436. switch (obj.type) {
  437. case 'line':
  438. // style and shadow properties should be set before
  439. // every draw of marker renderer.
  440. mr.style = 'line';
  441. opts.closePath = false;
  442. start = [plot.axes[obj.options.xaxis].series_u2p(obj.options.start[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.start[1])];
  443. stop = [plot.axes[obj.options.xaxis].series_u2p(obj.options.stop[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.stop[1])];
  444. mr.draw(start, stop, this.canvas._ctx, opts);
  445. break;
  446. case 'horizontalLine':
  447. // style and shadow properties should be set before
  448. // every draw of marker renderer.
  449. if (obj.options.y != null) {
  450. mr.style = 'line';
  451. opts.closePath = false;
  452. var xaxis = plot.axes[obj.options.xaxis],
  453. xstart,
  454. xstop,
  455. y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y),
  456. xminoff = obj.options.xminOffset || obj.options.xOffset,
  457. xmaxoff = obj.options.xmaxOffset || obj.options.xOffset;
  458. if (obj.options.xmin != null) {
  459. xstart = xaxis.series_u2p(obj.options.xmin);
  460. }
  461. else if (xminoff != null) {
  462. if ($.type(xminoff) == "number") {
  463. xstart = xaxis.series_u2p(xaxis.min + xminoff);
  464. }
  465. else if ($.type(xminoff) == "string") {
  466. xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff);
  467. }
  468. }
  469. if (obj.options.xmax != null) {
  470. xstop = xaxis.series_u2p(obj.options.xmax);
  471. }
  472. else if (xmaxoff != null) {
  473. if ($.type(xmaxoff) == "number") {
  474. xstop = xaxis.series_u2p(xaxis.max - xmaxoff);
  475. }
  476. else if ($.type(xmaxoff) == "string") {
  477. xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff);
  478. }
  479. }
  480. if (xstop != null && xstart != null) {
  481. mr.draw([xstart, y], [xstop, y], this.canvas._ctx, opts);
  482. }
  483. }
  484. break;
  485. case 'dashedHorizontalLine':
  486. var dashPat = obj.options.dashPattern;
  487. var dashPatLen = 0;
  488. for (var i=0; i<dashPat.length; i++) {
  489. dashPatLen += dashPat[i];
  490. }
  491. // style and shadow properties should be set before
  492. // every draw of marker renderer.
  493. if (obj.options.y != null) {
  494. mr.style = 'line';
  495. opts.closePath = false;
  496. var xaxis = plot.axes[obj.options.xaxis],
  497. xstart,
  498. xstop,
  499. y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y),
  500. xminoff = obj.options.xminOffset || obj.options.xOffset,
  501. xmaxoff = obj.options.xmaxOffset || obj.options.xOffset;
  502. if (obj.options.xmin != null) {
  503. xstart = xaxis.series_u2p(obj.options.xmin);
  504. }
  505. else if (xminoff != null) {
  506. if ($.type(xminoff) == "number") {
  507. xstart = xaxis.series_u2p(xaxis.min + xminoff);
  508. }
  509. else if ($.type(xminoff) == "string") {
  510. xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff);
  511. }
  512. }
  513. if (obj.options.xmax != null) {
  514. xstop = xaxis.series_u2p(obj.options.xmax);
  515. }
  516. else if (xmaxoff != null) {
  517. if ($.type(xmaxoff) == "number") {
  518. xstop = xaxis.series_u2p(xaxis.max - xmaxoff);
  519. }
  520. else if ($.type(xmaxoff) == "string") {
  521. xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff);
  522. }
  523. }
  524. if (xstop != null && xstart != null) {
  525. var numDash = Math.ceil((xstop - xstart)/dashPatLen);
  526. var b=xstart, e;
  527. for (var i=0; i<numDash; i++) {
  528. for (var j=0; j<dashPat.length; j+=2) {
  529. e = b+dashPat[j];
  530. mr.draw([b, y], [e, y], this.canvas._ctx, opts);
  531. b += dashPat[j];
  532. if (j < dashPat.length-1) {
  533. b += dashPat[j+1];
  534. }
  535. }
  536. }
  537. }
  538. }
  539. break;
  540. case 'verticalLine':
  541. // style and shadow properties should be set before
  542. // every draw of marker renderer.
  543. if (obj.options.x != null) {
  544. mr.style = 'line';
  545. opts.closePath = false;
  546. var yaxis = plot.axes[obj.options.yaxis],
  547. ystart,
  548. ystop,
  549. x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x),
  550. yminoff = obj.options.yminOffset || obj.options.yOffset,
  551. ymaxoff = obj.options.ymaxOffset || obj.options.yOffset;
  552. if (obj.options.ymin != null) {
  553. ystart = yaxis.series_u2p(obj.options.ymin);
  554. }
  555. else if (yminoff != null) {
  556. if ($.type(yminoff) == "number") {
  557. ystart = yaxis.series_u2p(yaxis.min - yminoff);
  558. }
  559. else if ($.type(yminoff) == "string") {
  560. ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff);
  561. }
  562. }
  563. if (obj.options.ymax != null) {
  564. ystop = yaxis.series_u2p(obj.options.ymax);
  565. }
  566. else if (ymaxoff != null) {
  567. if ($.type(ymaxoff) == "number") {
  568. ystop = yaxis.series_u2p(yaxis.max + ymaxoff);
  569. }
  570. else if ($.type(ymaxoff) == "string") {
  571. ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff);
  572. }
  573. }
  574. if (ystop != null && ystart != null) {
  575. mr.draw([x, ystart], [x, ystop], this.canvas._ctx, opts);
  576. }
  577. }
  578. break;
  579. case 'dashedVerticalLine':
  580. var dashPat = obj.options.dashPattern;
  581. var dashPatLen = 0;
  582. for (var i=0; i<dashPat.length; i++) {
  583. dashPatLen += dashPat[i];
  584. }
  585. // style and shadow properties should be set before
  586. // every draw of marker renderer.
  587. if (obj.options.x != null) {
  588. mr.style = 'line';
  589. opts.closePath = false;
  590. var yaxis = plot.axes[obj.options.yaxis],
  591. ystart,
  592. ystop,
  593. x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x),
  594. yminoff = obj.options.yminOffset || obj.options.yOffset,
  595. ymaxoff = obj.options.ymaxOffset || obj.options.yOffset;
  596. if (obj.options.ymin != null) {
  597. ystart = yaxis.series_u2p(obj.options.ymin);
  598. }
  599. else if (yminoff != null) {
  600. if ($.type(yminoff) == "number") {
  601. ystart = yaxis.series_u2p(yaxis.min - yminoff);
  602. }
  603. else if ($.type(yminoff) == "string") {
  604. ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff);
  605. }
  606. }
  607. if (obj.options.ymax != null) {
  608. ystop = yaxis.series_u2p(obj.options.ymax);
  609. }
  610. else if (ymaxoff != null) {
  611. if ($.type(ymaxoff) == "number") {
  612. ystop = yaxis.series_u2p(yaxis.max + ymaxoff);
  613. }
  614. else if ($.type(ymaxoff) == "string") {
  615. ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff);
  616. }
  617. }
  618. if (ystop != null && ystart != null) {
  619. var numDash = Math.ceil((ystart - ystop)/dashPatLen);
  620. var firstDashAdjust = ((numDash * dashPatLen) - (ystart - ystop))/2.0;
  621. var b=ystart, e, bs, es;
  622. for (var i=0; i<numDash; i++) {
  623. for (var j=0; j<dashPat.length; j+=2) {
  624. e = b - dashPat[j];
  625. if (e < ystop) {
  626. e = ystop;
  627. }
  628. if (b < ystop) {
  629. b = ystop;
  630. }
  631. // es = e;
  632. // if (i == 0) {
  633. // es += firstDashAdjust;
  634. // }
  635. mr.draw([x, b], [x, e], this.canvas._ctx, opts);
  636. b -= dashPat[j];
  637. if (j < dashPat.length-1) {
  638. b -= dashPat[j+1];
  639. }
  640. }
  641. }
  642. }
  643. }
  644. break;
  645. default:
  646. break;
  647. }
  648. }
  649. }
  650. }
  651. };
  652. // called within context of plot
  653. // create a canvas which we can draw on.
  654. // insert it before the eventCanvas, so eventCanvas will still capture events.
  655. $.jqplot.CanvasOverlay.postPlotDraw = function() {
  656. // Memory Leaks patch
  657. if (this.plugins.canvasOverlay && this.plugins.canvasOverlay.highlightCanvas) {
  658. this.plugins.canvasOverlay.highlightCanvas.resetCanvas();
  659. this.plugins.canvasOverlay.highlightCanvas = null;
  660. }
  661. this.plugins.canvasOverlay.canvas = new $.jqplot.GenericCanvas();
  662. this.eventCanvas._elem.before(this.plugins.canvasOverlay.canvas.createElement(this._gridPadding, 'jqplot-overlayCanvas-canvas', this._plotDimensions, this));
  663. this.plugins.canvasOverlay.canvas.setContext();
  664. if (!this.plugins.canvasOverlay.deferDraw) {
  665. this.plugins.canvasOverlay.draw(this);
  666. }
  667. };
  668. $.jqplot.postInitHooks.push($.jqplot.CanvasOverlay.postPlotInit);
  669. $.jqplot.postDrawHooks.push($.jqplot.CanvasOverlay.postPlotDraw);
  670. })(jQuery);