Version 3.18.1
Show:

File: charts/js/CartesianSeries.js

  1. /**
  2. * Provides functionality for creating a cartesian chart series.
  3. *
  4. * @module charts
  5. * @submodule series-cartesian
  6. */
  7. var Y_Lang = Y.Lang;
  8. /**
  9. * An abstract class for creating series instances with horizontal and vertical axes.
  10. * CartesianSeries provides the core functionality used by the following classes:
  11. * <ul>
  12. * <li>{{#crossLink "LineSeries"}}{{/crossLink}}</li>
  13. * <li>{{#crossLink "MarkerSeries"}}{{/crossLink}}</li>
  14. * <li>{{#crossLink "AreaSeries"}}{{/crossLink}}</li>
  15. * <li>{{#crossLink "SplineSeries"}}{{/crossLink}}</li>
  16. * <li>{{#crossLink "AreaSplineSeries"}}{{/crossLink}}</li>
  17. * <li>{{#crossLink "ComboSeries"}}{{/crossLink}}</li>
  18. * <li>{{#crossLink "ComboSplineSeries"}}{{/crossLink}}</li>
  19. * <li>{{#crossLink "Histogram"}}{{/crossLink}}</li>
  20. * </ul>
  21. *
  22. * @class CartesianSeries
  23. * @extends SeriesBase
  24. * @constructor
  25. * @param {Object} config (optional) Configuration parameters.
  26. * @submodule series-base
  27. */
  28. Y.CartesianSeries = Y.Base.create("cartesianSeries", Y.SeriesBase, [], {
  29. /**
  30. * Storage for `xDisplayName` attribute.
  31. *
  32. * @property _xDisplayName
  33. * @type String
  34. * @private
  35. */
  36. _xDisplayName: null,
  37. /**
  38. * Storage for `yDisplayName` attribute.
  39. *
  40. * @property _yDisplayName
  41. * @type String
  42. * @private
  43. */
  44. _yDisplayName: null,
  45. /**
  46. * Th x-coordinate for the left edge of the series.
  47. *
  48. * @property _leftOrigin
  49. * @type String
  50. * @private
  51. */
  52. _leftOrigin: null,
  53. /**
  54. * The y-coordinate for the bottom edge of the series.
  55. *
  56. * @property _bottomOrigin
  57. * @type String
  58. * @private
  59. */
  60. _bottomOrigin: null,
  61. /**
  62. * Adds event listeners.
  63. *
  64. * @method addListeners
  65. * @private
  66. */
  67. addListeners: function()
  68. {
  69. var xAxis = this.get("xAxis"),
  70. yAxis = this.get("yAxis");
  71. if(xAxis)
  72. {
  73. this._xDataReadyHandle = xAxis.after("dataReady", Y.bind(this._xDataChangeHandler, this));
  74. this._xDataUpdateHandle = xAxis.after("dataUpdate", Y.bind(this._xDataChangeHandler, this));
  75. }
  76. if(yAxis)
  77. {
  78. this._yDataReadyHandle = yAxis.after("dataReady", Y.bind(this._yDataChangeHandler, this));
  79. this._yDataUpdateHandle = yAxis.after("dataUpdate", Y.bind(this._yDataChangeHandler, this));
  80. }
  81. this._xAxisChangeHandle = this.after("xAxisChange", this._xAxisChangeHandler);
  82. this._yAxisChangeHandle = this.after("yAxisChange", this._yAxisChangeHandler);
  83. this._stylesChangeHandle = this.after("stylesChange", function() {
  84. var axesReady = this._updateAxisBase();
  85. if(axesReady)
  86. {
  87. this.draw();
  88. }
  89. });
  90. this._widthChangeHandle = this.after("widthChange", function() {
  91. var axesReady = this._updateAxisBase();
  92. if(axesReady)
  93. {
  94. this.draw();
  95. }
  96. });
  97. this._heightChangeHandle = this.after("heightChange", function() {
  98. var axesReady = this._updateAxisBase();
  99. if(axesReady)
  100. {
  101. this.draw();
  102. }
  103. });
  104. this._visibleChangeHandle = this.after("visibleChange", this._handleVisibleChange);
  105. },
  106. /**
  107. * Event handler for the xAxisChange event.
  108. *
  109. * @method _xAxisChangeHandler
  110. * @param {Object} e Event object.
  111. * @private
  112. */
  113. _xAxisChangeHandler: function()
  114. {
  115. var xAxis = this.get("xAxis");
  116. xAxis.after("dataReady", Y.bind(this._xDataChangeHandler, this));
  117. xAxis.after("dataUpdate", Y.bind(this._xDataChangeHandler, this));
  118. },
  119. /**
  120. * Event handler the yAxisChange event.
  121. *
  122. * @method _yAxisChangeHandler
  123. * @param {Object} e Event object.
  124. * @private
  125. */
  126. _yAxisChangeHandler: function()
  127. {
  128. var yAxis = this.get("yAxis");
  129. yAxis.after("dataReady", Y.bind(this._yDataChangeHandler, this));
  130. yAxis.after("dataUpdate", Y.bind(this._yDataChangeHandler, this));
  131. },
  132. /**
  133. * Constant used to generate unique id.
  134. *
  135. * @property GUID
  136. * @type String
  137. * @private
  138. */
  139. GUID: "yuicartesianseries",
  140. /**
  141. * Event handler for xDataChange event.
  142. *
  143. * @method _xDataChangeHandler
  144. * @param {Object} event Event object.
  145. * @private
  146. */
  147. _xDataChangeHandler: function()
  148. {
  149. var axesReady = this._updateAxisBase();
  150. if(axesReady)
  151. {
  152. this.draw();
  153. }
  154. },
  155. /**
  156. * Event handler for yDataChange event.
  157. *
  158. * @method _yDataChangeHandler
  159. * @param {Object} event Event object.
  160. * @private
  161. */
  162. _yDataChangeHandler: function()
  163. {
  164. var axesReady = this._updateAxisBase();
  165. if(axesReady)
  166. {
  167. this.draw();
  168. }
  169. },
  170. /**
  171. * Checks to ensure that both xAxis and yAxis data are available. If so, set the `xData` and `yData` attributes
  172. * and return `true`. Otherwise, return `false`.
  173. *
  174. * @method _updateAxisBase
  175. * @return Boolean
  176. * @private
  177. */
  178. _updateAxisBase: function()
  179. {
  180. var xAxis = this.get("xAxis"),
  181. yAxis = this.get("yAxis"),
  182. xKey = this.get("xKey"),
  183. yKey = this.get("yKey"),
  184. yData,
  185. xData,
  186. xReady,
  187. yReady,
  188. ready;
  189. if(!xAxis || !yAxis || !xKey || !yKey)
  190. {
  191. ready = false;
  192. }
  193. else
  194. {
  195. xData = xAxis.getDataByKey(xKey);
  196. yData = yAxis.getDataByKey(yKey);
  197. if(Y_Lang.isArray(xKey))
  198. {
  199. xReady = (xData && Y.Object.size(xData) > 0) ? this._checkForDataByKey(xData, xKey) : false;
  200. }
  201. else
  202. {
  203. xReady = xData ? true : false;
  204. }
  205. if(Y_Lang.isArray(yKey))
  206. {
  207. yReady = (yData && Y.Object.size(yData) > 0) ? this._checkForDataByKey(yData, yKey) : false;
  208. }
  209. else
  210. {
  211. yReady = yData ? true : false;
  212. }
  213. ready = xReady && yReady;
  214. if(ready)
  215. {
  216. this.set("xData", xData);
  217. this.set("yData", yData);
  218. }
  219. }
  220. return ready;
  221. },
  222. /**
  223. * Checks to see if all keys of a data object exist and contain data.
  224. *
  225. * @method _checkForDataByKey
  226. * @param {Object} obj The object to check
  227. * @param {Array} keys The keys to check
  228. * @return Boolean
  229. * @private
  230. */
  231. _checkForDataByKey: function(obj, keys)
  232. {
  233. var i,
  234. len = keys.length,
  235. hasData = false;
  236. for(i = 0; i < len; i = i + 1)
  237. {
  238. if(obj[keys[i]])
  239. {
  240. hasData = true;
  241. break;
  242. }
  243. }
  244. return hasData;
  245. },
  246. /**
  247. * Draws the series is the xAxis and yAxis data are both available.
  248. *
  249. * @method validate
  250. * @private
  251. */
  252. validate: function()
  253. {
  254. if((this.get("xData") && this.get("yData")) || this._updateAxisBase())
  255. {
  256. this.draw();
  257. }
  258. else
  259. {
  260. this.fire("drawingComplete");
  261. }
  262. },
  263. /**
  264. * Calculates the coordinates for the series.
  265. *
  266. * @method setAreaData
  267. * @protected
  268. */
  269. setAreaData: function()
  270. {
  271. var w = this.get("width"),
  272. h = this.get("height"),
  273. xAxis = this.get("xAxis"),
  274. yAxis = this.get("yAxis"),
  275. xData = this._copyData(this.get("xData")),
  276. yData = this._copyData(this.get("yData")),
  277. direction = this.get("direction"),
  278. dataLength = direction === "vertical" ? yData.length : xData.length,
  279. xOffset = xAxis.getEdgeOffset(xAxis.getTotalMajorUnits(), w),
  280. yOffset = yAxis.getEdgeOffset(yAxis.getTotalMajorUnits(), h),
  281. padding = this.get("styles").padding,
  282. leftPadding = padding.left,
  283. topPadding = padding.top,
  284. dataWidth = w - (leftPadding + padding.right + xOffset * 2),
  285. dataHeight = h - (topPadding + padding.bottom + yOffset * 2),
  286. xMax = xAxis.get("maximum"),
  287. xMin = xAxis.get("minimum"),
  288. yMax = yAxis.get("maximum"),
  289. yMin = yAxis.get("minimum"),
  290. graphic = this.get("graphic"),
  291. yAxisType = yAxis.get("type"),
  292. reverseYCoords = (yAxisType === "numeric" || yAxisType === "stacked"),
  293. xcoords,
  294. ycoords,
  295. xOriginValue = xAxis.getOrigin(),
  296. yOriginValue = yAxis.getOrigin();
  297. graphic.set("width", w);
  298. graphic.set("height", h);
  299. xOffset = xOffset + leftPadding;
  300. yOffset = reverseYCoords ? yOffset + dataHeight + topPadding + padding.bottom : topPadding + yOffset;
  301. this._leftOrigin = Math.round(xAxis._getCoordFromValue(xMin, xMax, dataWidth, xOriginValue, xOffset, false));
  302. this._bottomOrigin = Math.round(yAxis._getCoordFromValue(yMin, yMax, dataHeight, yOriginValue, yOffset, reverseYCoords));
  303. xcoords = this._getCoords(xMin, xMax, dataWidth, xData, xAxis, xOffset, false);
  304. ycoords = this._getCoords(yMin, yMax, dataHeight, yData, yAxis, yOffset, reverseYCoords);
  305. this.set("xcoords", xcoords);
  306. this.set("ycoords", ycoords);
  307. this._dataLength = dataLength;
  308. this._setXMarkerPlane(xcoords, dataLength);
  309. this._setYMarkerPlane(ycoords, dataLength);
  310. },
  311. /**
  312. * Returns either an array coordinates or an object key valued arrays of coordinates depending on the input.
  313. * If the input data is an array, an array is returned. If the input data is an object, an object will be returned.
  314. *
  315. * @method _getCoords
  316. * @param {Number} min The minimum value of the range of data.
  317. * @param {Number} max The maximum value of the range of data.
  318. * @param {Number} length The length, in pixels, of across which the coordinates will be calculated.
  319. * @param {AxisBase} axis The axis in which the data is bound.
  320. * @param {Number} offset The value in which to offet the first coordinate.
  321. * @param {Boolean} reverse Indicates whether to calculate the coordinates in reverse order.
  322. * @return Array|Object
  323. * @private
  324. */
  325. _getCoords: function(min, max, length, data, axis, offset, reverse)
  326. {
  327. var coords,
  328. key;
  329. if(Y_Lang.isArray(data))
  330. {
  331. coords = axis._getCoordsFromValues(min, max, length, data, offset, reverse);
  332. }
  333. else
  334. {
  335. coords = {};
  336. for(key in data)
  337. {
  338. if(data.hasOwnProperty(key))
  339. {
  340. coords[key] = this._getCoords.apply(this, [min, max, length, data[key], axis, offset, reverse]);
  341. }
  342. }
  343. }
  344. return coords;
  345. },
  346. /**
  347. * Used to cache xData and yData in the setAreaData method. Returns a copy of an
  348. * array if an array is received as the param and returns an object literal of
  349. * array copies if an object literal is received as the param.
  350. *
  351. * @method _copyData
  352. * @param {Array|Object} val The object or array to be copied.
  353. * @return Array|Object
  354. * @private
  355. */
  356. _copyData: function(val)
  357. {
  358. var copy,
  359. key;
  360. if(Y_Lang.isArray(val))
  361. {
  362. copy = val.concat();
  363. }
  364. else
  365. {
  366. copy = {};
  367. for(key in val)
  368. {
  369. if(val.hasOwnProperty(key))
  370. {
  371. copy[key] = val[key].concat();
  372. }
  373. }
  374. }
  375. return copy;
  376. },
  377. /**
  378. * Sets the marker plane for the series when the coords argument is an array.
  379. * If the coords argument is an object literal no marker plane is set.
  380. *
  381. * @method _setXMarkerPlane
  382. * @param {Array|Object} coords An array of x coordinates or an object literal
  383. * containing key value pairs mapped to an array of coordinates.
  384. * @param {Number} dataLength The length of data for the series.
  385. * @private
  386. */
  387. _setXMarkerPlane: function(coords, dataLength)
  388. {
  389. var i = 0,
  390. xMarkerPlane = [],
  391. xMarkerPlaneOffset = this.get("xMarkerPlaneOffset"),
  392. nextX;
  393. if(Y_Lang.isArray(coords))
  394. {
  395. for(i = 0; i < dataLength; i = i + 1)
  396. {
  397. nextX = coords[i];
  398. xMarkerPlane.push({start:nextX - xMarkerPlaneOffset, end: nextX + xMarkerPlaneOffset});
  399. }
  400. this.set("xMarkerPlane", xMarkerPlane);
  401. }
  402. },
  403. /**
  404. * Sets the marker plane for the series when the coords argument is an array.
  405. * If the coords argument is an object literal no marker plane is set.
  406. *
  407. * @method _setYMarkerPlane
  408. * @param {Array|Object} coords An array of y coordinates or an object literal
  409. * containing key value pairs mapped to an array of coordinates.
  410. * @param {Number} dataLength The length of data for the series.
  411. * @private
  412. */
  413. _setYMarkerPlane: function(coords, dataLength)
  414. {
  415. var i = 0,
  416. yMarkerPlane = [],
  417. yMarkerPlaneOffset = this.get("yMarkerPlaneOffset"),
  418. nextY;
  419. if(Y_Lang.isArray(coords))
  420. {
  421. for(i = 0; i < dataLength; i = i + 1)
  422. {
  423. nextY = coords[i];
  424. yMarkerPlane.push({start:nextY - yMarkerPlaneOffset, end: nextY + yMarkerPlaneOffset});
  425. }
  426. this.set("yMarkerPlane", yMarkerPlane);
  427. }
  428. },
  429. /**
  430. * Finds the first valid index of an array coordinates.
  431. *
  432. * @method _getFirstValidIndex
  433. * @param {Array} coords An array of x or y coordinates.
  434. * @return Number
  435. * @private
  436. */
  437. _getFirstValidIndex: function(coords)
  438. {
  439. var coord,
  440. i = -1,
  441. limit = coords.length;
  442. while(!Y_Lang.isNumber(coord) && i < limit)
  443. {
  444. i += 1;
  445. coord = coords[i];
  446. }
  447. return i;
  448. },
  449. /**
  450. * Finds the last valid index of an array coordinates.
  451. *
  452. * @method _getLastValidIndex
  453. * @param {Array} coords An array of x or y coordinates.
  454. * @return Number
  455. * @private
  456. */
  457. _getLastValidIndex: function(coords)
  458. {
  459. var coord,
  460. i = coords.length,
  461. limit = -1;
  462. while(!Y_Lang.isNumber(coord) && i > limit)
  463. {
  464. i -= 1;
  465. coord = coords[i];
  466. }
  467. return i;
  468. },
  469. /**
  470. * Draws the series.
  471. *
  472. * @method draw
  473. * @protected
  474. */
  475. draw: function()
  476. {
  477. var w = this.get("width"),
  478. h = this.get("height"),
  479. xcoords,
  480. ycoords;
  481. if(this.get("rendered"))
  482. {
  483. if((isFinite(w) && isFinite(h) && w > 0 && h > 0) &&
  484. ((this.get("xData") && this.get("yData")) ||
  485. this._updateAxisBase()))
  486. {
  487. if(this._drawing)
  488. {
  489. this._callLater = true;
  490. return;
  491. }
  492. this._drawing = true;
  493. this._callLater = false;
  494. this.setAreaData();
  495. xcoords = this.get("xcoords");
  496. ycoords = this.get("ycoords");
  497. if(xcoords && ycoords && xcoords.length > 0)
  498. {
  499. this.drawSeries();
  500. }
  501. this._drawing = false;
  502. if(this._callLater)
  503. {
  504. this.draw();
  505. }
  506. else
  507. {
  508. this._toggleVisible(this.get("visible"));
  509. this.fire("drawingComplete");
  510. }
  511. }
  512. }
  513. },
  514. /**
  515. * Default value for plane offsets when the parent chart's `interactiveType` is `planar`.
  516. *
  517. * @property _defaultPlaneOffset
  518. * @type Number
  519. * @private
  520. */
  521. _defaultPlaneOffset: 4,
  522. /**
  523. * Destructor implementation for the CartesianSeries class.
  524. * Calls destroy on all Graphic instances.
  525. *
  526. * @method destructor
  527. * @protected
  528. */
  529. destructor: function()
  530. {
  531. if(this.get("rendered"))
  532. {
  533. if(this._xDataReadyHandle)
  534. {
  535. this._xDataReadyHandle.detach();
  536. }
  537. if(this._xDataUpdateHandle)
  538. {
  539. this._xDataUpdateHandle.detach();
  540. }
  541. if(this._yDataReadyHandle)
  542. {
  543. this._yDataReadyHandle.detach();
  544. }
  545. if(this._yDataUpdateHandle)
  546. {
  547. this._yDataUpdateHandle.detach();
  548. }
  549. if(this._xAxisChangeHandle)
  550. {
  551. this._xAxisChangeHandle.detach();
  552. }
  553. if(this._yAxisChangeHandle)
  554. {
  555. this._yAxisChangeHandle.detach();
  556. }
  557. }
  558. }
  559. /**
  560. * Event handle for the x-axis' dataReady event.
  561. *
  562. * @property _xDataReadyHandle
  563. * @type {EventHandle}
  564. * @private
  565. */
  566. /**
  567. * Event handle for the x-axis dataUpdate event.
  568. *
  569. * @property _xDataUpdateHandle
  570. * @type {EventHandle}
  571. * @private
  572. */
  573. /**
  574. * Event handle for the y-axis dataReady event.
  575. *
  576. * @property _yDataReadyHandle
  577. * @type {EventHandle}
  578. * @private
  579. */
  580. /**
  581. * Event handle for the y-axis dataUpdate event.
  582. * @property _yDataUpdateHandle
  583. * @type {EventHandle}
  584. * @private
  585. */
  586. /**
  587. * Event handle for the xAxisChange event.
  588. * @property _xAxisChangeHandle
  589. * @type {EventHandle}
  590. * @private
  591. */
  592. /**
  593. * Event handle for the yAxisChange event.
  594. * @property _yAxisChangeHandle
  595. * @type {EventHandle}
  596. * @private
  597. */
  598. /**
  599. * Event handle for the stylesChange event.
  600. * @property _stylesChangeHandle
  601. * @type {EventHandle}
  602. * @private
  603. */
  604. /**
  605. * Event handle for the widthChange event.
  606. * @property _widthChangeHandle
  607. * @type {EventHandle}
  608. * @private
  609. */
  610. /**
  611. * Event handle for the heightChange event.
  612. * @property _heightChangeHandle
  613. * @type {EventHandle}
  614. * @private
  615. */
  616. /**
  617. * Event handle for the visibleChange event.
  618. * @property _visibleChangeHandle
  619. * @type {EventHandle}
  620. * @private
  621. */
  622. }, {
  623. ATTRS: {
  624. /**
  625. * An array of all series of the same type used within a chart application.
  626. *
  627. * @attribute seriesTypeCollection
  628. * @type Array
  629. */
  630. seriesTypeCollection: {},
  631. /**
  632. * Name used for for displaying data related to the x-coordinate.
  633. *
  634. * @attribute xDisplayName
  635. * @type String
  636. */
  637. xDisplayName: {
  638. getter: function()
  639. {
  640. return this._xDisplayName || this.get("xKey");
  641. },
  642. setter: function(val)
  643. {
  644. this._xDisplayName = val.toString();
  645. return val;
  646. }
  647. },
  648. /**
  649. * Name used for for displaying data related to the y-coordinate.
  650. *
  651. * @attribute yDisplayName
  652. * @type String
  653. */
  654. yDisplayName: {
  655. getter: function()
  656. {
  657. return this._yDisplayName || this.get("yKey");
  658. },
  659. setter: function(val)
  660. {
  661. this._yDisplayName = val.toString();
  662. return val;
  663. }
  664. },
  665. /**
  666. * Name used for for displaying category data
  667. *
  668. * @attribute categoryDisplayName
  669. * @type String
  670. * @readOnly
  671. */
  672. categoryDisplayName: {
  673. lazyAdd: false,
  674. getter: function()
  675. {
  676. return this.get("direction") === "vertical" ? this.get("yDisplayName") : this.get("xDisplayName");
  677. },
  678. setter: function(val)
  679. {
  680. if(this.get("direction") === "vertical")
  681. {
  682. this._yDisplayName = val;
  683. }
  684. else
  685. {
  686. this._xDisplayName = val;
  687. }
  688. return val;
  689. }
  690. },
  691. /**
  692. * Name used for for displaying value data
  693. *
  694. * @attribute valueDisplayName
  695. * @type String
  696. * @readOnly
  697. */
  698. valueDisplayName: {
  699. lazyAdd: false,
  700. getter: function()
  701. {
  702. return this.get("direction") === "vertical" ? this.get("xDisplayName") : this.get("yDisplayName");
  703. },
  704. setter: function(val)
  705. {
  706. if(this.get("direction") === "vertical")
  707. {
  708. this._xDisplayName = val;
  709. }
  710. else
  711. {
  712. this._yDisplayName = val;
  713. }
  714. return val;
  715. }
  716. },
  717. /**
  718. * Read-only attribute indicating the type of series.
  719. *
  720. * @attribute type
  721. * @type String
  722. * @default cartesian
  723. */
  724. type: {
  725. value: "cartesian"
  726. },
  727. /**
  728. * Order of this instance of this `type`.
  729. *
  730. * @attribute order
  731. * @type Number
  732. */
  733. order: {},
  734. /**
  735. * Order of the instance
  736. *
  737. * @attribute graphOrder
  738. * @type Number
  739. */
  740. graphOrder: {},
  741. /**
  742. * x coordinates for the series.
  743. *
  744. * @attribute xcoords
  745. * @type Array
  746. */
  747. xcoords: {},
  748. /**
  749. * y coordinates for the series
  750. *
  751. * @attribute ycoords
  752. * @type Array
  753. */
  754. ycoords: {},
  755. /**
  756. * Reference to the `Axis` instance used for assigning
  757. * x-values to the graph.
  758. *
  759. * @attribute xAxis
  760. * @type Axis
  761. */
  762. xAxis: {},
  763. /**
  764. * Reference to the `Axis` instance used for assigning
  765. * y-values to the graph.
  766. *
  767. * @attribute yAxis
  768. * @type Axis
  769. */
  770. yAxis: {},
  771. /**
  772. * Indicates which array to from the hash of value arrays in
  773. * the x-axis `Axis` instance.
  774. *
  775. * @attribute xKey
  776. * @type String
  777. */
  778. xKey: {
  779. setter: function(val)
  780. {
  781. if(Y_Lang.isArray(val))
  782. {
  783. return val;
  784. }
  785. else
  786. {
  787. return val.toString();
  788. }
  789. }
  790. },
  791. /**
  792. * Indicates which array to from the hash of value arrays in
  793. * the y-axis `Axis` instance.
  794. *
  795. * @attribute yKey
  796. * @type String
  797. */
  798. yKey: {
  799. setter: function(val)
  800. {
  801. if(Y_Lang.isArray(val))
  802. {
  803. return val;
  804. }
  805. else
  806. {
  807. return val.toString();
  808. }
  809. }
  810. },
  811. /**
  812. * Array of x values for the series.
  813. *
  814. * @attribute xData
  815. * @type Array
  816. */
  817. xData: {},
  818. /**
  819. * Array of y values for the series.
  820. *
  821. * @attribute yData
  822. * @type Array
  823. */
  824. yData: {},
  825. /**
  826. * Collection of area maps along the xAxis. Used to determine mouseover for multiple
  827. * series.
  828. *
  829. * @attribute xMarkerPlane
  830. * @type Array
  831. */
  832. xMarkerPlane: {},
  833. /**
  834. * Collection of area maps along the yAxis. Used to determine mouseover for multiple
  835. * series.
  836. *
  837. * @attribute yMarkerPlane
  838. * @type Array
  839. */
  840. yMarkerPlane: {},
  841. /**
  842. * Distance from a data coordinate to the left/right for setting a hotspot.
  843. *
  844. * @attribute xMarkerPlaneOffset
  845. * @type Number
  846. */
  847. xMarkerPlaneOffset: {
  848. getter: function() {
  849. var marker = this.get("styles").marker;
  850. if(marker && marker.width && isFinite(marker.width))
  851. {
  852. return marker.width * 0.5;
  853. }
  854. return this._defaultPlaneOffset;
  855. }
  856. },
  857. /**
  858. * Distance from a data coordinate to the top/bottom for setting a hotspot.
  859. *
  860. * @attribute yMarkerPlaneOffset
  861. * @type Number
  862. */
  863. yMarkerPlaneOffset: {
  864. getter: function() {
  865. var marker = this.get("styles").marker;
  866. if(marker && marker.height && isFinite(marker.height))
  867. {
  868. return marker.height * 0.5;
  869. }
  870. return this._defaultPlaneOffset;
  871. }
  872. },
  873. /**
  874. * Direction of the series
  875. *
  876. * @attribute direction
  877. * @type String
  878. */
  879. direction: {
  880. value: "horizontal"
  881. }
  882. }
  883. });