Version 3.18.1
Show:

File: charts/js/TopAxisLayout.js

  1. /**
  2. * Contains algorithms for rendering a top axis.
  3. *
  4. * @class TopAxisLayout
  5. * @constructor
  6. * @submodule axis
  7. */
  8. TopAxisLayout = function(){};
  9. TopAxisLayout.prototype = {
  10. /**
  11. * Default margins for text fields.
  12. *
  13. * @private
  14. * @method _getDefaultMargins
  15. * @return Object
  16. */
  17. _getDefaultMargins: function()
  18. {
  19. return {
  20. top: 0,
  21. left: 0,
  22. right: 0,
  23. bottom: 4
  24. };
  25. },
  26. /**
  27. * Sets the length of the tick on either side of the axis line.
  28. *
  29. * @method setTickOffsets
  30. * @protected
  31. */
  32. setTickOffsets: function()
  33. {
  34. var host = this,
  35. majorTicks = host.get("styles").majorTicks,
  36. tickLength = majorTicks.length,
  37. halfTick = tickLength * 0.5,
  38. display = majorTicks.display;
  39. host.set("leftTickOffset", 0);
  40. host.set("rightTickOffset", 0);
  41. switch(display)
  42. {
  43. case "inside" :
  44. host.set("bottomTickOffset", tickLength);
  45. host.set("topTickOffset", 0);
  46. break;
  47. case "outside" :
  48. host.set("bottomTickOffset", 0);
  49. host.set("topTickOffset", tickLength);
  50. break;
  51. case "cross" :
  52. host.set("topTickOffset", halfTick);
  53. host.set("bottomTickOffset", halfTick);
  54. break;
  55. default:
  56. host.set("topTickOffset", 0);
  57. host.set("bottomTickOffset", 0);
  58. break;
  59. }
  60. },
  61. /**
  62. * Calculates the coordinates for the first point on an axis.
  63. *
  64. * @method getLineStart
  65. * @protected
  66. */
  67. getLineStart: function()
  68. {
  69. var host = this,
  70. style = host.get("styles"),
  71. padding = style.padding,
  72. majorTicks = style.majorTicks,
  73. tickLength = majorTicks.length,
  74. display = majorTicks.display,
  75. pt = {x:0, y:padding.top};
  76. if(display === "outside")
  77. {
  78. pt.y += tickLength;
  79. }
  80. else if(display === "cross")
  81. {
  82. pt.y += tickLength/2;
  83. }
  84. return pt;
  85. },
  86. /**
  87. * Draws a tick
  88. *
  89. * @method drawTick
  90. * @param {Path} path reference to the path `Path` element in which to draw the tick.
  91. * @param {Object} pt hash containing x and y coordinates
  92. * @param {Object} tickStyles hash of properties used to draw the tick
  93. * @protected
  94. */
  95. drawTick: function(path, pt, tickStyles)
  96. {
  97. var host = this,
  98. style = host.get("styles"),
  99. padding = style.padding,
  100. tickLength = tickStyles.length,
  101. start = {x:pt.x, y:padding.top},
  102. end = {x:pt.x, y:tickLength + padding.top};
  103. host.drawLine(path, start, end);
  104. },
  105. /**
  106. * Calculates the point for a label.
  107. *
  108. * @method getLabelPoint
  109. * @param {Object} pt hash containing x and y coordinates
  110. * @return Object
  111. * @protected
  112. */
  113. getLabelPoint: function(pt)
  114. {
  115. return {x:pt.x, y:pt.y - this.get("topTickOffset")};
  116. },
  117. /**
  118. * Updates the value for the `maxLabelSize` for use in calculating total size.
  119. *
  120. * @method updateMaxLabelSize
  121. * @param {HTMLElement} label to measure
  122. * @protected
  123. */
  124. updateMaxLabelSize: function(labelWidth, labelHeight)
  125. {
  126. var host = this,
  127. props = this._labelRotationProps,
  128. rot = props.rot,
  129. absRot = props.absRot,
  130. sinRadians = props.sinRadians,
  131. cosRadians = props.cosRadians,
  132. max;
  133. if(rot === 0)
  134. {
  135. max = labelHeight;
  136. }
  137. else if(absRot === 90)
  138. {
  139. max = labelWidth;
  140. }
  141. else
  142. {
  143. max = (sinRadians * labelWidth) + (cosRadians * labelHeight);
  144. }
  145. host._maxLabelSize = Math.max(host._maxLabelSize, max);
  146. },
  147. /**
  148. * Determines the available label height when the axis width has been explicitly set.
  149. *
  150. * @method getExplicitlySized
  151. * @return Boolean
  152. * @protected
  153. */
  154. getExplicitlySized: function(styles)
  155. {
  156. if(this._explicitHeight)
  157. {
  158. var host = this,
  159. h = host._explicitHeight,
  160. totalTitleSize = host._totalTitleSize,
  161. topTickOffset = host.get("topTickOffset"),
  162. margin = styles.label.margin.right;
  163. host._maxLabelSize = h - (topTickOffset + margin + totalTitleSize);
  164. return true;
  165. }
  166. return false;
  167. },
  168. /**
  169. * Rotate and position title.
  170. *
  171. * @method positionTitle
  172. * @param {HTMLElement} label to rotate position
  173. * @protected
  174. */
  175. positionTitle: function(label)
  176. {
  177. var host = this,
  178. bounds = host._titleBounds,
  179. margin = host.get("styles").title.margin,
  180. props = host._titleRotationProps,
  181. labelWidth = label.offsetWidth,
  182. labelHeight = label.offsetHeight,
  183. h = bounds.bottom - bounds.top,
  184. x = (host.get("width") * 0.5) - (labelWidth * 0.5),
  185. y = h/2 - labelHeight/2;
  186. props.labelWidth = labelWidth;
  187. props.labelHeight = labelHeight;
  188. if(margin && margin.top)
  189. {
  190. y += margin.top;
  191. }
  192. props.x = x;
  193. props.y = y;
  194. props.transformOrigin = [0.5, 0.5];
  195. host._rotate(label, props);
  196. },
  197. /**
  198. * Rotate and position labels.
  199. *
  200. * @method positionLabel
  201. * @param {HTMLElement} label to rotate position
  202. * @param {Object} pt hash containing the x and y coordinates in which the label will be positioned
  203. * against.
  204. * @protected
  205. */
  206. positionLabel: function(label, pt, styles, i)
  207. {
  208. var host = this,
  209. offset = parseFloat(styles.label.offset),
  210. totalTitleSize = this._totalTitleSize,
  211. maxLabelSize = host._maxLabelSize,
  212. leftOffset = pt.x,
  213. topOffset = pt.y + totalTitleSize + maxLabelSize,
  214. props = this._labelRotationProps,
  215. rot = props.rot,
  216. absRot = props.absRot,
  217. labelWidth = this._labelWidths[i],
  218. labelHeight = this._labelHeights[i];
  219. if(rot === 0)
  220. {
  221. leftOffset -= labelWidth * offset;
  222. topOffset -= labelHeight;
  223. }
  224. else
  225. {
  226. if(rot === 90)
  227. {
  228. leftOffset = leftOffset - labelWidth + labelHeight/2 - (labelHeight * offset);
  229. topOffset -= (labelHeight * 0.5);
  230. }
  231. else if (rot === -90)
  232. {
  233. leftOffset = leftOffset + labelHeight/2 - (labelHeight * offset);
  234. topOffset -= (labelHeight * 0.5);
  235. }
  236. else if(rot > 0)
  237. {
  238. leftOffset = leftOffset - labelWidth + labelHeight/2 - (labelHeight * offset);
  239. topOffset -= labelHeight - (labelHeight * rot/180);
  240. }
  241. else
  242. {
  243. leftOffset = leftOffset + labelHeight/2 - (labelHeight * offset);
  244. topOffset -= labelHeight - (labelHeight * absRot/180);
  245. }
  246. }
  247. props.x = Math.round(leftOffset);
  248. props.y = Math.round(topOffset);
  249. props.labelWidth = labelWidth;
  250. props.labelHeight = labelHeight;
  251. this._rotate(label, props);
  252. },
  253. /**
  254. * Adjusts the coordinates of an axis label based on the rotation.
  255. *
  256. * @method _setRotationCoords
  257. * @param {Object} props Coordinates, dimension and rotation properties of the label.
  258. * @protected
  259. */
  260. _setRotationCoords: function(props)
  261. {
  262. var rot = props.rot,
  263. absRot = props.absRot,
  264. labelWidth = props.labelWidth,
  265. labelHeight = props.labelHeight,
  266. leftOffset,
  267. topOffset;
  268. if(rot === 0)
  269. {
  270. leftOffset = labelWidth * 0.5;
  271. topOffset = labelHeight;
  272. }
  273. else
  274. {
  275. if(rot === 90)
  276. {
  277. leftOffset = labelWidth;
  278. topOffset = (labelHeight * 0.5);
  279. }
  280. else if (rot === -90)
  281. {
  282. topOffset = (labelHeight * 0.5);
  283. }
  284. else if(rot > 0)
  285. {
  286. leftOffset = labelWidth;
  287. topOffset = labelHeight - (labelHeight * rot/180);
  288. }
  289. else
  290. {
  291. topOffset = labelHeight - (labelHeight * absRot/180);
  292. }
  293. }
  294. props.x -= leftOffset;
  295. props.y -= topOffset;
  296. },
  297. /**
  298. * Returns the transformOrigin to use for an axis label based on the position of the axis
  299. * and the rotation of the label.
  300. *
  301. * @method _getTransformOrigin
  302. * @param {Number} rot The rotation (in degrees) of the label.
  303. * @return Array
  304. * @protected
  305. */
  306. _getTransformOrigin: function(rot)
  307. {
  308. var transformOrigin;
  309. if(rot === 0)
  310. {
  311. transformOrigin = [0, 0];
  312. }
  313. else
  314. {
  315. if(rot === 90)
  316. {
  317. transformOrigin = [1, 0.5];
  318. }
  319. else if (rot === -90)
  320. {
  321. transformOrigin = [0, 0.5];
  322. }
  323. else if(rot > 0)
  324. {
  325. transformOrigin = [1, 0.5];
  326. }
  327. else
  328. {
  329. transformOrigin = [0, 0.5];
  330. }
  331. }
  332. return transformOrigin;
  333. },
  334. /**
  335. * Adjusts position for inner ticks.
  336. *
  337. * @method offsetNodeForTick
  338. * @param {Node} cb contentBox of the axis
  339. * @protected
  340. */
  341. offsetNodeForTick: function()
  342. {
  343. },
  344. /**
  345. * Assigns a height based on the size of the contents.
  346. *
  347. * @method setCalculatedSize
  348. * @protected
  349. */
  350. setCalculatedSize: function()
  351. {
  352. var host = this,
  353. graphic = host.get("graphic"),
  354. styles = host.get("styles"),
  355. labelMargin = styles.label.margin,
  356. totalLabelSize = labelMargin.bottom + host._maxLabelSize,
  357. totalTitleSize = host._totalTitleSize,
  358. topTickOffset = this.get("topTickOffset"),
  359. ttl = Math.round(topTickOffset + totalLabelSize + totalTitleSize);
  360. if(this._explicitHeight)
  361. {
  362. ttl = this._explicitHeight;
  363. }
  364. host.set("calculatedHeight", ttl);
  365. graphic.set("y", ttl - topTickOffset);
  366. }
  367. };
  368. Y.TopAxisLayout = TopAxisLayout;