CartesianChart.js revision a5057260e5538ddf2faca20fa81271eeff2bf892
/**
* The CartesianChart class creates a chart with horizontal and vertical axes.
*
* @class CartesianChart
* @extends ChartBase
* @constructor
*/
/**
* @private
*/
renderUI: function()
{
//move the position = absolute logic to a class file
this._addAxes();
this._addGridlines();
this._addSeries();
{
this._addTooltip();
}
//If there is a style definition. Force them to set.
this.get("styles");
{
}
this._redraw();
},
/**
* @private
*/
_planarEventDispatcher: function(e)
{
x = e.pageX,
y = e.pageY,
i = 0,
oldIndex = this._selectedIndex,
item,
items = [],
categoryItems = [],
valueItems = [],
//data columns and area data could be created on a graph level
for(; i < len; ++i)
{
{
index = i;
break;
}
}
for(i = 0; i < len; ++i)
{
{
}
{
{
}
}
}
this._selectedIndex = index;
/**
* Broadcasts when <code>interactionType</code> is set to <code>planar</code> and a series' marker plane has received a mouseover event.
*
*
* @event planarEvent:mouseover
* @preventable false
* @param {EventFacade} e Event facade with the following additional
* properties:
* <dl>
* <dt>categoryItem</dt><dd>An array of hashes, each containing information about the category <code>Axis</code> of each marker whose plane has been intersected.</dd>
* <dt>valueItem</dt><dd>An array of hashes, each containing information about the value <code>Axis</code> of each marker whose plane has been intersected.</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>items</dt><dd>An array including all the series which contain a marker whose plane has been intersected.</dd>
* <dt>index</dt><dd>Index of the markers in their respective series.</dd>
* </dl>
*/
/**
* Broadcasts when <code>interactionType</code> is set to <code>planar</code> and a series' marker plane has received a mouseout event.
*
* @event planarEvent:mouseout
* @preventable false
* @param {EventFacade} e
*/
if(index > -1)
{
this.fire("planarEvent:mouseover", {categoryItem:categoryItems, valueItem:valueItems, x:posX, y:posY, items:items, index:index});
}
else
{
this.fire("planarEvent:mouseout");
}
},
/**
* @private
*/
_type: "combo",
/**
* @private
*/
_axesRenderQueue: null,
/**
* @private
*/
_addToAxesRenderQueue: function(axis)
{
if(!this._axesRenderQueue)
{
this._axesRenderQueue = [];
}
{
}
},
/**
* @private
*/
_getDefaultSeriesCollection: function(val)
{
tempKeys = [],
i,
l,
key,
if(dir == "vertical")
{
catAxis = "yAxis";
catKey = "yKey";
valAxis = "xAxis";
seriesKey = "xKey";
}
else
{
catAxis = "xAxis";
catKey = "xKey";
valAxis = "yAxis";
seriesKey = "yKey";
}
for(i = 0; i < l; ++i)
{
if(key)
{
if(index > -1)
{
}
}
}
{
}
for(i = 0; i < l; ++i)
{
if(series instanceof Y.CartesianSeries)
{
this._parseSeriesAxes(series);
continue;
}
if((series.type == "combo" || series.type == "stackedcombo" || series.type == "combospline" || series.type == "stackedcombospline"))
{
if(showAreaFill !== null)
{
series.showAreaFill = (series.showAreaFill !== null && series.showAreaFill !== undefined) ? series.showAreaFill : showAreaFill;
}
if(showMarkers !== null)
{
series.showMarkers = (series.showMarkers !== null && series.showMarkers !== undefined) ? series.showMarkers : showMarkers;
}
if(showLines !== null)
{
series.showLines = (series.showLines !== null && series.showLines !== undefined) ? series.showLines : showLines;
}
}
}
if(val)
{
}
return sc;
},
/**
* @private
*/
_parseSeriesAxes: function(series)
{
axis;
{
{
}
}
{
{
}
}
},
/**
* @private
*/
_getCategoryAxis: function()
{
var axis,
return axis;
},
/**
* @private
*/
{
i,
keys,
axis;
if(axes)
{
{
}
else
{
for(i in axes)
{
if(axes.hasOwnProperty(i))
{
{
break;
}
}
}
}
}
return axis;
},
/**
* @private
* Gets an attribute from an object, using a getter for Base objects and a property for object
* literals. Used for determining attributes from series/axis references which can be an actual class instance
* or a hash of properties that will be used to create a class instance.
*/
{
{
}
{
}
return null;
},
/**
* @private
* Sets an attribute on an object, using a setter of Base objects and a property for object
* literals. Used for setting attributes on a Base class, either directly or to be stored in an object literal
* for use at instantiation.
*/
{
{
}
else
{
}
},
/**
* @private
* Creates Axis and Axis data classes based on hashes of properties.
*/
_parseAxes: function(val)
{
axes = {},
axesAttrs = {
edgeOffset: "edgeOffset",
position: "position",
overlapGraph:"overlapGraph",
labelFunction:"labelFunction",
labelFunctionScope:"labelFunctionScope",
labelFormat:"labelFormat",
maximum:"maximum",
minimum:"minimum",
roundingMethod:"roundingMethod",
alwaysShowZero:"alwaysShowZero",
title:"title"
},
ai,
i,
pos,
axis,
dh,
for(i in hash)
{
if(hash.hasOwnProperty(i))
{
{
}
else
{
config = {};
{
}
{
}
{
{
}
}
}
if(axis)
{
{
}
}
}
}
return axes;
},
/**
* @private
*/
_addAxes: function()
{
i,
axis,
pos,
w = this.get("width"),
h = this.get("height"),
if(!this._axesCollection)
{
this._axesCollection = [];
}
for(i in axes)
{
if(axes.hasOwnProperty(i))
{
{
if(!w)
{
w = this.get("width");
}
if(!h)
{
h = this.get("height");
}
this._addToAxesRenderQueue(axis);
{
}
else
{
}
{
}
}
}
}
},
/**
* @private
*/
_addSeries: function()
{
},
/**
* @private
* @description Adds gridlines to the chart.
*/
_addGridlines: function()
{
if(this._axesCollection)
{
}
if(hgl)
{
{
}
{
}
else
{
}
{
}
{
}
}
if(vgl)
{
{
}
{
}
else
{
}
{
}
{
}
}
},
/**
* @private
*/
_getDefaultAxes: function(axes)
{
axis,
attr,
keys,
newAxes = {},
claimedKeys = [],
i,
l,
ii,
ll,
dv,
valueAxes = [],
if(direction == "vertical")
{
seriesPosition = "bottom";
categoryPosition = "left";
}
else
{
seriesPosition = "left";
categoryPosition = "bottom";
}
if(axes)
{
for(i in axes)
{
if(axes.hasOwnProperty(i))
{
{
categoryAxisName = i;
this.set("categoryAxisName", i);
{
}
}
else if(i == categoryAxisName)
{
}
else
{
{
{
}
}
{
}
{
this._setBaseAttribute(newAxes[i], "position", this._getDefaultAxisPosition(newAxes[i], valueAxes, seriesPosition));
}
}
}
}
}
{
for(i in dv)
{
{
seriesKeys.push(i);
}
}
}
if(cIndex > -1)
{
}
l = claimedKeys.length;
for(i = 0; i < l; ++i)
{
if(cIndex > -1)
{
}
}
{
newAxes[categoryAxisName] = {};
}
{
}
{
}
{
}
{
}
{
{
}
else
{
}
}
{
{
this._setBaseAttribute(newAxes[valueAxisName], "position", this._getDefaultAxisPosition(newAxes[valueAxisName], valueAxes, seriesPosition));
}
{
}
{
}
}
return newAxes;
},
/**
* @private
* @description Determines the position of an axis when one is not specified.
*/
{
{
if(direction == "horizontal")
{
{
position = "right";
}
{
position = "left";
}
}
else
{
{
position = "top";
}
else
{
position = "bottom";
}
}
}
return position;
},
/**
* Returns an object literal containing a categoryItem and a valueItem for a given series index.
*
* @method getSeriesItem
* @param {CartesianSeries} series Reference to a series.
* @param {Number} index Index of the specified item within a series.
* @return Object
*/
{
{
categoryItem = {
};
valueItem = {
};
}
else
{
valueItem = {
};
categoryItem = {
};
}
},
/**
* @private
* Listender for axisRendered event.
*/
_axisRendered: function(e)
{
this._axesRenderQueue = this._axesRenderQueue.splice(1 + Y.Array.indexOf(this._axesRenderQueue, e.currentTarget), 1);
{
this._redraw();
}
},
/**
* @private
*/
_sizeChanged: function(e)
{
if(this._axesCollection)
{
var ac = this._axesCollection,
i = 0,
for(; i < l; ++i)
{
this._addToAxesRenderQueue(ac[i]);
}
this._redraw();
}
},
/**
* @private
*/
_redraw: function()
{
if(this._drawing)
{
this._callLater = true;
return;
}
this._drawing = true;
this._callLater = false;
var w = this.get("width"),
h = this.get("height"),
lw = 0,
rw = 0,
th = 0,
bh = 0,
i = 0,
l,
axis,
pos,
pts = [],
graphOverflow = "visible",
if(lc)
{
for(i = l - 1; i > -1; --i)
{
}
}
if(rc)
{
i = 0;
for(i = l - 1; i > -1; --i)
{
}
}
if(tc)
{
for(i = l - 1; i > -1; --i)
{
}
}
if(bc)
{
for(i = l - 1; i > -1; --i)
{
}
}
l = this._axesCollection.length;
i = 0;
for(; i < l; ++i)
{
axis = this._axesCollection[i];
{
{
}
}
{
{
}
}
{
graphOverflow = "hidden";
}
}
this._drawing = false;
if(this._callLater)
{
this._redraw();
return;
}
if(graph)
{
}
if(this._overlay)
{
}
}
}, {
ATTRS: {
/**
* @private
* Style object for the axes.
*
* @attribute axesStyles
* @type Object
*/
axesStyles: {
getter: function()
{
i,
styles = this._axesStyles;
if(axes)
{
for(i in axes)
{
{
if(!styles)
{
styles = {};
}
}
}
}
return styles;
},
{
i;
for(i in val)
{
{
}
}
}
},
/**
* @private
* Style object for the series
*
* @attribute seriesStyles
* @type Object
*/
seriesStyles: {
getter: function()
{
var styles = this._seriesStyles,
dict,
i;
if(graph)
{
if(dict)
{
styles = {};
for(i in dict)
{
if(dict.hasOwnProperty(i))
{
}
}
}
}
return styles;
},
{
var i,
l,
s;
{
s = this.get("seriesCollection");
i = 0;
for(; i < l; ++i)
{
}
}
else
{
for(i in val)
{
if(val.hasOwnProperty(i))
{
s = this.getSeries(i);
}
}
}
}
},
/**
* @private
* Styles for the graph.
*
* @attribute graphStyles
* @type Object
*/
graphStyles: {
getter: function()
{
if(graph)
{
}
return this._graphStyles;
},
{
}
},
/**
* Style properties for the chart. Contains a key indexed hash of the following:
* <dl>
* <dt>series</dt><dd>A key indexed hash containing references to the <code>styles</code> attribute for each series in the chart.
* Specific style attributes vary depending on the series:
* <ul>
* <li><a href="AreaSeries.html#config_styles">AreaSeries</a></li>
* <li><a href="BarSeries.html#config_styles">BarSeries</a></li>
* <li><a href="ColumnSeries.html#config_styles">ColumnSeries</a></li>
* <li><a href="ComboSeries.html#config_styles">ComboSeries</a></li>
* <li><a href="LineSeries.html#config_styles">LineSeries</a></li>
* <li><a href="MarkerSeries.html#config_styles">MarkerSeries</a></li>
* <li><a href="SplineSeries.html#config_styles">SplineSeries</a></li>
* </ul>
* </dd>
* <dt>axes</dt><dd>A key indexed hash containing references to the <code>styles</code> attribute for each axes in the chart. Specific
* style attributes can be found in the <a href="Axis.html#config_styles">Axis</a> class.</dd>
* <dt>graph</dt><dd>A reference to the <code>styles</code> attribute in the chart. Specific style attributes can be found in the
* <a href="Graph.html#config_styles">Graph</a> class.</dd>
* </dl>
*
* @attribute styles
* @type Object
*/
styles: {
getter: function()
{
var styles = {
};
return styles;
},
{
{
if(this.get("axesStyles"))
{
}
else
{
}
}
{
if(this.get("seriesStyles"))
{
}
else
{
}
}
{
}
}
},
/**
* Axes to appear in the chart. This can be a key indexed hash of axis instances or object literals
* used to construct the appropriate axes.
*
* @attribute axes
* @type Object
*/
axes: {
valueFn: "_parseAxes",
{
return this._parseAxes(val);
}
},
/**
* Collection of series to appear on the chart. This can be an array of Series instances or object literals
* used to construct the appropriate series.
*
* @attribute seriesCollection
* @type Array
*/
valueFn: "_getDefaultSeriesCollection",
{
return this._getDefaultSeriesCollection(val);
}
},
/**
* Reference to the left-aligned axes for the chart.
*
* @attribute leftAxesCollection
* @type Array
* @private
*/
leftAxesCollection: {},
/**
* Reference to the bottom-aligned axes for the chart.
*
* @attribute bottomAxesCollection
* @type Array
* @private
*/
bottomAxesCollection: {},
/**
* Reference to the right-aligned axes for the chart.
*
* @attribute rightAxesCollection
* @type Array
* @private
*/
rightAxesCollection: {},
/**
* Reference to the top-aligned axes for the chart.
*
* @attribute topAxesCollection
* @type Array
* @private
*/
topAxesCollection: {},
/**
* Indicates whether or not the chart is stacked.
*
* @attribute stacked
* @type Boolean
*/
stacked: {
value: false
},
/**
* Direction of chart's category axis when there is no series collection specified. Charts can
* be horizontal or vertical. When the chart type is column, the chart is horizontal.
* When the chart type is bar, the chart is vertical.
*
* @attribute direction
* @type String
*/
direction: {
getter: function()
{
if(type == "bar")
{
return "vertical";
}
else if(type == "column")
{
return "horizontal";
}
return this._direction;
},
{
this._direction = val;
return this._direction;
}
},
/**
* Indicates whether or not an area is filled in a combo chart.
*
* @attribute showAreaFill
* @type Boolean
*/
showAreaFill: {},
/**
* Indicates whether to display markers in a combo chart.
*
* @attribute showMarkers
* @type Boolean
*/
showMarkers:{},
/**
* Indicates whether to display lines in a combo chart.
*
* @attribute showLines
* @type Boolean
*/
showLines:{},
/**
* Indicates the key value used to identify a category axis in the <code>axes</code> hash. If
* not specified, the categoryKey attribute value will be used.
*
* @attribute categoryAxisName
* @type String
*/
},
/**
* Indicates the key value used to identify a the series axis when an axis not generated.
*
* @attribute valueAxisName
* @type String
*/
value: "values"
},
/**
* Reference to the horizontalGridlines for the chart.
*
* @attribute horizontalGridlines
* @type Gridlines
*/
getter: function()
{
if(graph)
{
}
return this._horizontalGridlines;
},
{
{
val = {};
}
if(graph)
{
}
else
{
this._horizontalGridlines = val;
}
}
},
/**
* Reference to the verticalGridlines for the chart.
*
* @attribute verticalGridlines
* @type Gridlines
*/
getter: function()
{
if(graph)
{
}
return this._verticalGridlines;
},
{
{
val = {};
}
if(graph)
{
}
else
{
this._verticalGridlines = val;
}
}
},
/**
* Type of chart when there is no series collection specified.
*
* @attribute type
* @type String
*/
type: {
getter: function()
{
if(this.get("stacked"))
{
return "stacked" + this._type;
}
return this._type;
},
{
if(this._type == "bar")
{
if(val != "bar")
{
}
}
else
{
if(val == "bar")
{
}
}
return this._type;
}
},
/**
* Reference to the category axis used by the chart.
*
* @attribute categoryAxis
* @type Axis
*/
categoryAxis:{}
}
});