API Docs for: 3.18.1
Show:

File: charts/js/Lines.js

  1. /**
  2. * Provides functionality for drawing lines in a series.
  3. *
  4. * @module charts
  5. * @submodule series-line-util
  6. */
  7. /**
  8. * Utility class used for drawing lines.
  9. *
  10. * @class Lines
  11. * @constructor
  12. * @submodule series-line-util
  13. */
  14. var Y_Lang = Y.Lang;
  15. function Lines(){}
  16.  
  17. Lines.prototype = {
  18. /**
  19. * @property _lineDefaults
  20. * @type Object
  21. * @private
  22. */
  23. _lineDefaults: null,
  24.  
  25. /**
  26. * Creates a graphic in which to draw a series.
  27. *
  28. * @method _getGraphic
  29. * @return Graphic
  30. * @private
  31. */
  32. _getGraphic: function()
  33. {
  34. var graphic = this.get("graphic") || this.get("graph").get("graphic");
  35. if(!this._lineGraphic)
  36. {
  37. this._lineGraphic = graphic.addShape({type: "path"});
  38. }
  39. this._lineGraphic.clear();
  40. return this._lineGraphic;
  41. },
  42.  
  43. /**
  44. * Toggles visibility
  45. *
  46. * @method _toggleVisible
  47. * @param {Boolean} visible indicates visibilitye
  48. * @private
  49. */
  50. _toggleVisible: function(visible)
  51. {
  52. if(this._lineGraphic)
  53. {
  54. this._lineGraphic.set("visible", visible);
  55. }
  56. },
  57.  
  58. /**
  59. * Draws lines for the series.
  60. *
  61. * @method drawLines
  62. * @protected
  63. */
  64. drawLines: function()
  65. {
  66. if(this.get("xcoords").length < 1)
  67. {
  68. return;
  69. }
  70. var isNumber = Y_Lang.isNumber,
  71. xcoords,
  72. ycoords,
  73. direction = this.get("direction"),
  74. len,
  75. lastPointValid,
  76. pointValid,
  77. noPointsRendered = true,
  78. lastValidX,
  79. lastValidY,
  80. nextX,
  81. nextY,
  82. i,
  83. styles = this.get("styles").line,
  84. lineType = styles.lineType,
  85. lc = styles.color || this._getDefaultColor(this.get("graphOrder"), "line"),
  86. lineAlpha = styles.alpha,
  87. dashLength = styles.dashLength,
  88. gapSpace = styles.gapSpace,
  89. connectDiscontinuousPoints = styles.connectDiscontinuousPoints,
  90. discontinuousType = styles.discontinuousType,
  91. discontinuousDashLength = styles.discontinuousDashLength,
  92. discontinuousGapSpace = styles.discontinuousGapSpace,
  93. path = this._getGraphic();
  94. if(this._stacked)
  95. {
  96. xcoords = this.get("stackedXCoords");
  97. ycoords = this.get("stackedYCoords");
  98. }
  99. else
  100. {
  101. xcoords = this.get("xcoords");
  102. ycoords = this.get("ycoords");
  103. }
  104. len = direction === "vertical" ? ycoords.length : xcoords.length;
  105. path.set("stroke", {
  106. weight: styles.weight,
  107. color: lc,
  108. opacity: lineAlpha
  109. });
  110. for(i = 0; i < len; i = ++i)
  111. {
  112. nextX = xcoords[i];
  113. nextY = ycoords[i];
  114. pointValid = isNumber(nextX) && isNumber(nextY);
  115. if(!pointValid)
  116. {
  117. lastPointValid = pointValid;
  118. continue;
  119. }
  120. if(noPointsRendered)
  121. {
  122. noPointsRendered = false;
  123. path.moveTo(nextX, nextY);
  124. }
  125. else if(lastPointValid)
  126. {
  127. if(lineType !== "dashed")
  128. {
  129. path.lineTo(nextX, nextY);
  130. }
  131. else
  132. {
  133. this.drawDashedLine(path, lastValidX, lastValidY, nextX, nextY,
  134. dashLength,
  135. gapSpace);
  136. }
  137. }
  138. else if(!connectDiscontinuousPoints)
  139. {
  140. path.moveTo(nextX, nextY);
  141. }
  142. else
  143. {
  144. if(discontinuousType !== "solid")
  145. {
  146. this.drawDashedLine(path, lastValidX, lastValidY, nextX, nextY,
  147. discontinuousDashLength,
  148. discontinuousGapSpace);
  149. }
  150. else
  151. {
  152. path.lineTo(nextX, nextY);
  153. }
  154. }
  155. lastValidX = nextX;
  156. lastValidY = nextY;
  157. lastPointValid = true;
  158. }
  159. path.end();
  160. },
  161.  
  162. /**
  163. * Connects data points with a consistent curve for a series.
  164. *
  165. * @method drawSpline
  166. * @protected
  167. */
  168. drawSpline: function()
  169. {
  170. if(this.get("xcoords").length < 1)
  171. {
  172. return;
  173. }
  174. var xcoords = this.get("xcoords"),
  175. ycoords = this.get("ycoords"),
  176. curvecoords = this.getCurveControlPoints(xcoords, ycoords),
  177. len = curvecoords.length,
  178. cx1,
  179. cx2,
  180. cy1,
  181. cy2,
  182. x,
  183. y,
  184. i = 0,
  185. styles = this.get("styles").line,
  186. path = this._getGraphic(),
  187. lineAlpha = styles.alpha,
  188. color = styles.color || this._getDefaultColor(this.get("graphOrder"), "line");
  189. path.set("stroke", {
  190. weight: styles.weight,
  191. color: color,
  192. opacity: lineAlpha
  193. });
  194. path.moveTo(xcoords[0], ycoords[0]);
  195. for(; i < len; i = ++i)
  196. {
  197. x = curvecoords[i].endx;
  198. y = curvecoords[i].endy;
  199. cx1 = curvecoords[i].ctrlx1;
  200. cx2 = curvecoords[i].ctrlx2;
  201. cy1 = curvecoords[i].ctrly1;
  202. cy2 = curvecoords[i].ctrly2;
  203. path.curveTo(cx1, cy1, cx2, cy2, x, y);
  204. }
  205. path.end();
  206. },
  207.  
  208. /**
  209. * Draws a dashed line between two points.
  210. *
  211. * @method drawDashedLine
  212. * @param {Number} xStart The x position of the start of the line
  213. * @param {Number} yStart The y position of the start of the line
  214. * @param {Number} xEnd The x position of the end of the line
  215. * @param {Number} yEnd The y position of the end of the line
  216. * @param {Number} dashSize the size of dashes, in pixels
  217. * @param {Number} gapSize the size of gaps between dashes, in pixels
  218. * @private
  219. */
  220. drawDashedLine: function(path, xStart, yStart, xEnd, yEnd, dashSize, gapSize)
  221. {
  222. dashSize = dashSize || 10;
  223. gapSize = gapSize || 10;
  224. var segmentLength = dashSize + gapSize,
  225. xDelta = xEnd - xStart,
  226. yDelta = yEnd - yStart,
  227. delta = Math.sqrt(Math.pow(xDelta, 2) + Math.pow(yDelta, 2)),
  228. segmentCount = Math.floor(Math.abs(delta / segmentLength)),
  229. radians = Math.atan2(yDelta, xDelta),
  230. xCurrent = xStart,
  231. yCurrent = yStart,
  232. i;
  233. xDelta = Math.cos(radians) * segmentLength;
  234. yDelta = Math.sin(radians) * segmentLength;
  235.  
  236. for(i = 0; i < segmentCount; ++i)
  237. {
  238. path.moveTo(xCurrent, yCurrent);
  239. path.lineTo(xCurrent + Math.cos(radians) * dashSize, yCurrent + Math.sin(radians) * dashSize);
  240. xCurrent += xDelta;
  241. yCurrent += yDelta;
  242. }
  243.  
  244. path.moveTo(xCurrent, yCurrent);
  245. delta = Math.sqrt((xEnd - xCurrent) * (xEnd - xCurrent) + (yEnd - yCurrent) * (yEnd - yCurrent));
  246.  
  247. if(delta > dashSize)
  248. {
  249. path.lineTo(xCurrent + Math.cos(radians) * dashSize, yCurrent + Math.sin(radians) * dashSize);
  250. }
  251. else if(delta > 0)
  252. {
  253. path.lineTo(xCurrent + Math.cos(radians) * delta, yCurrent + Math.sin(radians) * delta);
  254. }
  255.  
  256. path.moveTo(xEnd, yEnd);
  257. },
  258.  
  259. /**
  260. * Default values for `styles` attribute.
  261. *
  262. * @method _getLineDefaults
  263. * @return Object
  264. * @protected
  265. */
  266. _getLineDefaults: function()
  267. {
  268. return {
  269. alpha: 1,
  270. weight: 6,
  271. lineType:"solid",
  272. dashLength:10,
  273. gapSpace:10,
  274. connectDiscontinuousPoints:true,
  275. discontinuousType:"solid",
  276. discontinuousDashLength:10,
  277. discontinuousGapSpace:10
  278. };
  279. }
  280. };
  281. Y.augment(Lines, Y.Attribute);
  282. Y.Lines = Lines;
  283.