/**
* Copyright (c) 2015, Oracle and/or its affiliates.
* All rights reserved.
*/
/*jslint browser: true*/
/**
* @class oj.CubeAxisValue
* @classdesc Represents one value within an axis header
* @see oj.CubeAxis
* @since 1.1.0
*/
/**
* Represents one value within an axis header
* @constructor
* @export
* @private
*/
oj.CubeAxisValue = function(value, label, level, parent) {
this.Init();
this._children = [];
this._parent = parent;
this._cubeLevel = level;
this._data = {};
this._data.value = value;
this._data.label = label;
};
// Subclass from oj.Object
oj.Object.createSubclass(oj.CubeAxisValue, oj.Object, "oj.CubeAxisValue");
/**
* Initializes instance with the set options
* @private
*/
oj.CubeAxisValue.prototype.Init = function()
{
oj.CubeAxisValue.superclass.Init.call(this);
};
/**
* Get the {@link oj.CubeLevel} of which this value is a member
* @return {oj.CubeLevel} the level to which this header value belongs
* @export
*/
oj.CubeAxisValue.prototype.getLevel = function() {
return this._cubeLevel;
};
/**
* Get the number of levels this header value spans
* @return {number} the number of levels this header value spans. Typically one, but in the future something like a grand total may span all the available levels at a particular
* axis value location
* @export
*/
oj.CubeAxisValue.prototype.getDepth = function() {
return 1;
};
/**
* Get the parent oj.CubeAxisValues of this value
* @return {Array} an array of oj.CubeAxisValues--all the slower-varying level axis values under which this value is grouped
* @export
*/
oj.CubeAxisValue.prototype.getParents = function() {
var parents = [];
var parent = this._parent;
// Add parents, don't add root
while (parent && parent._parent) {
parents.unshift(parent);
parent = parent._parent;
}
return parents;
};
/**
* Get an ordered list of the child oj.CubeAxisValues of this value, at the next level
* @return {Array} an array of the children of this oj.CubeAxisValue
* @export
*/
oj.CubeAxisValue.prototype.getChildren = function() {
return this._children;
};
/**
* Get the number of indices spanned by this value
* @return {number} the number of indices spanned by this value
* @export
*/
oj.CubeAxisValue.prototype.getExtent = function() {
if (this._extent > -1) {
return this._extent;
}
// Calculate it: add up all my children's extents--if there are none, my extent is one as I'm the innermost level
if (!this._children || this._children.length === 0) {
this._extent = 1;
}
else {
this._extent = 0;
for (var c = 0; c < this.getChildren().length; c++) {
this._extent += this.getChildren()[c].getExtent();
}
}
return this._extent;
};
/**
* Get the starting index of this value within the axis
*
* @return {number} the starting index of this value within the axis
* @export
*/
oj.CubeAxisValue.prototype.getStart = function() {
if (this._start > -1) {
return this._start;
}
if (!this._parent) {
// We're the root
return 0;
}
// Add up all my earlier siblings' extents plus my parent's start--that's my start
var start = this._parent.getStart();
var currChild = this._parent._getPrevChild(this);
while (currChild) {
start += currChild.getExtent();
currChild = this._parent._getPrevChild(currChild);
}
this._start = start;
return start;
};
/**
* Get the actual value of this axis header location
* @return {Object} the value at this location in the header
* @export
*/
oj.CubeAxisValue.prototype.getValue = function() {
return this._data.value;
};
/**
* Get the label for this axis header location, if any. If none, falls back to {@link getValue}
* @returns {Object} the label for this axis header value
* @export
*/
oj.CubeAxisValue.prototype.getLabel = function() {
if (this._data.label) {
return this._data.label;
}
return this.getValue();
};
// Return the axis value child with the level/value pair found in key
oj.CubeAxisValue.prototype.GetChild = function(key) {
var childLevel = this._getChildLevel();
if (childLevel === null) {
return null;
}
if (childLevel.isDataValue()) {
// Special case: the key is the value
return this._getDataValueChild(key);
}
var levelAttr = childLevel['attribute'];
// Do we have a key value for this?
var val = key[levelAttr];
if (val) {
// Yes, see if any of the children have this value
for (var c = 0; c < this._children.length; c++) {
if (this._children[c].getValue() === val) {
return this._children[c];
}
}
}
return null;
};
oj.CubeAxisValue.prototype._getDataValueChild = function(key) {
for (var c = 0; c < this._children.length; c++) {
var val = this._children[c].getValue();
if (key.hasOwnProperty(val) && key[val] === val) {
// found it
return this._children[c];
}
}
return null;
};
oj.CubeAxisValue.prototype._getChildLevel = function() {
if (this._children && this._children.length > 0) {
return this._children[0].getLevel();
}
return null;
};
// Return the axis value child at the given index
oj.CubeAxisValue.prototype.GetChildAt = function(index) {
return this._findChild(index, 0, this._children.length - 1);
};
oj.CubeAxisValue.prototype._findChild = function(index, start, end) {
if (start > end) {
return null;
}
var mid = Math.floor((start + end) / 2);
var value = this._children[mid];
var valStart = value.getStart();
if (valStart > index) {
return this._findChild(index, start, mid-1);
}
if (valStart + value.getExtent() - 1 < index) {
return this._findChild(index, mid+1, end);
}
return value;
}
// Add this value to the node if not already there; return either the new cube axis value or the one where it was found
oj.CubeAxisValue.prototype.AddNode = function(value, label, level) {
// Check if this value is already in the child list
for (var c = 0; c < this._children.length; c++) {
if (this._children[c].getValue() === value) {
// We already have this node: just return it so any other members below its level get put in the right place
return this._children[c];
}
}
// Not found: add a new child
var newValue = new oj.CubeAxisValue(value, label, level, this);
this._children.push(newValue);
return newValue;
};
// Get a "hash value" for this axis value. Format is levelAttr:value
oj.CubeAxisValue.prototype.GetHashCode = function() {
var obj = {};
obj[this.getLevel()['attribute']] = this.getValue();
return obj;
};
// Return the child immediately preceding this one
oj.CubeAxisValue.prototype._getPrevChild = function(currChild) {
for (var c = 0; c < this._children.length; c++) {
if (this._children[c] === currChild) {
// Found this child: see if there's a previous one
if (c > 0) {
return this._children[c-1];
}
// First child
return null;
}
}
// Not found
return null;
};
Source: src/main/javascript/oracle/oj/ojcube/CubeAxisValue.js
Oracle® JavaScript Extension Toolkit (JET)
1.1.2
E65298-01