PieChart.js revision 8209f3939e32e0e5bde64192267fdaf9db6f4fbc
/**
* The PieChart class creates a pie chart
*
* @class PieChart
* @extends ChartBase
* @constructor
*/
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._axisRendered, 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") || [],
seriesAxis = "numeric",
i,
dv = this.get("dataProvider")[0];
if(seriesKeys.length < 1)
{
for(i in dv)
{
if(i != catKey)
{
seriesKeys.push(i);
}
}
if(seriesKeys.length > 0)
{
this.set("seriesKeys", seriesKeys);
}
}
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(e)
{
this._redraw();
},
/**
* Redraws the chart instance.
*
* @method _redraw
* @private
*/
_redraw: function()
{
var graph = this.get("graph");
if(graph)
{
graph.set("width", this.get("width"));
graph.set("height", this.get("height"));
}
}
}, {
ATTRS: {
/**
* 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: {
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"
}
}
});