ChartBase.js revision 97a5407d7fca2fea1fb9c9e7a7cc06183bc1c839
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore/**
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * The ChartBase class is an abstract class used to create charts.
b39897a381c2203466da5568bfd2862a54a81311Adam Moore *
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * @module charts
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore * @class ChartBase
2c5ce90c334a2d0f18474e85c93b424b6ec9daaaAdam Moore * @constructor
4778ff543a041ac356d6e661cc9b66c3fafa2092Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moorefunction ChartBase() {}
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam MooreChartBase.ATTRS = {
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore /**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * Reference to the default tooltip available for the chart.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * <p>Contains the following properties:</p>
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * <dl>
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * <dt>node</dt><dd>Reference to the actual dom node</dd>
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * <dt>showEvent</dt><dd>Event that should trigger the tooltip</dd>
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * <dt>hideEvent</dt><dd>Event that should trigger the removal of a tooltip (can be an event or an array of events)</dd>
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * <dt>styles</dt><dd>A hash of style properties that will be applied to the tooltip node</dd>
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * <dt>show</dt><dd>Indicates whether or not to show the tooltip</dd>
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * <dt>markerEventHandler</dt><dd>Displays and hides tooltip based on marker events</dd>
173310d032abe522e8645dd148cc28591cd128eaAdam Moore * <dt>planarEventHandler</dt><dd>Displays and hides tooltip based on planar events</dd>
173310d032abe522e8645dd148cc28591cd128eaAdam Moore * <dt>markerLabelFunction</dt><dd>Reference to the function used to format a marker event triggered tooltip's text. The method contains
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * the following arguments:
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * <dl>
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * <dt>categoryItem</dt><dd>An object containing the following:
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * <dl>
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * <dt>axis</dt><dd>The axis to which the category is bound.</dd>
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * <dt>displayName</dt><dd>The display name set to the category (defaults to key if not provided).</dd>
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * <dt>key</dt><dd>The key of the category.</dd>
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * <dt>value</dt><dd>The value of the category.</dd>
173310d032abe522e8645dd148cc28591cd128eaAdam Moore * </dl>
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * </dd>
16bec62f211cecacdbbc2cb4632f079ef8c7f936Adam Moore * <dt>valueItem</dt><dd>An object containing the following:
c7eb563867fa29409073f3b495a067d9afa00006Adam Moore * <dl>
c74cf2305e301535acc8a5d42be60e93dcbd97daAdam Moore * <dt>axis</dt><dd>The axis to which the item's series is bound.</dd>
16bec62f211cecacdbbc2cb4632f079ef8c7f936Adam Moore * <dt>displayName</dt><dd>The display name of the series. (defaults to key if not provided)</dd>
16bec62f211cecacdbbc2cb4632f079ef8c7f936Adam Moore * <dt>key</dt><dd>The key for the series.</dd>
0bc189b2acbd7c4b5af63eded0c4289e224676b7Adam Moore * <dt>value</dt><dd>The value for the series item.</dd>
9fb523cf517ad4d6a53ae9f461d672cba63835d2Adam Moore * </dl>
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * </dd>
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * <dt>itemIndex</dt><dd>The index of the item within the series.</dd>
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * <dt>series</dt><dd> The `CartesianSeries` instance of the item.</dd>
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * <dt>seriesIndex</dt><dd>The index of the series in the `seriesCollection`.</dd>
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * </dl>
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * The method returns an `HTMLElement` which is written into the DOM using `appendChild`. If you override this method and choose to return an html string, you
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * will also need to override the tooltip's `setTextFunction` method to accept an html string.
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * </dd>
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * <dt>planarLabelFunction</dt><dd>Reference to the function used to format a planar event triggered tooltip's text
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * <dl>
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * <dt>categoryAxis</dt><dd> `CategoryAxis` Reference to the categoryAxis of the chart.
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * <dt>valueItems</dt><dd>Array of objects for each series that has a data point in the coordinate plane of the event. Each object contains the following data:
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * <dl>
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * <dt>axis</dt><dd>The value axis of the series.</dd>
489c0c8e2523f1bcd1acee1173c6d85f6a7edd6aAdam Moore * <dt>key</dt><dd>The key for the series.</dd>
4390434761f176b0f8d7a71c00a6e0141aa1752cAdam Moore * <dt>value</dt><dd>The value for the series item.</dd>
4390434761f176b0f8d7a71c00a6e0141aa1752cAdam Moore * <dt>displayName</dt><dd>The display name of the series. (defaults to key if not provided)</dd>
4390434761f176b0f8d7a71c00a6e0141aa1752cAdam Moore * </dl>
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * </dd>
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * <dt>index</dt><dd>The index of the item within its series.</dd>
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * <dt>seriesArray</dt><dd>Array of series instances for each value item.</dd>
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * <dt>seriesIndex</dt><dd>The index of the series in the `seriesCollection`.</dd>
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * </dl>
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * </dd>
91ff24e65531ce8bf171340d9384182f8c168af3Adam Moore * </dl>
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * The method returns an `HTMLElement` which is written into the DOM using `appendChild`. If you override this method and choose to return an html string, you
173310d032abe522e8645dd148cc28591cd128eaAdam Moore * will also need to override the tooltip's `setTextFunction` method to accept an html string.
173310d032abe522e8645dd148cc28591cd128eaAdam Moore * </dd>
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * <dt>setTextFunction</dt><dd>Method that writes content returned from `planarLabelFunction` or `markerLabelFunction` into the the tooltip node.
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * has the following signature:
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * <dl>
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * <dt>label</dt><dd>The `HTMLElement` that the content is to be added.</dd>
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * <dt>val</dt><dd>The content to be rendered into tooltip. This can be a `String` or `HTMLElement`. If an HTML string is used, it will be rendered as a
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * string.</dd>
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * </dl>
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * </dd>
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * </dl>
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * @attribute tooltip
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * @type Object
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore */
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore tooltip: {
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore valueFn: "_getTooltip",
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore setter: function(val)
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore {
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore return this._updateTooltip(val);
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore }
b39897a381c2203466da5568bfd2862a54a81311Adam Moore },
b39897a381c2203466da5568bfd2862a54a81311Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore /**
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * The key value used for the chart's category axis.
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore *
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * @attribute categoryKey
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * @type String
458ca79ae0e4fa1eb1a2a3c6f67401a191d025e4Adam Moore * @default category
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore */
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore categoryKey: {
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore value: "category"
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore },
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore /**
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * Indicates the type of axis to use for the category axis.
b39897a381c2203466da5568bfd2862a54a81311Adam Moore *
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * <dl>
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * <dt>category</dt><dd>Specifies a `CategoryAxis`.</dd>
13a50a8c4ecfe16d42abb7605f9451f76e02dc42Adam Moore * <dt>time</dt><dd>Specifies a `TimeAxis</dd>
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * </dl>
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore *
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @attribute categoryType
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @type String
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @default category
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore */
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore categoryType:{
b39897a381c2203466da5568bfd2862a54a81311Adam Moore value:"category"
b39897a381c2203466da5568bfd2862a54a81311Adam Moore },
b39897a381c2203466da5568bfd2862a54a81311Adam Moore
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore /**
16bec62f211cecacdbbc2cb4632f079ef8c7f936Adam Moore * Indicates the the type of interactions that will fire events.
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore *
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * <dl>
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * <dt>marker</dt><dd>Events will be broadcasted when the mouse interacts with individual markers.</dd>
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * <dt>planar</dt><dd>Events will be broadcasted when the mouse intersects the plane of any markers on the chart.</dd>
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * <dt>none</dt><dd>No events will be broadcasted.</dd>
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * </dl>
b39897a381c2203466da5568bfd2862a54a81311Adam Moore *
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @attribute interactionType
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @type String
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore * @default marker
d4dbc3afb5bb9cfd13490b358dc37bf951104ca7Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore interactionType: {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore value: "marker"
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore },
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore /**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * Data used to generate the chart.
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore *
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * @attribute dataProvider
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * @type Array
b39897a381c2203466da5568bfd2862a54a81311Adam Moore */
b39897a381c2203466da5568bfd2862a54a81311Adam Moore dataProvider: {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore setter: function(val)
16bec62f211cecacdbbc2cb4632f079ef8c7f936Adam Moore {
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore return this._setDataValues(val);
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore }
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore },
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
2e3359c809b56e9d1c663465eaf85d1a4c03bf4cAdam Moore /**
87d6b0a14cce52c4faa4b78fc9878eb553dab0d5Adam Moore * A collection of keys that map to the series axes. If no keys are set,
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * they will be generated automatically depending on the data structure passed into
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * the chart.
b39897a381c2203466da5568bfd2862a54a81311Adam Moore *
efa57736d44cf446f1661497a8645bd388b493fbAdam Moore * @attribute seriesKeys
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * @type Array
b39897a381c2203466da5568bfd2862a54a81311Adam Moore */
b39897a381c2203466da5568bfd2862a54a81311Adam Moore seriesKeys: {},
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
b39897a381c2203466da5568bfd2862a54a81311Adam Moore /**
ba2701ee03e94104edf19911ee0989f8cee11088Adam Moore * Reference to all the axes in the chart.
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore *
ba2701ee03e94104edf19911ee0989f8cee11088Adam Moore * @attribute axesCollection
489c0c8e2523f1bcd1acee1173c6d85f6a7edd6aAdam Moore * @type Array
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore */
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore axesCollection: {},
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore /**
1b298c6f0ef597aa4ab0b8bcb25430b6c9a87749Adam Moore * Reference to graph instance.
c4e6d94ea429e473a6732b6eb5e0fc980e822881Adam Moore *
7cd8fe832d4f91bed468c7498ff957c446f90aaaAdam Moore * @attribute graph
23209f57fce338501bc1dc828a991d103732b92fAdam Moore * @type Graph
23209f57fce338501bc1dc828a991d103732b92fAdam Moore */
23209f57fce338501bc1dc828a991d103732b92fAdam Moore graph: {
23209f57fce338501bc1dc828a991d103732b92fAdam Moore valueFn: "_getGraph"
23209f57fce338501bc1dc828a991d103732b92fAdam Moore },
23209f57fce338501bc1dc828a991d103732b92fAdam Moore
b39897a381c2203466da5568bfd2862a54a81311Adam Moore /**
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * Indicates whether or not markers for a series will be grouped and rendered in a single complex shape instance.
23209f57fce338501bc1dc828a991d103732b92fAdam Moore *
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * @attribute groupMarkers
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * @type Boolean
b39897a381c2203466da5568bfd2862a54a81311Adam Moore */
b39897a381c2203466da5568bfd2862a54a81311Adam Moore groupMarkers: {
23209f57fce338501bc1dc828a991d103732b92fAdam Moore value: false,
b39897a381c2203466da5568bfd2862a54a81311Adam Moore
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore setter: function(val)
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore {
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore if(this.get("graph"))
489c0c8e2523f1bcd1acee1173c6d85f6a7edd6aAdam Moore {
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore this.get("graph").set("groupMarkers", val);
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore }
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore return val;
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore }
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore }
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore};
e0a1d83ad86620d8fd4e2bfa3c4ec5c0944a002aAdam Moore
23209f57fce338501bc1dc828a991d103732b92fAdam MooreChartBase.prototype = {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore /**
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * Default value function for the `Graph` attribute.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore *
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @method _getGraph
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @return Graph
02b581ebfa9969c32cac8cd44ebe35e0e47f00ceAdam Moore * @private
b39897a381c2203466da5568bfd2862a54a81311Adam Moore */
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore _getGraph: function()
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore {
0dca577a07715960da42d47787eecc25b285182fAdam Moore var graph = new Y.Graph({
b39897a381c2203466da5568bfd2862a54a81311Adam Moore chart:this,
0dca577a07715960da42d47787eecc25b285182fAdam Moore groupMarkers: this.get("groupMarkers")
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore });
b39897a381c2203466da5568bfd2862a54a81311Adam Moore graph.after("chartRendered", Y.bind(function(e) {
0dca577a07715960da42d47787eecc25b285182fAdam Moore this.fire("chartRendered");
0bc189b2acbd7c4b5af63eded0c4289e224676b7Adam Moore }, this));
0dca577a07715960da42d47787eecc25b285182fAdam Moore return graph;
0dca577a07715960da42d47787eecc25b285182fAdam Moore },
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore
b39897a381c2203466da5568bfd2862a54a81311Adam Moore /**
b9f576e4a859f38cf945d867cf23fdbb84347564Adam Moore * Returns a series instance by index or key value.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore *
0bc189b2acbd7c4b5af63eded0c4289e224676b7Adam Moore * @method getSeries
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @param val
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @return CartesianSeries
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore */
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore getSeries: function(val)
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore var series = null,
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore graph = this.get("graph");
b39897a381c2203466da5568bfd2862a54a81311Adam Moore if(graph)
b39897a381c2203466da5568bfd2862a54a81311Adam Moore {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore if(Y_Lang.isNumber(val))
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore series = graph.getSeriesByIndex(val);
02b581ebfa9969c32cac8cd44ebe35e0e47f00ceAdam Moore }
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore else
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore series = graph.getSeriesByKey(val);
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore }
b39897a381c2203466da5568bfd2862a54a81311Adam Moore }
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore return series;
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore },
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore
b39897a381c2203466da5568bfd2862a54a81311Adam Moore /**
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * Returns an `Axis` instance by key reference. If the axis was explicitly set through the `axes` attribute,
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * the key will be the same as the key used in the `axes` object. For default axes, the key for
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * the category axis is the value of the `categoryKey` (`category`). For the value axis, the default
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * key is `values`.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore *
0bc189b2acbd7c4b5af63eded0c4289e224676b7Adam Moore * @method getAxisByKey
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @param {String} val Key reference used to look up the axis.
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore * @return Axis
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore */
0bc189b2acbd7c4b5af63eded0c4289e224676b7Adam Moore getAxisByKey: function(val)
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore var axis,
0bc189b2acbd7c4b5af63eded0c4289e224676b7Adam Moore axes = this.get("axes");
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore if(axes && axes.hasOwnProperty(val))
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore {
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore axis = axes[val];
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore }
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore return axis;
3395e5fc071521d4e6b258ef4c7c0ef38601b94eAdam Moore },
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore /**
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore * Returns the category axis for the chart.
02b581ebfa9969c32cac8cd44ebe35e0e47f00ceAdam Moore *
b39897a381c2203466da5568bfd2862a54a81311Adam Moore * @method getCategoryAxis
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore * @return Axis
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore */
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore getCategoryAxis: function()
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore {
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore var axis,
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore key = this.get("categoryKey"),
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore axes = this.get("axes");
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore if(axes.hasOwnProperty(key))
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore {
8c3fae1cf2a8dfa82c53922a6f99ab7b991b959cAdam Moore axis = axes[key];
}
return axis;
},
/**
* Default direction of the chart.
*
* @property _direction
* @type String
* @default horizontal
* @private
*/
_direction: "horizontal",
/**
* Storage for the `dataProvider` attribute.
*
* @property _dataProvider
* @type Array
* @private
*/
_dataProvider: null,
/**
* Setter method for `dataProvider` attribute.
*
* @method _setDataValues
* @param {Array} val Array to be set as `dataProvider`.
* @return Array
* @private
*/
_setDataValues: function(val)
{
if(Y_Lang.isArray(val[0]))
{
var hash,
dp = [],
cats = val[0],
i = 0,
l = cats.length,
n,
sl = val.length;
for(; i < l; ++i)
{
hash = {category:cats[i]};
for(n = 1; n < sl; ++n)
{
hash["series" + n] = val[n][i];
}
dp[i] = hash;
}
return dp;
}
return val;
},
/**
* Storage for `seriesCollection` attribute.
*
* @property _seriesCollection
* @type Array
* @private
*/
_seriesCollection: null,
/**
* Setter method for `seriesCollection` attribute.
*
* @property _setSeriesCollection
* @param {Array} val Array of either `CartesianSeries` instances or objects containing series attribute key value pairs.
* @private
*/
_setSeriesCollection: function(val)
{
this._seriesCollection = val;
},
/**
* Helper method that returns the axis class that a key references.
*
* @method _getAxisClass
* @param {String} t The type of axis.
* @return Axis
* @private
*/
_getAxisClass: function(t)
{
return this._axisClass[t];
},
/**
* Key value pairs of axis types.
*
* @property _axisClass
* @type Object
* @private
*/
_axisClass: {
stacked: Y.StackedAxis,
numeric: Y.NumericAxis,
category: Y.CategoryAxis,
time: Y.TimeAxis
},
/**
* Collection of axes.
*
* @property _axes
* @type Array
* @private
*/
_axes: null,
/**
* @method initializer
* @private
*/
initializer: function()
{
this._axesRenderQueue = [];
this.after("dataProviderChange", this._dataProviderChangeHandler);
},
/**
* @method renderUI
* @private
*/
renderUI: function()
{
var tt = this.get("tooltip");
//move the position = absolute logic to a class file
this.get("boundingBox").setStyle("position", "absolute");
this.get("contentBox").setStyle("position", "absolute");
this._addAxes();
this._addSeries();
if(tt && tt.show)
{
this._addTooltip();
}
this._redraw();
},
/**
* @property bindUI
* @private
*/
bindUI: function()
{
this.after("tooltipChange", Y.bind(this._tooltipChangeHandler, this));
this.after("widthChange", this._sizeChanged);
this.after("heightChange", this._sizeChanged);
var tt = this.get("tooltip"),
hideEvent = "mouseout",
showEvent = "mouseover",
cb = this.get("contentBox"),
interactionType = this.get("interactionType"),
i = 0,
len,
markerClassName = "." + SERIES_MARKER;
if(interactionType == "marker")
{
hideEvent = tt.hideEvent;
showEvent = tt.showEvent;
Y.delegate("mouseenter", Y.bind(this._markerEventDispatcher, this), cb, markerClassName);
Y.delegate("mousedown", Y.bind(this._markerEventDispatcher, this), cb, markerClassName);
Y.delegate("mouseup", Y.bind(this._markerEventDispatcher, this), cb, markerClassName);
Y.delegate("mouseleave", Y.bind(this._markerEventDispatcher, this), cb, markerClassName);
Y.delegate("click", Y.bind(this._markerEventDispatcher, this), cb, markerClassName);
Y.delegate("mousemove", Y.bind(this._positionTooltip, this), cb, markerClassName);
}
else if(interactionType == "planar")
{
this._overlay.on("mousemove", Y.bind(this._planarEventDispatcher, this));
this.on("mouseout", this.hideTooltip);
}
if(tt)
{
if(hideEvent && showEvent && hideEvent == showEvent)
{
this.on(interactionType + "Event:" + hideEvent, this.toggleTooltip);
}
else
{
if(showEvent)
{
this.on(interactionType + "Event:" + showEvent, tt[interactionType + "EventHandler"]);
}
if(hideEvent)
{
if(Y_Lang.isArray(hideEvent))
{
len = hideEvent.length;
for(; i < len; ++i)
{
this.on(interactionType + "Event:" + hideEvent[i], this.hideTooltip);
}
}
this.on(interactionType + "Event:" + hideEvent, this.hideTooltip);
}
}
}
},
/**
* Event handler for marker events.
*
* @method _markerEventDispatcher
* @param {Object} e Event object.
* @private
*/
_markerEventDispatcher: function(e)
{
var type = e.type,
cb = this.get("contentBox"),
markerNode = e.currentTarget,
strArr = markerNode.getAttribute("id").split("_"),
index = strArr.pop(),
seriesIndex = strArr.pop(),
series = this.getSeries(parseInt(seriesIndex, 10)),
items = this.getSeriesItems(series, index),
pageX = e.pageX,
pageY = e.pageY,
x = pageX - cb.getX(),
y = pageY - cb.getY();
if(type == "mouseenter")
{
type = "mouseover";
}
else if(type == "mouseleave")
{
type = "mouseout";
}
series.updateMarkerState(type, index);
e.halt();
/**
* Broadcasts when `interactionType` is set to `marker` and a series marker has received a mouseover event.
*
*
* @event markerEvent:mouseover
* @preventable false
* @param {EventFacade} e Event facade with the following additional
* properties:
* <dl>
* <dt>categoryItem</dt><dd>Hash containing information about the category `Axis`.</dd>
* <dt>valueItem</dt><dd>Hash containing information about the value `Axis`.</dd>
* <dt>node</dt><dd>The dom node of the marker.</dd>
* <dt>x</dt><dd>The x-coordinate of the mouse in relation to the Chart.</dd>
* <dt>y</dt><dd>The y-coordinate of the mouse in relation to the Chart.</dd>
* <dt>series</dt><dd>Reference to the series of the marker.</dd>
* <dt>index</dt><dd>Index of the marker in the series.</dd>
* <dt>seriesIndex</dt><dd>The `order` of the marker's series.</dd>
* </dl>
*/
/**
* Broadcasts when `interactionType` is set to `marker` and a series marker has received a mouseout event.
*
* @event markerEvent:mouseout
* @preventable false
* @param {EventFacade} e Event facade with the following additional
* properties:
* <dl>
* <dt>categoryItem</dt><dd>Hash containing information about the category `Axis`.</dd>
* <dt>valueItem</dt><dd>Hash containing information about the value `Axis`.</dd>
* <dt>node</dt><dd>The dom node of the marker.</dd>
* <dt>x</dt><dd>The x-coordinate of the mouse in relation to the Chart.</dd>
* <dt>y</dt><dd>The y-coordinate of the mouse in relation to the Chart.</dd>
* <dt>series</dt><dd>Reference to the series of the marker.</dd>
* <dt>index</dt><dd>Index of the marker in the series.</dd>
* <dt>seriesIndex</dt><dd>The `order` of the marker's series.</dd>
* </dl>
*/
/**
* Broadcasts when `interactionType` is set to `marker` and a series marker has received a mousedown event.
*
* @event markerEvent:mousedown
* @preventable false
* @param {EventFacade} e Event facade with the following additional
* properties:
* <dl>
* <dt>categoryItem</dt><dd>Hash containing information about the category `Axis`.</dd>
* <dt>valueItem</dt><dd>Hash containing information about the value `Axis`.</dd>
* <dt>node</dt><dd>The dom node of the marker.</dd>
* <dt>x</dt><dd>The x-coordinate of the mouse in relation to the Chart.</dd>
* <dt>y</dt><dd>The y-coordinate of the mouse in relation to the Chart.</dd>
* <dt>series</dt><dd>Reference to the series of the marker.</dd>
* <dt>index</dt><dd>Index of the marker in the series.</dd>
* <dt>seriesIndex</dt><dd>The `order` of the marker's series.</dd>
* </dl>
*/
/**
* Broadcasts when `interactionType` is set to `marker` and a series marker has received a mouseup event.
*
* @event markerEvent:mouseup
* @preventable false
* @param {EventFacade} e Event facade with the following additional
* properties:
* <dl>
* <dt>categoryItem</dt><dd>Hash containing information about the category `Axis`.</dd>
* <dt>valueItem</dt><dd>Hash containing information about the value `Axis`.</dd>
* <dt>node</dt><dd>The dom node of the marker.</dd>
* <dt>x</dt><dd>The x-coordinate of the mouse in relation to the Chart.</dd>
* <dt>y</dt><dd>The y-coordinate of the mouse in relation to the Chart.</dd>
* <dt>series</dt><dd>Reference to the series of the marker.</dd>
* <dt>index</dt><dd>Index of the marker in the series.</dd>
* <dt>seriesIndex</dt><dd>The `order` of the marker's series.</dd>
* </dl>
*/
/**
* Broadcasts when `interactionType` is set to `marker` and a series marker has received a click event.
*
* @event markerEvent:click
* @preventable false
* @param {EventFacade} e Event facade with the following additional
* properties:
* <dl>
* <dt>categoryItem</dt><dd>Hash containing information about the category `Axis`.</dd>
* <dt>valueItem</dt><dd>Hash containing information about the value `Axis`.</dd>
* <dt>node</dt><dd>The dom node of the marker.</dd>
* <dt>x</dt><dd>The x-coordinate of the mouse in relation to the Chart.</dd>
* <dt>y</dt><dd>The y-coordinate of the mouse in relation to the Chart.</dd>
* <dt>pageX</dt><dd>The x location of the event on the page (including scroll)</dd>
* <dt>pageY</dt><dd>The y location of the event on the page (including scroll)</dd>
* <dt>series</dt><dd>Reference to the series of the marker.</dd>
* <dt>index</dt><dd>Index of the marker in the series.</dd>
* <dt>seriesIndex</dt><dd>The `order` of the marker's series.</dd>
* <dt>originEvent</dt><dd>Underlying dom event.</dd>
* </dl>
*/
this.fire("markerEvent:" + type, {
originEvent: e,
pageX:pageX,
pageY:pageY,
categoryItem:items.category,
valueItem:items.value,
node:markerNode,
x:x,
y:y,
series:series,
index:index,
seriesIndex:seriesIndex
});
},
/**
* Event handler for dataProviderChange.
*
* @method _dataProviderChangeHandler
* @param {Object} e Event object.
* @private
*/
_dataProviderChangeHandler: function(e)
{
var dataProvider = this.get("dataProvider"),
axes = this.get("axes"),
i,
axis;
if(axes)
{
for(i in axes)
{
if(axes.hasOwnProperty(i))
{
axis = axes[i];
if(axis instanceof Y.Axis)
{
axis.set("dataProvider", dataProvider);
}
}
}
}
},
/**
* Event listener for toggling the tooltip. If a tooltip is visible, hide it. If not, it
* will create and show a tooltip based on the event object.
*
* @method toggleTooltip
* @param {Object} e Event object.
*/
toggleTooltip: function(e)
{
var tt = this.get("tooltip");
if(tt.visible)
{
this.hideTooltip();
}
else
{
tt.markerEventHandler.apply(this, [e]);
}
},
/**
* Shows a tooltip
*
* @method _showTooltip
* @param {String} msg Message to dispaly in the tooltip.
* @param {Number} x x-coordinate
* @param {Number} y y-coordinate
* @private
*/
_showTooltip: function(msg, x, y)
{
var tt = this.get("tooltip"),
node = tt.node;
if(msg)
{
tt.visible = true;
tt.setTextFunction(node, msg);
node.setStyle("top", y + "px");
node.setStyle("left", x + "px");
node.setStyle("visibility", "visible");
}
},
/**
* Positions the tooltip
*
* @method _positionTooltip
* @param {Object} e Event object.
* @private
*/
_positionTooltip: function(e)
{
var tt = this.get("tooltip"),
node = tt.node,
cb = this.get("contentBox"),
x = (e.pageX + 10) - cb.getX(),
y = (e.pageY + 10) - cb.getY();
if(node)
{
node.setStyle("left", x + "px");
node.setStyle("top", y + "px");
}
},
/**
* Hides the default tooltip
*
* @method hideTooltip
*/
hideTooltip: function()
{
var tt = this.get("tooltip"),
node = tt.node;
tt.visible = false;
node.set("innerHTML", "");
node.setStyle("left", -10000);
node.setStyle("top", -10000);
node.setStyle("visibility", "hidden");
},
/**
* Adds a tooltip to the dom.
*
* @method _addTooltip
* @private
*/
_addTooltip: function()
{
var tt = this.get("tooltip"),
id = this.get("id") + "_tooltip",
cb = this.get("contentBox"),
oldNode = DOCUMENT.getElementById(id);
if(oldNode)
{
cb.removeChild(oldNode);
}
tt.node.setAttribute("id", id);
tt.node.setStyle("visibility", "hidden");
cb.appendChild(tt.node);
},
/**
* Updates the tooltip attribute.
*
* @method _updateTooltip
* @param {Object} val Object containing properties for the tooltip.
* @return Object
* @private
*/
_updateTooltip: function(val)
{
var tt = this._tooltip,
i,
styles,
node,
props = {
markerLabelFunction:"markerLabelFunction",
planarLabelFunction:"planarLabelFunction",
setTextFunction:"setTextFunction",
showEvent:"showEvent",
hideEvent:"hideEvent",
markerEventHandler:"markerEventHandler",
planarEventHandler:"planarEventHandler",
show:"show"
};
if(Y_Lang.isObject(val))
{
styles = val.styles;
node = Y.one(val.node) || tt.node;
if(styles)
{
for(i in styles)
{
if(styles.hasOwnProperty(i))
{
node.setStyle(i, styles[i]);
}
}
}
for(i in props)
{
if(val.hasOwnProperty(i))
{
tt[i] = val[i];
}
}
tt.node = node;
}
return tt;
},
/**
* Default getter for `tooltip` attribute.
*
* @method _getTooltip
* @return Object
* @private
*/
_getTooltip: function()
{
var node = DOCUMENT.createElement("div"),
tt = {
setTextFunction: this._setText,
markerLabelFunction: this._tooltipLabelFunction,
planarLabelFunction: this._planarLabelFunction,
show: true,
hideEvent: "mouseout",
showEvent: "mouseover",
markerEventHandler: function(e)
{
var tt = this.get("tooltip"),
msg = tt.markerLabelFunction.apply(this, [e.categoryItem, e.valueItem, e.index, e.series, e.seriesIndex]);
this._showTooltip(msg, e.x + 10, e.y + 10);
},
planarEventHandler: function(e)
{
var tt = this.get("tooltip"),
msg ,
categoryAxis = this.get("categoryAxis");
msg = tt.planarLabelFunction.apply(this, [categoryAxis, e.valueItem, e.index, e.items, e.seriesIndex]);
this._showTooltip(msg, e.x + 10, e.y + 10);
}
};
node.setAttribute("id", this.get("id") + "_tooltip");
node = Y.one(node);
node.setStyle("fontSize", "85%");
node.setStyle("opacity", "0.83");
node.setStyle("position", "absolute");
node.setStyle("paddingTop", "2px");
node.setStyle("paddingRight", "5px");
node.setStyle("paddingBottom", "4px");
node.setStyle("paddingLeft", "2px");
node.setStyle("backgroundColor", "#fff");
node.setStyle("border", "1px solid #dbdccc");
node.setStyle("pointerEvents", "none");
node.setStyle("zIndex", 3);
node.setStyle("whiteSpace", "noWrap");
node.setStyle("visibility", "hidden");
tt.node = Y.one(node);
this._tooltip = tt;
return tt;
},
/**
* Formats tooltip text when `interactionType` is `planar`.
*
* @method _planarLabelFunction
* @param {Axis} categoryAxis Reference to the categoryAxis of the chart.
* @param {Array} valueItems Array of objects for each series that has a data point in the coordinate plane of the event. Each object contains the following data:
* <dl>
* <dt>axis</dt><dd>The value axis of the series.</dd>
* <dt>key</dt><dd>The key for the series.</dd>
* <dt>value</dt><dd>The value for the series item.</dd>
* <dt>displayName</dt><dd>The display name of the series. (defaults to key if not provided)</dd>
* </dl>
* @param {Number} index The index of the item within its series.
* @param {Array} seriesArray Array of series instances for each value item.
* @param {Number} seriesIndex The index of the series in the `seriesCollection`.
* @return {String | HTML}
* @private
*/
_planarLabelFunction: function(categoryAxis, valueItems, index, seriesArray, seriesIndex)
{
var msg = DOCUMENT.createElement("div"),
valueItem,
i = 0,
len = seriesArray.length,
axis,
series;
if(categoryAxis)
{
msg.appendChild(DOCUMENT.createTextNode(categoryAxis.get("labelFunction").apply(this, [categoryAxis.getKeyValueAt(this.get("categoryKey"), index), categoryAxis.get("labelFormat")])));
}
for(; i < len; ++i)
{
series = seriesArray[i];
if(series.get("visible"))
{
valueItem = valueItems[i];
axis = valueItem.axis;
msg.appendChild(DOCUMENT.createElement("br"));
msg.appendChild(DOCUMENT.createTextNode(valueItem.displayName + ": " + axis.get("labelFunction").apply(this, [axis.getKeyValueAt(valueItem.key, index), axis.get("labelFormat")])));
}
}
return msg;
},
/**
* Formats tooltip text when `interactionType` is `marker`.
*
* @method _tooltipLabelFunction
* @param {Object} categoryItem An object containing the following:
* <dl>
* <dt>axis</dt><dd>The axis to which the category is bound.</dd>
* <dt>displayName</dt><dd>The display name set to the category (defaults to key if not provided)</dd>
* <dt>key</dt><dd>The key of the category.</dd>
* <dt>value</dt><dd>The value of the category</dd>
* </dl>
* @param {Object} valueItem An object containing the following:
* <dl>
* <dt>axis</dt><dd>The axis to which the item's series is bound.</dd>
* <dt>displayName</dt><dd>The display name of the series. (defaults to key if not provided)</dd>
* <dt>key</dt><dd>The key for the series.</dd>
* <dt>value</dt><dd>The value for the series item.</dd>
* </dl>
* @param {Number} itemIndex The index of the item within the series.
* @param {CartesianSeries} series The `CartesianSeries` instance of the item.
* @param {Number} seriesIndex The index of the series in the `seriesCollection`.
* @return {String | HTML}
* @private
*/
_tooltipLabelFunction: function(categoryItem, valueItem, itemIndex, series, seriesIndex)
{
var msg = DOCUMENT.createElement("div");
msg.appendChild(DOCUMENT.createTextNode(categoryItem.displayName +
": " + categoryItem.axis.get("labelFunction").apply(this, [categoryItem.value, categoryItem.axis.get("labelFormat")])));
msg.appendChild(DOCUMENT.createElement("br"));
msg.appendChild(DOCUMENT.createTextNode(valueItem.displayName +
": " + valueItem.axis.get("labelFunction").apply(this, [valueItem.value, valueItem.axis.get("labelFormat")])));
return msg;
},
/**
* Event handler for the tooltipChange.
*
* @method _tooltipChangeHandler
* @param {Object} e Event object.
* @private
*/
_tooltipChangeHandler: function(e)
{
if(this.get("tooltip"))
{
var tt = this.get("tooltip"),
node = tt.node,
show = tt.show,
cb = this.get("contentBox");
if(node && show)
{
if(!cb.contains(node))
{
this._addTooltip();
}
}
}
},
/**
* Updates the content of text field. This method writes a value into a text field using
* `appendChild`. If the value is a `String`, it is converted to a `TextNode` first.
*
* @method _setText
* @param label {HTMLElement} label to be updated
* @param val {String} value with which to update the label
* @private
*/
_setText: function(textField, val)
{
textField.setContent("");
if(IS_STRING(val))
{
val = DOCUMENT.createTextNode(val);
}
textField.appendChild(val);
}
};
Y.ChartBase = ChartBase;