- /**
- * The PieChart class creates a pie chart
- *
- * @class PieChart
- * @extends ChartBase
- * @constructor
- * @submodule charts-base
- */
- Y.PieChart = Y.Base.create("pieChart", Y.Widget, [Y.ChartBase], {
- /**
- * Calculates and returns a `seriesCollection`.
- *
- * @method _getSeriesCollection
- * @return Array
- * @private
- */
- _getSeriesCollection: function()
- {
- if(this._seriesCollection)
- {
- return this._seriesCollection;
- }
- var axes = this.get("axes"),
- sc = [],
- seriesKeys,
- i = 0,
- l,
- type = this.get("type"),
- key,
- catAxis = "categoryAxis",
- catKey = "categoryKey",
- valAxis = "valueAxis",
- seriesKey = "valueKey";
- if(axes)
- {
- seriesKeys = axes.values.get("keyCollection");
- key = axes.category.get("keyCollection")[0];
- l = seriesKeys.length;
- for(; i < l; ++i)
- {
- sc[i] = {type:type};
- sc[i][catAxis] = "category";
- sc[i][valAxis] = "values";
- sc[i][catKey] = key;
- sc[i][seriesKey] = seriesKeys[i];
- }
- }
- this._seriesCollection = sc;
- return sc;
- },
-
- /**
- * Creates `Axis` instances.
- *
- * @method _parseAxes
- * @param {Object} val Object containing `Axis` instances or objects in which to construct `Axis` instances.
- * @return Object
- * @private
- */
- _parseAxes: function(hash)
- {
- if(!this._axes)
- {
- this._axes = {};
- }
- var i, pos, axis, dh, config, AxisClass,
- type = this.get("type"),
- w = this.get("width"),
- h = this.get("height"),
- node = Y.Node.one(this._parentNode);
- if(!w)
- {
- this.set("width", node.get("offsetWidth"));
- w = this.get("width");
- }
- if(!h)
- {
- this.set("height", node.get("offsetHeight"));
- h = this.get("height");
- }
- for(i in hash)
- {
- if(hash.hasOwnProperty(i))
- {
- dh = hash[i];
- pos = type === "pie" ? "none" : dh.position;
- AxisClass = this._getAxisClass(dh.type);
- config = {dataProvider:this.get("dataProvider")};
- if(dh.hasOwnProperty("roundingUnit"))
- {
- config.roundingUnit = dh.roundingUnit;
- }
- config.keys = dh.keys;
- config.width = w;
- config.height = h;
- config.position = pos;
- config.styles = dh.styles;
- axis = new AxisClass(config);
- axis.on("axisRendered", Y.bind(this._itemRendered, this));
- this._axes[i] = axis;
- }
- }
- },
-
- /**
- * Adds axes to the chart.
- *
- * @method _addAxes
- * @private
- */
- _addAxes: function()
- {
- var axes = this.get("axes"),
- i,
- axis,
- p;
- if(!axes)
- {
- this.set("axes", this._getDefaultAxes());
- axes = this.get("axes");
- }
- if(!this._axesCollection)
- {
- this._axesCollection = [];
- }
- for(i in axes)
- {
- if(axes.hasOwnProperty(i))
- {
- axis = axes[i];
- p = axis.get("position");
- if(!this.get(p + "AxesCollection"))
- {
- this.set(p + "AxesCollection", [axis]);
- }
- else
- {
- this.get(p + "AxesCollection").push(axis);
- }
- this._axesCollection.push(axis);
- }
- }
- },
-
- /**
- * Renders the Graph.
- *
- * @method _addSeries
- * @private
- */
- _addSeries: function()
- {
- var graph = this.get("graph"),
- seriesCollection = this.get("seriesCollection");
- this._parseSeriesAxes(seriesCollection);
- graph.set("showBackground", false);
- graph.set("width", this.get("width"));
- graph.set("height", this.get("height"));
- graph.set("seriesCollection", seriesCollection);
- this._seriesCollection = graph.get("seriesCollection");
- graph.render(this.get("contentBox"));
- },
-
- /**
- * Parse and sets the axes for the chart.
- *
- * @method _parseSeriesAxes
- * @param {Array} c A collection `PieSeries` instance.
- * @private
- */
- _parseSeriesAxes: function(c)
- {
- var i = 0,
- len = c.length,
- s,
- axes = this.get("axes"),
- axis;
- for(; i < len; ++i)
- {
- s = c[i];
- if(s)
- {
- //If series is an actual series instance,
- //replace axes attribute string ids with axes
- if(s instanceof Y.PieSeries)
- {
- axis = s.get("categoryAxis");
- if(axis && !(axis instanceof Y.Axis))
- {
- s.set("categoryAxis", axes[axis]);
- }
- axis = s.get("valueAxis");
- if(axis && !(axis instanceof Y.Axis))
- {
- s.set("valueAxis", axes[axis]);
- }
- continue;
- }
- s.categoryAxis = axes.category;
- s.valueAxis = axes.values;
- if(!s.type)
- {
- s.type = this.get("type");
- }
- }
- }
- },
-
- /**
- * Generates and returns a key-indexed object containing `Axis` instances or objects used to create `Axis` instances.
- *
- * @method _getDefaultAxes
- * @return Object
- * @private
- */
- _getDefaultAxes: function()
- {
- var catKey = this.get("categoryKey"),
- seriesKeys = this.get("seriesKeys").concat(),
- seriesAxis = "numeric";
- return {
- values:{
- keys:seriesKeys,
- type:seriesAxis
- },
- category:{
- keys:[catKey],
- type:this.get("categoryType")
- }
- };
- },
-
- /**
- * Returns an object literal containing a categoryItem and a valueItem for a given series index.
- *
- * @method getSeriesItem
- * @param series Reference to a series.
- * @param index Index of the specified item within a series.
- * @return Object
- */
- getSeriesItems: function(series, index)
- {
- var categoryItem = {
- axis: series.get("categoryAxis"),
- key: series.get("categoryKey"),
- displayName: series.get("categoryDisplayName")
- },
- valueItem = {
- axis: series.get("valueAxis"),
- key: series.get("valueKey"),
- displayName: series.get("valueDisplayName")
- };
- categoryItem.value = categoryItem.axis.getKeyValueAt(categoryItem.key, index);
- valueItem.value = valueItem.axis.getKeyValueAt(valueItem.key, index);
- return {category:categoryItem, value:valueItem};
- },
-
- /**
- * Handler for sizeChanged event.
- *
- * @method _sizeChanged
- * @param {Object} e Event object.
- * @private
- */
- _sizeChanged: function()
- {
- this._redraw();
- },
-
- /**
- * Redraws the chart instance.
- *
- * @method _redraw
- * @private
- */
- _redraw: function()
- {
- var graph = this.get("graph"),
- w = this.get("width"),
- h = this.get("height"),
- dimension;
- if(graph)
- {
- dimension = Math.min(w, h);
- graph.set("width", dimension);
- graph.set("height", dimension);
- }
- },
-
- /**
- * Formats tooltip text for a pie chart.
- *
- * @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 `PieSeries` instance of the item.
- * @return {HTML}
- * @private
- */
- _tooltipLabelFunction: function(categoryItem, valueItem, itemIndex, series)
- {
- var msg = DOCUMENT.createElement("div"),
- total = series.getTotalValues(),
- pct = Math.round((valueItem.value / total) * 10000)/100;
- 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")])));
- msg.appendChild(DOCUMENT.createElement("br"));
- msg.appendChild(DOCUMENT.createTextNode(pct + "%"));
- return msg;
- },
-
- /**
- * Returns the appropriate message based on the key press.
- *
- * @method _getAriaMessage
- * @param {Number} key The keycode that was pressed.
- * @return String
- */
- _getAriaMessage: function(key)
- {
- var msg = "",
- categoryItem,
- items,
- series,
- valueItem,
- seriesIndex = 0,
- itemIndex = this._itemIndex,
- len,
- total,
- pct,
- markers;
- series = this.getSeries(parseInt(seriesIndex, 10));
- markers = series.get("markers");
- len = markers && markers.length ? markers.length : 0;
- if(key === 37)
- {
- itemIndex = itemIndex > 0 ? itemIndex - 1 : len - 1;
- }
- else if(key === 39)
- {
- itemIndex = itemIndex >= len - 1 ? 0 : itemIndex + 1;
- }
- this._itemIndex = itemIndex;
- items = this.getSeriesItems(series, itemIndex);
- categoryItem = items.category;
- valueItem = items.value;
- total = series.getTotalValues();
- pct = Math.round((valueItem.value / total) * 10000)/100;
- if(categoryItem && valueItem)
- {
- msg += categoryItem.displayName +
- ": " +
- categoryItem.axis.formatLabel.apply(this, [categoryItem.value, categoryItem.axis.get("labelFormat")]) +
- ", ";
- msg += valueItem.displayName +
- ": " + valueItem.axis.formatLabel.apply(this, [valueItem.value, valueItem.axis.get("labelFormat")]) +
- ", ";
- msg += "Percent of total " + valueItem.displayName + ": " + pct + "%,";
- }
- else
- {
- msg += "No data available,";
- }
- msg += (itemIndex + 1) + " of " + len + ". ";
- return msg;
- }
- }, {
- ATTRS: {
- /**
- * Sets the aria description for the chart.
- *
- * @attribute ariaDescription
- * @type String
- */
- ariaDescription: {
- value: "Use the left and right keys to navigate through items.",
-
- setter: function(val)
- {
- if(this._description)
- {
- this._description.setContent("");
- this._description.appendChild(DOCUMENT.createTextNode(val));
- }
- return val;
- }
- },
-
- /**
- * Axes to appear in the chart.
- *
- * @attribute axes
- * @type Object
- */
- axes: {
- getter: function()
- {
- return this._axes;
- },
-
- setter: function(val)
- {
- this._parseAxes(val);
- }
- },
-
- /**
- * Collection of series to appear on the chart. This can be an array of Series instances or object literals
- * used to describe a Series instance.
- *
- * @attribute seriesCollection
- * @type Array
- */
- seriesCollection: {
- lazyAdd: false,
-
- getter: function()
- {
- return this._getSeriesCollection();
- },
-
- setter: function(val)
- {
- return this._setSeriesCollection(val);
- }
- },
-
- /**
- * Type of chart when there is no series collection specified.
- *
- * @attribute type
- * @type String
- */
- type: {
- value: "pie"
- }
- }
- });
-
-