PieSeries.js revision c6624d55071139dbc6ebd4252f6c7ee46a5800a9
Y.PieSeries = Y.Base.create("pieSeries", Y.MarkerSeries, [], {
/**
* @private
*/
_categoryDisplayName: null,
/**
* @private
*/
_valueDisplayName: null,
/**
* @private
*/
addListeners: function()
{
var categoryAxis = this.get("categoryAxis"),
valueAxis = this.get("valueAxis");
if(categoryAxis)
{
categoryAxis.after("dataReady", Y.bind(this._categoryDataChangeHandler, this));
categoryAxis.after("dataUpdate", Y.bind(this._categoryDataChangeHandler, this));
}
if(valueAxis)
{
valueAxis.after("dataReady", Y.bind(this._valueDataChangeHandler, this));
valueAxis.after("dataUpdate", Y.bind(this._valueDataChangeHandler, this));
}
this.after("categoryAxisChange", this.categoryAxisChangeHandler);
this.after("valueAxisChange", this.valueAxisChangeHandler);
this.after("stylesChange", this._updateHandler);
},
validate: function()
{
this.draw();
this._renderered = true;
},
_categoryAxisChangeHandler: function(e)
{
var categoryAxis = this.get("categoryAxis");
categoryAxis.after("dataReady", Y.bind(this._categoryDataChangeHandler, this));
categoryAxis.after("dataUpdate", Y.bind(this._categoryDataChangeHandler, this));
},
_valueAxisChangeHandler: function(e)
{
var valueAxis = this.get("valueAxis");
valueAxis.after("dataReady", Y.bind(this._valueDataChangeHandler, this));
valueAxis.after("dataUpdate", Y.bind(this._valueDataChangeHandler, this));
},
/**
* Constant used to generate unique id.
*/
GUID: "pieseries",
/**
* @private (protected)
* Handles updating the graph when the x < code>Axis</code> values
* change.
*/
_categoryDataChangeHandler: function(event)
{
if(this._rendered && this.get("categoryKey") && this.get("valueKey"))
{
this.draw();
}
},
/**
* @private (protected)
* Handles updating the chart when the y <code>Axis</code> values
* change.
*/
_valueDataChangeHandler: function(event)
{
if(this._rendered && this.get("categoryKey") && this.get("valueKey"))
{
this.draw();
}
},
/**
* @private (override)
*/
draw: function()
{
var graph = this.get("graph"),
w = graph.get("width"),
h = graph.get("height");
if(isFinite(w) && isFinite(h) && w > 0 && h > 0)
{
this._rendered = true;
this.drawSeries();
this.fire("drawingComplete");
}
},
/**
* @private
*/
drawPlots: function()
{
var values = this.get("valueAxis").getDataByKey(this.get("valueKey")).concat(),
catValues = this.get("categoryAxis").getDataByKey(this.get("categoryKey")).concat(),
totalValue = 0,
itemCount = values.length,
styles = this.get("styles").marker,
fillColors = styles.fill.colors,
fillAlphas = styles.fill.alphas || ["1"],
borderColors = styles.border.colors,
borderWeights = [styles.border.weight],
borderAlphas = [styles.border.alpha],
tbw = borderWeights.concat(),
tbc = borderColors.concat(),
tba = borderAlphas.concat(),
tfc,
tfa,
padding = styles.padding,
graph = this.get("graph"),
w = graph.get("width") - (padding.left + padding.right),
h = graph.get("height") - (padding.top + padding.bottom),
startAngle = -90,
halfWidth = w / 2,
halfHeight = h / 2,
radius = Math.min(halfWidth, halfHeight),
i = 0,
value,
angle = 0,
lc,
la,
lw,
wedgeStyle,
marker,
graphOrder = this.get("graphOrder"),
mnode;
for(; i < itemCount; ++i)
{
value = values[i];
values.push(value);
if(!isNaN(value))
{
totalValue += value;
}
}
tfc = fillColors ? fillColors.concat() : null;
tfa = fillAlphas ? fillAlphas.concat() : null;
this._createMarkerCache();
for(i = 0; i < itemCount; i++)
{
value = values[i];
if(totalValue === 0)
{
angle = 360 / values.length;
}
else
{
angle = 360 * (value / totalValue);
}
angle = Math.round(angle);
if(tfc && tfc.length < 1)
{
tfc = fillColors.concat();
}
if(tfa && tfa.length < 1)
{
tfa = fillAlphas.concat();
}
if(tbw && tbw.length < 1)
{
tbw = borderWeights.concat();
}
if(tbw && tbc.length < 1)
{
tbc = borderColors.concat();
}
if(tba && tba.length < 1)
{
tba = borderAlphas.concat();
}
lw = tbw ? tbw.shift() : null;
lc = tbc ? tbc.shift() : null;
la = tba ? tba.shift() : null;
startAngle += angle;
wedgeStyle = {
border: {
color:lc,
weight:lw,
alpha:la
},
fill: {
color:tfc ? tfc.shift() : this._getDefaultColor(i, "slice"),
alpha:tfa ? tfa.shift() : null
},
shape: "wedge",
props: {
arc: angle,
radius: radius,
startAngle: startAngle,
x: halfWidth,
y: halfHeight
},
width: w,
height: h
};
marker = this.getMarker(wedgeStyle, graphOrder, i);
mnode = Y.one(marker.parent);
}
this._clearMarkerCache();
},
updateMarkerState: function(type, i)
{
if(this._markers[i])
{
var state = this._getState(type),
markerStyles,
indexStyles,
marker = this._markers[i],
graphicNode = this._graphicNodes[i],
styles = this.get("styles").marker;
markerStyles = state == "off" || !styles[state] ? styles : styles[state];
indexStyles = this._mergeStyles(markerStyles, {});
indexStyles.fill.color = indexStyles.fill.colors[i % indexStyles.fill.colors.length];
indexStyles.fill.alpha = indexStyles.fill.alphas[i % indexStyles.fill.alphas.length];
marker.update(indexStyles);
if(state == "over" || state == "down")
{
Y.one(graphicNode).setStyle("zIndex", 3);
}
else
{
Y.one(graphicNode).setStyle("zIndex", 2);
}
}
},
/**
* @private
*/
_createMarker: function(styles, order, index)
{
var graphic = this.get("graphic"),
cfg = Y.clone(styles),
marker = graphic.getShape(cfg);
marker.addClass("yui3-seriesmarker");
marker.node.setAttribute("id", "series_" + order + "_" + index);
return marker;
},
/**
* @private
*/
_clearMarkerCache: function()
{
var len = this._markerCache.length,
i = 0,
marker;
for(; i < len; ++i)
{
marker = this._markerCache[i];
if(marker && marker.node && marker.parentNode)
{
marker.parentNode.removeChild(marker.node);
}
}
this._markerCache = [];
},
/**
* @private
*/
_getPlotDefaults: function()
{
var defs = {
padding:{
top: 0,
left: 0,
right: 0,
bottom: 0
},
fill:{
alphas:["1"]
},
border: {
weight: 0,
alpha: 1
}
};
defs.fill.colors = this._defaultSliceColors;
defs.border.colors = this._defaultBorderColors;
return defs;
},
/**
* @private
*/
_defaultLineColors:["#426ab3", "#d09b2c", "#000000", "#b82837", "#b384b5", "#ff7200", "#779de3", "#cbc8ba", "#7ed7a6", "#007a6c"],
/**
* @private
*/
_defaultFillColors:["#6084d0", "#eeb647", "#6c6b5f", "#d6484f", "#ce9ed1", "#ff9f3b", "#93b7ff", "#e0ddd0", "#94ecba", "#309687"],
/**
* @private
*/
_defaultBorderColors:["#205096", "#b38206", "#000000", "#94001e", "#9d6fa0", "#e55b00", "#5e85c9", "#adab9e", "#6ac291", "#006457"],
/**
* @private
*/
_defaultSliceColors: ["#66007f", "#a86f41", "#295454", "#996ab2", "#e8cdb7", "#90bdbd","#000000","#c3b8ca", "#968373", "#678585"],
/**
* @private
* @description Colors used if style colors are not specified
*/
_getDefaultColor: function(index, type)
{
var colors = {
line: this._defaultLineColors,
fill: this._defaultFillColors,
border: this._defaultBorderColors,
slice: this._defaultSliceColors
},
col = colors[type],
l = col.length;
index = index || 0;
if(index >= l)
{
index = index % l;
}
type = type || "fill";
return colors[type][index];
}
}, {
ATTRS: {
type: {
value: "pie"
},
/**
* Order of this ISeries instance of this <code>type</code>.
*/
order: {},
graph: {},
/**
* Reference to the <code>Axis</code> instance used for assigning
* x-values to the graph.
*/
categoryAxis: {
value: null,
validator: function(value)
{
return value !== this.get("categoryAxis");
}
},
valueAxis: {
value: null,
validator: function(value)
{
return value !== this.get("valueAxis");
}
},
/**
* Indicates which array to from the hash of value arrays in
* the category <code>Axis</code> instance.
*/
categoryKey: {
value: null,
validator: function(value)
{
return value !== this.get("categoryKey");
}
},
/**
* Indicates which array to from the hash of value arrays in
* the value <code>Axis</code> instance.
*/
valueKey: {
value: null,
validator: function(value)
{
return value !== this.get("valueKey");
}
},
categoryDisplayName: {
setter: function(val)
{
this._categoryDisplayName = val;
return val;
},
getter: function()
{
return this._categoryDisplayName || this.get("categoryKey");
}
},
valueDisplayName: {
setter: function(val)
{
this._valueDisplayName = val;
return val;
},
getter: function()
{
return this._valueDisplayName || this.get("valueKey");
}
},
slices: null
}
});