// During the rave-utilities.js build, this file is added to the top.
// Create an inner self-executing function that will be run with the global scope
// On browsers, this is 'window'. Everywhere else should use 'this' if available.
// Need to run eval('this') "indirectly" by having eval returned by (1,eval). OBVIOUSLY :)
(function (global, factory) {
// dynamically determine how 'rave' variable should be loaded depeneding on loader type
var _rave;
if (typeof module === "object" && typeof module.exports === "object" && typeof require == "function") {
// CommonJS/node.js
var rave = require("rave");
var navigation = factory(global,rave);
module.exports = rave;
} else if (typeof define === "function" && define.amd) {
// AMD
define(['rave'], function(rave) {
return factory(global,rave);
});
} else {
// probably loading via script tag. run as is, setting stuff on rave
factory(global,global['rave']);
}
}((1, eval)('this'), function (_global, _rave) {(function() {
var $ = {};
// $source: com/ibm/rave/ext/utilities/internal/nativeImpl/ModuleHeader
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2014
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// setup
var global = typeof _global !== "undefined" ? _global : (1, eval)('this');
var rave = typeof _rave !== "undefined" ? _rave : global['rave'];
com_ibm_rave_core_Rave = rave;
rave["internal"]["Declare"] = rave["_"]["com_ibm_rave_core_nativeImpl_Declare"];
// $source: com/ibm/rave/ext/axis/RaveAxis
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
//@import com/ibm/rave/ext/axis/tickLabelDrop/TickLabelDrop (runtime) // new
/**
* A factory of extended axis capabilities.
*/
var com_ibm_rave_ext_axis_RaveAxis = rave['internal']['Declare']({
/**
* @return (com.ibm.rave.ext.axis.tickLabelDrop.TickLabelDrop) a new instance of {@link TickLabelDrop}
* @see TickLabelDrop
*/
/** @expose */
tickLabelDrop : function() {
return new com_ibm_rave_ext_axis_tickLabelDrop_TickLabelDrop();
}
//constructor : function() {}
});
com_ibm_rave_ext_axis_RaveAxis.getRegistrationStatus = function() {
var registrationStatus = rave['internal']['RaveContextManager'].INSTANCE.getRaveContext().getData("RAVEAXIS_EXTENSION_REGISTRATION_STATUS_KEY");
if (!registrationStatus) {
registrationStatus = new com_ibm_rave_ext_axis_RaveAxis.RegistrationStatus();
rave['internal']['RaveContextManager'].INSTANCE.getRaveContext().putData("RAVEAXIS_EXTENSION_REGISTRATION_STATUS_KEY", registrationStatus);
}
return registrationStatus;
};
/**
* Register all extended axis capabilities.
* @return (boolean) true if registration was successful, false otherwise
*/
/** @expose */
com_ibm_rave_ext_axis_RaveAxis.init = function() {
var registrationStatus = com_ibm_rave_ext_axis_RaveAxis.getRegistrationStatus();
if (!registrationStatus.registered) {
registrationStatus.registered = rave.capabilities.extension("axis", function() {
return com_ibm_rave_ext_axis_RaveAxis.INSTANCE;
});
}
return registrationStatus.registered;
};
com_ibm_rave_ext_axis_RaveAxis.RegistrationStatus = rave['internal']['Declare']({
registered : false
});
//com_ibm_rave_ext_axis_RaveAxis.AXIS_EXT = "axis";
//com_ibm_rave_ext_axis_RaveAxis.EXTENSION_REGISTRATION_STATUS_KEY = "RAVEAXIS_EXTENSION_REGISTRATION_STATUS_KEY";
com_ibm_rave_ext_axis_RaveAxis.INSTANCE = new com_ibm_rave_ext_axis_RaveAxis();
// Auto initialization
com_ibm_rave_ext_axis_RaveAxis.init();
if (!rave.capabilities["axis"]) {
rave.capabilities["axis"] = function() {
return com_ibm_rave_ext_axis_RaveAxis.INSTANCE;
};
} else {
console.log("Could not register extension: RaveAxis");
}
// $source: com/ibm/rave/ext/axis/tickLabelDrop/TickLabelDrop
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
//@import com/ibm/rave/ext/position/drop/DropOverlap (runtime) // new
/**
* Utility for dropping overlapping tick labels.
*/
var com_ibm_rave_ext_axis_tickLabelDrop_TickLabelDrop = rave['internal']['Declare'](rave['internal']['AbstractTickHandler'], {
//drop : null,
removeOverlapping : true,
_$functionClassMethod : function() {
var _$self = function(args) {
if (args !== null || arguments.length > 1){
args = Array.prototype.slice.call(arguments, 0);
}
{
_$self.tickLabelDrop(args[0]);
return null;
}
};
return _$self;
},
constructor : function() {
this.drop = new com_ibm_rave_ext_position_drop_DropOverlap();
},
/**
* Set if the overlapping tick labels are to be removed from the axis, (otherwise, they will simply be hidden).
* @param (boolean) remove true
to indicate the overlapping tick labels are to be removed (the default), false
will hide them.
* @return (com.ibm.rave.ext.axis.tickLabelDrop.TickLabelDrop) this instance
*/
remove$0 : function(remove) {
this.removeOverlapping = remove;
return this;
},
/**
* @return (boolean) true
if the overlapping tick labels are to be removed, false
otherwise.
*/
remove$1 : function() {
return this.removeOverlapping;
},
/**
* Resets the overlapping labels. If removing the labels, this does nothing. If not, this will make the labels visible again.
* @param (rave['internal']['Selection']) ticks The selection containing the ticks to reset.
*/
/** @expose */
reset : function(ticks) {
if (!this.removeOverlapping) {
var labels = ticks.selectAll("text");
this.drop.reset(labels);
}
},
/**
* Remove overlapping labels from the selection.
* @param (rave['internal']['Selection']) axis The selection containing the axis.
*/
/** @expose */
tickLabelDrop : function(axis) {
this.drop.remove(this.removeOverlapping);
this.drop.dropOverlap(axis.selectAll("text"));
},
/** @expose */
remove : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.remove$1();
}
return this.remove$0(a0);
}
});
//com_ibm_rave_ext_axis_tickLabelDrop_TickLabelDrop.TEXT = "text";
// $source: com/ibm/rave/ext/position/drop/DropOverlap
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
/**
* Utility for dropping overlapping elements.
*/
var com_ibm_rave_ext_position_drop_DropOverlap = rave['internal']['Declare']({
//quadTree : null,
//extentPts : null,
//hideCallback : null,
//clampCallback : null,
//showCallback : null,
removeOverlapping : true,
collisionFound : false,
maxRadius : 0.0,
labelGap : 0.0,
clippingAllowed : true,
_$functionClassMethod : function() {
var _$self = function(args) {
if (args !== null || arguments.length > 1){
args = Array.prototype.slice.call(arguments, 0);
}
{
_$self.dropOverlap(args[0]);
return null;
}
};
return _$self;
},
constructor : function() {
this.quadTree = new rave['internal']['QuadTree']().x(com_ibm_rave_ext_position_drop_DropOverlap.fx).y(com_ibm_rave_ext_position_drop_DropOverlap.fy);
{
var self = this;
this.hideCallback = function(args) {
if (args !== null || arguments.length > 1){
args = Array.prototype.slice.call(arguments, 0);
}
{
if (self.removeOverlapping) {
this.rave_getParentNode().removeChild(this);
} else if (!(this.rave_hasProperty("__raveOverlapHidden__"))) {
this.setAttribute("visibility", "hidden");
this.rave_setProperty("__raveOverlapHidden__", "hidden");
var count = ~~ (this.rave_getProperty(com_ibm_rave_ext_position_drop_DropOverlap.HIDDEN_COUNT));
this.rave_setProperty(com_ibm_rave_ext_position_drop_DropOverlap.HIDDEN_COUNT, count + 1);
}
return null;
}
};
this.clampCallback = function(args) {
if (args !== null || arguments.length > 1){
args = Array.prototype.slice.call(arguments, 0);
}
{
var moveX = 0.0;
var moveY = 0.0;
var rect = this.getBBox();
var extent = self.quadTree.extent();
if (rect.x < extent[0][0]) {
moveX = extent[0][0] - rect.x;
} else if (rect.x + rect.width > extent[1][0]) {
moveX = extent[1][0] - (rect.x + rect.width);
}
if (rect.y < extent[0][1]) {
moveY = extent[0][1] - rect.y;
} else if (rect.y + rect.height > extent[1][1]) {
moveY = extent[1][1] - (rect.y + rect.height);
}
var node = rave.select(this);
var nodeXcoordinate = node.attr("x");
var nodeYcoordinate = node.attr("y");
var x = (nodeXcoordinate == null) ? rect.x : + (nodeXcoordinate);
var y = (nodeYcoordinate == null) ? rect.y : + (nodeYcoordinate);
node.attr("x", x + moveX);
node.attr("y", y + moveY);
return null;
}
};
this.showCallback = function(args) {
if (args !== null || arguments.length > 1){
args = Array.prototype.slice.call(arguments, 0);
}
{
if (this.rave_hasProperty("__raveOverlapHidden__")) {
this.rave_removeProperty("__raveOverlapHidden__");
var count = ~~ (this.rave_getProperty(com_ibm_rave_ext_position_drop_DropOverlap.HIDDEN_COUNT));
if (count <= 1) {
this.rave_removeProperty(com_ibm_rave_ext_position_drop_DropOverlap.HIDDEN_COUNT);
this.removeAttribute("visibility");
} else {
this.rave_setProperty(com_ibm_rave_ext_position_drop_DropOverlap.HIDDEN_COUNT, count - 1);
}
}
return null;
}
};
}
},
/**
* Configure how much space to leave between nodes (default is 0)
* @param (double) gap size of space
*/
/** @expose */
setOverlapGap : function(gap) {
this.labelGap = gap;
},
/**
* Node must be fully inside extent to be considered for overlap tests
*/
/** @expose */
noClipping : function() {
this.clippingAllowed = false;
},
/**
* Remove the overlapping elements in the selection. Assumes the elements return a valid bounding box. If no extent is provided, the selection's owner node will be used to calculate one.
* @param (rave['internal']['Selection']) s The elements.
*/
/** @expose */
dropOverlap : function(s) {
var node;
if (s && (node = s.node())) {
var extent = this.extentPts;
if (!extent) {
var bbox = node.rave_getOwner().getBBox();
var ownerExtent = [[bbox.x, bbox.y], [bbox.x + bbox.width, bbox.y + bbox.height]];
extent = ownerExtent;
}
var extentPoints = extent;
var root = this.quadTree.extent(extent)([]);
var self = this;
s.each(function(data, index, groupIndex) {
if (this) {
self.collisionFound = false;
var overlapNode = new com_ibm_rave_ext_position_drop_DropOverlap.OverlapNode(this, self.labelGap, self.clippingAllowed);
if (self.isCollisionCandidate(this, overlapNode, extentPoints)) {
root.visit(self.collide(overlapNode, self.maxRadius));
if (!self.collisionFound) {
self.showCallback.call(this);
root.add(overlapNode);
self.maxRadius = Math.max(self.maxRadius, overlapNode.radius);
} else {
self.hideCallback.call(this);
}
}
}
});
}
},
isCollisionCandidate : function(sceneNode, overlapNode, extentPoints) {
var isCandidate;
var point0 = extentPoints[0];
var extentLeft = point0[0];
var extentTop = point0[1];
var point1 = extentPoints[1];
var extentRight = point1[0];
var extentBottom = point1[1];
if (this.clippingAllowed) {
isCandidate = overlapNode.boundingRect.left <= extentRight && overlapNode.boundingRect.top <= extentBottom && overlapNode.boundingRect.right >= extentLeft && overlapNode.boundingRect.bottom >= extentTop;
} else {
var isHalfInside = false;
var isFullyInside = (overlapNode.boundingRect.left + this.labelGap / 2) >= extentLeft && overlapNode.boundingRect.top >= extentTop && (overlapNode.boundingRect.right - this.labelGap / 2) <= extentRight && overlapNode.boundingRect.bottom <= extentBottom;
if (!isFullyInside) {
isHalfInside = (((overlapNode.boundingRect.left + overlapNode.boundingRect.width / 2 < extentRight && overlapNode.boundingRect.right > extentRight) || (overlapNode.boundingRect.left < extentLeft && overlapNode.boundingRect.right - overlapNode.boundingRect.width / 2 > extentLeft)) && (overlapNode.boundingRect.top > extentTop && overlapNode.boundingRect.bottom < extentBottom)) || (((overlapNode.boundingRect.top < extentTop && overlapNode.boundingRect.top + overlapNode.boundingRect.height / 2 > extentTop) || (overlapNode.boundingRect.top + overlapNode.boundingRect.height / 2 < extentBottom && overlapNode.boundingRect.bottom > extentBottom)) && (overlapNode.boundingRect.left > extentLeft && overlapNode.boundingRect.right < extentRight));
if (isHalfInside) {
this.clampCallback.call(sceneNode);
} else {
this.hideCallback.call(sceneNode);
}
}
isCandidate = isFullyInside || isHalfInside;
}
return isCandidate;
},
/**
* Determine if a node collides with any in the quadtree.
* @param (com.ibm.rave.ext.position.drop.DropOverlap.OverlapNode) node The node to compare against.
* @param (double) radius The longest radius of the visited nodes.
* @return (rave['internal']['Visitor']) The visiting function.
*/
collide : function(node, radius) {
var nx1, nx2, ny1, ny2;
nx1 = node.boundingRect.left - radius;
nx2 = node.boundingRect.right + radius;
ny1 = node.boundingRect.top - radius;
ny2 = node.boundingRect.bottom + radius;
var self = this;
return function(qtNode, x1, y1, x2, y2) {
if (self.collisionFound) {
return true;
}
if (qtNode.point && qtNode.point.node != node.node) {
self.collisionFound = com_ibm_rave_ext_position_drop_DropOverlap.intersect(node.boundingRect, qtNode.point.boundingRect);
}
var isOutsideQuad = x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
return self.collisionFound || isOutsideQuad;
};
},
/**
* When using the default hide/show functionality, set if the overlapping elements are to be removed (otherwise, they will be hidden).
* @param (boolean) remove true
to indicate the overlapping elements are to be removed (the default), false
will hide them.
* @return (com.ibm.rave.ext.position.drop.DropOverlap) this instance
*/
remove$0 : function(remove) {
this.removeOverlapping = remove;
return this;
},
/**
* @return (boolean) true
if the overlapping elements are to be removed, false
otherwise (they will be hidden).
*/
remove$1 : function() {
return this.removeOverlapping;
},
/**
* Returns the current extent, which, if not specified, defaults to the selection's owner's bounding box.
* @return (rave['internal']['Point[]']) an array of points [[x0,y0], [x1, y1]]
*/
extent$0 : function() {
return this.extentPts;
},
/**
* Sets the current extent and returns this object. The extent must be specified as a two-dimensional array [[x0, y0], [x1, y1]], where x0 and y0 are the lower bounds of the extent, and x1 and y1 are the upper bounds of the extent.
* @param (rave['internal']['Point[]']) pt A two-dimensional array [[x0, y0], [x1, y1]], where x0 and y0 are the lower bounds of the extent, and x1 and y1 are the upper bounds of the extent
* @return (com.ibm.rave.ext.position.drop.DropOverlap) an instance of this object
*/
extent$1 : function(pt) {
this.extentPts = pt;
return this;
},
/**
* Resets the visibility of the overlapping nodes that were dropped. If the nodes were removed, this has no effect.
* @param (rave['internal']['Selection']) s The elements.
* @return (com.ibm.rave.ext.position.drop.DropOverlap) an instance of this object
*/
/** @expose */
reset : function(s) {
var self = this;
s.each(function(data, index, groupIndex) {
self.showCallback.call(this);
});
return this;
},
/** @expose */
remove : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.remove$1();
}
return this.remove$0(a0);
},
/** @expose */
extent : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.extent$0();
}
return this.extent$1(a0);
}
});
/**
* Are the 2 rectangles intersecting?
* @param (rave['internal']['NodeRect']) r1 First rectangle
* @param (rave['internal']['NodeRect']) r2 Second rectangle
* @return (boolean) true
if the rectangles intersect, false
otherwise.
*/
com_ibm_rave_ext_position_drop_DropOverlap.intersect = function(r1, r2) {
return !(r2.left > r1.right || r2.right < r1.left || r2.top > r1.bottom || r2.bottom < r1.top);
};
/**
* Container for the quad tree element nodes. This is needed so we can cache the bounding rect, which is an expensive call in JavaScript.
*/
com_ibm_rave_ext_position_drop_DropOverlap.OverlapNode = function(sceneNode, gap, useBoundingClientRect) {
this.node = sceneNode;
var bbox = sceneNode.getBBox();
var bounding = new rave['internal']['RectStruct'](bbox.x, bbox.y, bbox.width, bbox.height);
if (useBoundingClientRect) {
bounding = rave['internal']['MatrixUtil'].transformBounds(bounding, this.node.getCTM());
}
this.boundingRect = new rave['internal']['NodeRect'](bounding.x - gap / 2, bounding.x + bounding.width + gap / 2, bounding.y + bounding.height, bounding.y, bounding.width + gap, bounding.height);
this.radius = 0.5 * Math.max(bounding.width, bounding.height);
this.x = bounding.x + 0.5 * bounding.width;
this.y = bounding.y + 0.5 * bounding.height;
};
//com_ibm_rave_ext_position_drop_DropOverlap.VISIBILITY = "visibility";
//com_ibm_rave_ext_position_drop_DropOverlap.HIDDEN = "hidden";
/** @expose */
com_ibm_rave_ext_position_drop_DropOverlap.HIDDEN_FLAG = "__raveOverlapHidden__";
/** @expose */
com_ibm_rave_ext_position_drop_DropOverlap.HIDDEN_COUNT = "__hiddenCount__";
com_ibm_rave_ext_position_drop_DropOverlap.fx = function(node, index) {
return node.x;
};
com_ibm_rave_ext_position_drop_DropOverlap.fy = function(node, index) {
return node.y;
};
// $source: com/ibm/rave/ext/position/RavePosition
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
//@import com/ibm/rave/ext/position/place/LabelPositioning (runtime) // new
//@import com/ibm/rave/ext/position/drop/DropOverlap (runtime) // new
/**
* A factory of extended positioning capabilities.
*/
var com_ibm_rave_ext_position_RavePosition = rave['internal']['Declare']({
/**
* @return (com.ibm.rave.ext.position.place.LabelPositioning) a new instance of {@link LabelPositioning}
* @see LabelPositioning
*/
/** @expose */
place : function() {
return new com_ibm_rave_ext_position_place_LabelPositioning();
},
/**
* @return (com.ibm.rave.ext.position.drop.DropOverlap) a new instance of {@link DropOverlap}
* @see DropOverlap
*/
/** @expose */
drop : function() {
return new com_ibm_rave_ext_position_drop_DropOverlap();
}
//constructor : function() {}
});
com_ibm_rave_ext_position_RavePosition.getRegistrationStatus = function() {
var registrationStatus = rave['internal']['RaveContextManager'].INSTANCE.getRaveContext().getData("RAVEPOSITION_EXTENSION_REGISTRATION_STATUS_KEY");
if (!registrationStatus) {
registrationStatus = new com_ibm_rave_ext_position_RavePosition.RegistrationStatus();
rave['internal']['RaveContextManager'].INSTANCE.getRaveContext().putData("RAVEPOSITION_EXTENSION_REGISTRATION_STATUS_KEY", registrationStatus);
}
return registrationStatus;
};
/**
* Register all extended positioning capabilities.
* @return (boolean) true if registration was successful, false otherwise
*/
/** @expose */
com_ibm_rave_ext_position_RavePosition.init = function() {
var registrationStatus = com_ibm_rave_ext_position_RavePosition.getRegistrationStatus();
if (!registrationStatus.registered) {
registrationStatus.registered = rave.capabilities.extension("position", function() {
return com_ibm_rave_ext_position_RavePosition.INSTANCE;
});
}
return registrationStatus.registered;
};
com_ibm_rave_ext_position_RavePosition.RegistrationStatus = rave['internal']['Declare']({
registered : false
});
//com_ibm_rave_ext_position_RavePosition.POSITION_EXT = "position";
//com_ibm_rave_ext_position_RavePosition.EXTENSION_REGISTRATION_STATUS_KEY = "RAVEPOSITION_EXTENSION_REGISTRATION_STATUS_KEY";
com_ibm_rave_ext_position_RavePosition.INSTANCE = new com_ibm_rave_ext_position_RavePosition();
// Auto initialization
com_ibm_rave_ext_position_RavePosition.init();
if (!rave.capabilities["position"]) {
rave.capabilities["position"] = function() {
return com_ibm_rave_ext_position_RavePosition.INSTANCE;
};
} else {
console.log("Could not register extension: RavePosition");
}
// $source: com/ibm/rave/ext/position/place/LabelPositioning
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
/**
* The Label Mover utility tries to resolve label overlaps by moving them to around the chart into better positions.
*/
var com_ibm_rave_ext_position_place_LabelPositioning = rave['internal']['Declare']({
//event : null,
//lab : null,
//anc : null,
//_energy : null,
//_schedule : null,
totalDistance : 1.7976931348623157E308,
w : 1,
h : 1,
malpha : 0,
max_move : 5.0,
max_angle : 0.5,
acc : 0,
rej : 0,
w_len : 0.2,
w_inter : 1.0,
w_lab2 : 30.0,
w_lab_anc : 30.0,
w_orient : 3.0,
currT : 0,
nsweeps : 500,
constructor : function() {
this.event = rave['internal']['Dispatcher'].create("start", "tick", "end");
this.lab = [];
this.anc = [];
},
/**
* Sets the function for computing energy values, function that will be called by the Labeler class to get the data values
* @param (rave['internal']['ValueFunction']) valueFn The function for computing data values
* @return (com.ibm.rave.ext.position.place.LabelPositioning) this labelPlacement instance itself
*/
energy$0 : function(valueFn) {
this._energy = valueFn;
return this;
},
/**
* Sets the function for computing energy values, function that will be called by the Labeler class to get the data values
* @param (Number) value the new energy value
* @return (com.ibm.rave.ext.position.place.LabelPositioning) this labelPlacement instance itself
*/
energy$1 : function(value) {
this._energy = value;
return this;
},
/**
* Gets the energy value function
* @return (Object) the value function
*/
energy$2 : function() {
return this._energy;
},
/**
* Sets the function for computing schedule values, function that will be called by the Labeler class to get the data values
* @param (rave['internal']['ValueFunction']) valueFn The function for computing data values
* @return (com.ibm.rave.ext.position.place.LabelPositioning) this labelPlacement instance itself
*/
schedule$0 : function(valueFn) {
this._schedule = valueFn;
return this;
},
/**
* Gets the schedule value function
* @return (Object) the value function
*/
schedule$1 : function() {
return this._schedule;
},
/**
* In order to distinguish between the quality of different configurations in our search space, we need construct a function which takes as input a label configuration and outputs a score indicating the quality of the placements. In a labeling problem, the inputs are themselves functions of various parameters such as the amount of overlaps, distances between labels and their corresponding anchor points, and various stylistic preferences. This function, often an energy (also called cost or objective) function, is what we need to optimize. The default energy function includes penalties for:Label-label overlaps, Label-anchor overlaps, Labels far from the corresponding anchor, Leader line intersections, Poorly oriented labels
* @param (int) index
* @return (double) energy
*/
calculateEnergy : function(index) {
var m = this.lab.length;
var ener = 0;
var currentLabel = this.lab[index];
var currentAnchor = this.anc[index];
var dx = currentLabel["x"] - currentAnchor["x"];
var dy = currentAnchor["y"] - currentLabel["y"];
var dist = Math.sqrt(dx * dx + dy * dy);
var overlap = true;
if (dist > 0) {
ener += dist * this.w_len;
}
dx /= dist;
dy /= dist;
if (dx > 0 && dy > 0) {
ener += 0 * this.w_orient;
} else if (dx < 0 && dy > 0) {
ener += 1 * this.w_orient;
} else if (dx < 0 && dy < 0) {
ener += 2 * this.w_orient;
} else {
ener += 3 * this.w_orient;
}
var x21 = currentLabel["x"];
var y21 = currentLabel["y"] - currentLabel["height"] + 2.0;
var x22 = currentLabel["x"] + currentLabel["width"];
var y22 = currentLabel["y"] + 2.0;
var x11, x12, y11, y12, x_overlap, y_overlap, overlap_area;
for (var i = 0; i < m; ++i) {
var otherLabel = this.lab[i];
var otherAnchor = this.anc[i];
if (i != index) {
overlap = com_ibm_rave_ext_position_place_LabelPositioning.leaderLinesIntersect(otherAnchor["x"], otherLabel["x"], otherAnchor["x"], otherLabel["x"], otherAnchor["y"], otherLabel["y"], otherAnchor["y"], otherLabel["y"]);
if (overlap) {
ener += this.w_inter;
}
x11 = otherLabel["x"];
y11 = otherLabel["y"] - otherLabel["height"] + 2.0;
x12 = otherLabel["x"] + otherLabel["width"];
y12 = otherLabel["y"] + 2.0;
x_overlap = Math.max(0, Math.min(x12, x22) - Math.max(x11, x21));
y_overlap = Math.max(0, Math.min(y12, y22) - Math.max(y11, y21));
overlap_area = x_overlap * y_overlap;
ener += (overlap_area * this.w_lab2);
}
var r = otherAnchor["r"] * 2;
x11 = otherAnchor["x"] - r;
y11 = otherAnchor["y"] - r;
x12 = otherAnchor["x"] + r;
y12 = otherAnchor["y"] + r;
x_overlap = Math.max(0, Math.min(x12, x22) - Math.max(x11, x21));
y_overlap = Math.max(0, Math.min(y12, y22) - Math.max(y11, y21));
overlap_area = x_overlap * y_overlap;
ener += (overlap_area * this.w_lab_anc);
}
return ener;
},
/**
* Randomly moves the label
* @param (double) currTemp current temperature
* @param (double) old_energy old energy
* @param (int) i index
*/
mcmove : function(currTemp, old_energy, i) {
var currentLabel = this.lab[i];
var currentAnchor = this.anc[i];
var x_old = currentLabel["x"];
var y_old = currentLabel["y"];
currentLabel["x"] += (Math.random() - 0.5) * this.max_move;
currentLabel["y"] += (Math.random() - 0.5) * this.max_move;
this.compareOldEnergy(currTemp, old_energy, i, currentLabel, currentAnchor, x_old, y_old);
},
/**
* Randomly rotates the label position
* @param (double) currTemp current temperature
* @param (double) old_energy old energy
* @param (int) i index
*/
mcrotate : function(currTemp, old_energy, i) {
var currentLabel = this.lab[i];
var currentAnchor = this.anc[i];
var x_old = currentLabel["x"];
var y_old = currentLabel["y"];
var angle = (Math.random() - 0.5) * this.max_angle;
var s = Math.sin(angle);
var c = Math.cos(angle);
currentLabel["x"] -= currentAnchor["x"];
currentLabel["y"] -= currentAnchor["y"];
var x_new = currentLabel["x"] * c - currentLabel["y"] * s;
var y_new = currentLabel["x"] * s + currentLabel["y"] * c;
currentLabel["x"] = x_new + currentAnchor["x"];
currentLabel["y"] = y_new + currentAnchor["y"];
this.compareOldEnergy(currTemp, old_energy, i, currentLabel, currentAnchor, x_old, y_old);
},
/**
* Compares the energy of the Old and new position, if the energy of the new position is less the move happens
* @param (double) currTemp current temperature
* @param (double) old_energy old energy
* @param (int) i index
* @param (Object) currentLabel current label
* @param (Object) currentAnchor current anchor
* @param (double) x_old old x
* @param (double) y_old old y
*/
compareOldEnergy : function(currTemp, old_energy, i, currentLabel, currentAnchor, x_old, y_old) {
if (currentLabel["x"] > this.w) {
currentLabel["x"] = x_old;
}
if (currentLabel["x"] < 0) {
currentLabel["x"] = x_old;
}
if (Math.abs(currentLabel["x"] - currentAnchor["x"]) > this.totalDistance) {
currentLabel["x"] = x_old;
}
if (currentLabel["y"] > this.h) {
currentLabel["y"] = y_old;
}
if (currentLabel["y"] < 0) {
currentLabel["y"] = y_old;
}
if (Math.abs(currentLabel["y"] - currentAnchor["y"]) > this.totalDistance) {
currentLabel["y"] = y_old;
}
var new_energy;
if (this._energy != null) {
new_energy = + ((typeof this._energy === "function") ? (this._energy).call(this, this.lab, i, -1) : this._energy);
} else {
new_energy = this.calculateEnergy(i);
}
var delta_energy = new_energy - old_energy;
if (Math.random() < Math.exp(-delta_energy / currTemp)) {
this.acc += 1;
} else {
currentLabel["x"] = x_old;
currentLabel["y"] = y_old;
this.rej += 1;
}
},
/**
* Gets the listener for the specified event type supported by labelPlacement: "start", "tick", and "end"
* @param (String) type the type of event to get the listener for
* @return (rave['internal']['RunFunction']) the listener for the specified event or null if none was registered
*/
on$0 : function(type) {
return this.event.on(type);
},
/**
* Registers the specified listener to receive events of the specified type from the force layout. Currently, only "start", "tick", and "end" events are supported. The "tick" events are dispatched for each tick of the simulation. Listen to tick events to update the displayed positions of nodes and links. The "end" event is dispatched when the simulations internal cooling parameter reaches zero. The "start" is dispatched when the simulation starts
* @param (String) type the type of the labelPlacement event to listen for
* @param (rave['internal']['RunFunction']) listener the listener
* @return (com.ibm.rave.ext.position.place.LabelPositioning) this labelPlacement instance itself
*/
on$1 : function(type, listener) {
this.event.on(type, listener);
return this;
},
/**
* Starts the simulation; this method must be called when the layout is first created, after assigning the nodes and links. On start, the layout initializes temperature and alpha.
* @return (com.ibm.rave.ext.position.place.LabelPositioning) labelPlacement
*/
/** @expose */
start : function() {
this.currT = 1.0;
this.alpha(0.1);
return this;
},
/**
* Runs the one iteration/sweep of simulated annealing. This method can be used in conjunction with start and stop to compute a static layout. For example: labelPlacement.start(); for (int i = 0; i < n; ++i) abelMover.tick(); abelMover.stop();
The choice of initial positions can have a dramatic impact on how quickly the label mover finds a good position.
* @return (boolean) true if the simulation has ended, false otherwise. in other words, it will return true if the layout's cooling parameter decays below some threshold and the simulation will stop. This is useful if you're calling this function in a loop and wanted to know when it is no longer necessary to call it again and break out of the loop.
*/
/** @expose */
tick : function() {
var m = this.lab.length;
var initialT = 1.0;
if (this.currT < .005) {
this.malpha = 0;
var eo = new com_ibm_rave_ext_position_place_LabelPositioning.EventObject("end", 0);
this.event[eo.type].call(eo, eo);
return true;
}
for (var j = 0; j < m; ++j) {
var i = Math.floor(Math.random() * this.lab.length);
var old_energy;
if (this._energy != null) {
old_energy = + ((typeof this._energy === "function") ? (this._energy).call(this, this.lab, i, -1) : this._energy);
} else {
old_energy = this.calculateEnergy(i);
}
if (old_energy > 500) {
if (Math.random() < 0.5) {
this.mcmove(this.currT, old_energy, i);
} else {
this.mcrotate(this.currT, old_energy, i);
}
}
}
if (this._schedule) {
this.currT = + (this._schedule.call(this, this.lab, -1, -1));
} else {
this.currT = (this.currT - (initialT / this.nsweeps));
}
var eo = new com_ibm_rave_ext_position_place_LabelPositioning.EventObject("tick", this.malpha);
this.event[eo.type].call(eo, eo);
return false;
},
/**
* Stops the simulated anealing process, and label positioning.
* @return (com.ibm.rave.ext.position.place.LabelPositioning) labelPlacement
*/
/** @expose */
stop : function() {
return this.alpha(0);
},
/**
* Controls the iterations used for sa alpha(0) stops ticks from running.
*/
alpha : function(x) {
if (this.malpha != 0) {
if (x > 0) {
this.malpha = x;
} else {
this.malpha = 0;
}
} else if (x > 0) {
this.malpha = x;
var eo = new com_ibm_rave_ext_position_place_LabelPositioning.EventObject("start", x);
this.event[eo.type].call(eo, eo);
var labelers = this;
rave.timer(function(elapsed) {
return labelers.tick();
});
}
return this;
},
/**
* Gets the maximum allowed distance from label and point
* @return (double) maximumDistance
*/
maxDistance$0 : function() {
return this.totalDistance;
},
/**
* Sets the maximum distance allowed between label and point
* @param (double) maxDistance maximum distance allowed between label and point
* @return (com.ibm.rave.ext.position.place.LabelPositioning) this labelPlacement instance itself
*/
maxDistance$1 : function(maxDistance) {
this.totalDistance = maxDistance;
return this;
},
/**
* Sets the number of iterations in which to attempt overlap resolution
* @param (int) sweeps number of sweeps
* @return (com.ibm.rave.ext.position.place.LabelPositioning) this labelPlacement instance itself
*/
numberOfSweeps$0 : function(sweeps) {
this.nsweeps = sweeps;
return this;
},
/**
* Gets the number of sweeps to attempt to overlap resolution
* @return (int) number of sweeps
*/
numberOfSweeps$1 : function() {
return this.nsweeps;
},
/**
* Gets the currentTemperature during the run.
* @return (double) currentTemperature
*/
/** @expose */
currentTemperature : function() {
return this.currT;
},
/**
* The width is used to set the boundary conditions so that labels do not go outside the width of the figure. More specifically, Monte Carlo moves in which the labels cross the boundaries are rejected. If they are not specified, both the width defaults to 1.
* @param (double) width width of the boundary
* @return (com.ibm.rave.ext.position.place.LabelPositioning) this labelPlacement instance itself
*/
width$0 : function(width) {
this.w = width;
return this;
},
/**
* Gets width
* @return (double) width
*/
width$1 : function() {
return this.w;
},
/**
* The height is used to set the boundary conditions so that labels do not go outside the height of the figure. More specifically, Monte Carlo moves in which the labels cross the boundaries are rejected. If they are not specified, both the height defaults to 1.
* @param (double) height height of the boundary
* @return (com.ibm.rave.ext.position.place.LabelPositioning) this labelPlacement instance itself
*/
height$0 : function(height) {
this.h = height;
return this;
},
/**
* Gets height
* @return (double) height
*/
height$1 : function() {
return this.h;
},
/**
* Gets list of labels
* @return (Array) get list of labels
*/
label$0 : function() {
return this.lab;
},
/**
* Sets the list of labels that need to be moved
* @param (Array) labelList list of labels
* @return (com.ibm.rave.ext.position.place.LabelPositioning) this labelPlacement instance itself
*/
label$1 : function(labelList) {
this.lab = labelList;
return this;
},
/**
* Sets the anchor point list for the provided labels
* @param (Array) anchorList anchor point list
* @return (com.ibm.rave.ext.position.place.LabelPositioning) this labelPlacement instance itself
*/
anchor$0 : function(anchorList) {
this.anc = anchorList;
return this;
},
/**
* Gets the list of anchor points for labels
* @return (Array) list of anchor points
*/
anchor$1 : function() {
return this.anc;
},
/** @expose */
energy : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.energy$2();
}
if (args.length == 1 && typeof a0 === "function") {
return this.energy$0(a0);
}
return this.energy$1(a0);
},
/** @expose */
schedule : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.schedule$1();
}
return this.schedule$0(a0);
},
/** @expose */
on : function(a0, a1) {
var args = arguments;
if (args.length == 1) {
return this.on$0(a0);
}
return this.on$1(a0, a1);
},
/** @expose */
maxDistance : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.maxDistance$0();
}
return this.maxDistance$1(a0);
},
/** @expose */
numberOfSweeps : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.numberOfSweeps$1();
}
return this.numberOfSweeps$0(a0);
},
/** @expose */
width : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.width$1();
}
return this.width$0(a0);
},
/** @expose */
height : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.height$1();
}
return this.height$0(a0);
},
/** @expose */
label : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.label$0();
}
return this.label$1(a0);
},
/** @expose */
anchor : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.anchor$1();
}
return this.anchor$0(a0);
}
});
/**
* Method checks whether or not leader lines between anchors and labels intersect.
* @param (double) anc1x Anchor 1 x-coordinate
* @param (double) lab1x Label 1 x-coordinate
* @param (double) anc2x Anchor 2 x-coordinate
* @param (double) lab2x Label 2 x-coordinate
* @param (double) anc1y Anchor 1 y-coordinate
* @param (double) lab1y Label 1 y-coordinate
* @param (double) anc2y Anchor 2 y-coordinate
* @param (double) lab2y Label 2 y-coordinate
* @return (boolean) boolean.
*/
com_ibm_rave_ext_position_place_LabelPositioning.leaderLinesIntersect = function(anc1x, lab1x, anc2x, lab2x, anc1y, lab1y, anc2y, lab2y) {
var mua, mub, denom, numera, numerb;
denom = (lab2y - anc2y) * (lab1x - anc1x) - (lab2x - anc2x) * (lab1y - anc1y);
numera = (lab2x - anc2x) * (anc1y - anc2y) - (lab2y - anc2y) * (anc1x - anc2x);
numerb = (lab1x - anc1x) * (anc1y - anc2y) - (lab1y - anc1y) * (anc1x - anc2x);
mua = numera / denom;
mub = numerb / denom;
return !(mua < 0 || mua > 1 || mub < 0 || mub > 1);
};
/**
* The event object fired by label movers
*/
com_ibm_rave_ext_position_place_LabelPositioning.EventObject = rave['internal']['Declare']({
/**
* The type of the event being fired, could either: "start", "tick" or "end"
*/
/** @expose */
type : null,
/**
* The current value of the cooling parameter alpha
*/
/** @expose */
alpha : 0,
constructor : function(type, alpha) {
this.type = type;
this.alpha = alpha;
}
});
// $source: com/ibm/rave/ext/statistics/RaveStatistics
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
//@import com/ibm/rave/ext/statistics/outliersUtility/PeirceCriterion (runtime) // new
/**
* A factory of extended statistics for rave capability.
* @see PeirceCriterion
*/
var com_ibm_rave_ext_statistics_RaveStatistics = rave['internal']['Declare']({
/**
* @return (com.ibm.rave.ext.statistics.outliersUtility.PeirceCriterion) a new instance of {@link PeirceCriterion}
* @see PeirceCriterion
*/
/** @expose */
peirceCriterion : function() {
return new com_ibm_rave_ext_statistics_outliersUtility_PeirceCriterion();
},
/**
* Perform the default outlier calculation on a list of data. This currently uses the Peirce Criterion calculation. This is a convenient way of calling RaveStaticstics.peirceCriterion().outliers(data)
* @param (Array) data The set of data to find outliers for.
* @return (Array) Indexes of statistical outliers within 'data'.
*/
/** @expose */
outliers : function(data) {
return this.peirceCriterion().outliers(data);
}
//constructor : function() {}
});
com_ibm_rave_ext_statistics_RaveStatistics.getRegistrationStatus = function() {
var registrationStatus = rave['internal']['RaveContextManager'].INSTANCE.getRaveContext().getData("RAVESTATISTICS_EXTENSION_REGISTRATION_STATUS_KEY");
if (!registrationStatus) {
registrationStatus = new com_ibm_rave_ext_statistics_RaveStatistics.RegistrationStatus();
rave['internal']['RaveContextManager'].INSTANCE.getRaveContext().putData("RAVESTATISTICS_EXTENSION_REGISTRATION_STATUS_KEY", registrationStatus);
}
return registrationStatus;
};
/**
* Register all extended statistics functionality.
* @return (boolean) true if registration was successful, false otherwise
*/
/** @expose */
com_ibm_rave_ext_statistics_RaveStatistics.init = function() {
var registrationStatus = com_ibm_rave_ext_statistics_RaveStatistics.getRegistrationStatus();
if (!registrationStatus.registered) {
registrationStatus.registered = rave.capabilities.extension("statistics", function() {
return new com_ibm_rave_ext_statistics_RaveStatistics();
});
}
return registrationStatus.registered;
};
com_ibm_rave_ext_statistics_RaveStatistics.RegistrationStatus = rave['internal']['Declare']({
registered : false
});
/** @expose */
com_ibm_rave_ext_statistics_RaveStatistics.STATISTICS = "statistics";
//com_ibm_rave_ext_statistics_RaveStatistics.EXTENSION_REGISTRATION_STATUS_KEY = "RAVESTATISTICS_EXTENSION_REGISTRATION_STATUS_KEY";
// Auto initialization
com_ibm_rave_ext_statistics_RaveStatistics.init();
if (!rave.capabilities["statistics"]) {
rave.capabilities["statistics"] = function() {
return new com_ibm_rave_ext_statistics_RaveStatistics();
};
} else {
console.log("Could not register extension: RaveStatistics");
}
// $source: com/ibm/rave/ext/statistics/outliersUtility/RaveOutlier
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
/**
* Abstract class that describes an outlier utility. All outlier algorithms should follow this interface.
*/
var com_ibm_rave_ext_statistics_outliersUtility_RaveOutlier = rave['internal']['Declare']({
//_value : null,
constructor : function() {
this._value = com_ibm_rave_ext_statistics_outliersUtility_RaveOutlier.VALUE;
},
/**
* sets the function for computing data values, function that will be called by the outlier class to get the data values
* @param (rave['internal']['ValueFunction']) valueFn The function for computing data values
* @return (com.ibm.rave.ext.statistics.outliersUtility.RaveOutlier) this outlier instance
*/
value$0 : function(valueFn) {
this._value = valueFn;
return this;
},
/**
* gets the data value function
* @return (rave['internal']['ValueFunction']) the value function
*/
value$1 : function() {
return this._value;
},
/**
* Returns a list containing the indices of potential outliers within the dataset according to the implemented algorithm. The data set is processed and any element that deviates greater than the allowable maximum deviation is flagged as an outlier.
* @param (Array) data of data objects. Must be either a number or an object type that can be converted into a number (Date, String).
* @return (Array) ArrayEx of outliers of this dataset. Each element is an index into the original data set. This list is simply a collection of all the outliers' indices and is not guaranteed to be in any significant order.
*/
/** @expose */
outliers : function(data) {},
/** @expose */
value : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.value$1();
}
return this.value$0(a0);
}
});
/**
* Default value function for value calculation.
*/
com_ibm_rave_ext_statistics_outliersUtility_RaveOutlier.VALUE = function(data, index, groupIndex) {
return + (data);
};
// $source: com/ibm/rave/ext/text/TextExtensions
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
//@import com/ibm/rave/ext/text/wrap/TextFlow (runtime) // new
//@import com/ibm/rave/ext/text/nativeImpl/FontChecker (runtime) // new
/**
* Common text extensions initializer class
*/
var com_ibm_rave_ext_text_TextExtensions = rave['internal']['Declare']({
});
com_ibm_rave_ext_text_TextExtensions.getRegistrationStatus = function() {
var registrationStatus = rave['internal']['RaveContextManager'].INSTANCE.getRaveContext().getData("TEXTEXTENSIONS_EXTENSION_REGISTRATION_STATUS_KEY");
if (!registrationStatus) {
registrationStatus = new com_ibm_rave_ext_text_TextExtensions.RegistrationStatus();
rave['internal']['RaveContextManager'].INSTANCE.getRaveContext().putData("TEXTEXTENSIONS_EXTENSION_REGISTRATION_STATUS_KEY", registrationStatus);
}
return registrationStatus;
};
/** @expose */
com_ibm_rave_ext_text_TextExtensions.init = function() {
var registrationStatus = com_ibm_rave_ext_text_TextExtensions.getRegistrationStatus();
if (!registrationStatus.registered) {
registrationStatus.registered &= rave.capabilities.extension("textflow", function() {
return new com_ibm_rave_ext_text_wrap_TextFlow();
});
registrationStatus.registered &= rave.capabilities.extension(com_ibm_rave_ext_text_TextExtensions.FONTCHECKER_EXTENSION, function() {
return new com_ibm_rave_ext_text_nativeImpl_FontChecker();
});
}
return registrationStatus.registered;
};
com_ibm_rave_ext_text_TextExtensions.RegistrationStatus = rave['internal']['Declare']({
registered : false
});
com_ibm_rave_ext_text_TextExtensions.TEXTFLOW_EXTENSION = "textflow";
com_ibm_rave_ext_text_TextExtensions.FONTCHECKER_EXTENSION = "fontchecker";
//com_ibm_rave_ext_text_TextExtensions.EXTENSION_REGISTRATION_STATUS_KEY = "TEXTEXTENSIONS_EXTENSION_REGISTRATION_STATUS_KEY";
// Auto initialization
com_ibm_rave_ext_text_TextExtensions.init();
if (!rave.capabilities["textflow"]) {
rave.capabilities["textflow"] = function() {
return new com_ibm_rave_ext_text_wrap_TextFlow();
};
} else {
console.log("Could not register extension: TextExtensions");
}
if (!rave.capabilities[com_ibm_rave_ext_text_TextExtensions.FONTCHECKER_EXTENSION]) {
rave.capabilities[com_ibm_rave_ext_text_TextExtensions.FONTCHECKER_EXTENSION] = function() {
return new com_ibm_rave_ext_text_nativeImpl_FontChecker();
};
} else {
console.log("Could not register extension: TextExtensions");
}
// $source: com/ibm/rave/ext/text/wrap/TextFlow
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
//@import com/ibm/rave/ext/text/nativeImpl/FontChecker (runtime) // new
//@import com/ibm/rave/ext/text/internal/wrap/TextOperation (runtime) // getOperation
//@import com/ibm/rave/ext/text/internal/wrap/FontStyleStruct (runtime) // new
/**
* A text wrapping, truncating and fitting function operating on a selection of text nodes Example usage: RunFunction textfitter = Rave.capabilities.extension("textflow"); String text = "Regular expressions are patterns used to match character combinations in strings. In JavaScript, regular expressions are also objects. These patterns are used with the exec and test methods of RegExp, and with the match, replace, search, and split methods of String. This chapter describes JavaScript regular expressions."; Selector svg = Rave.select("body").append("svg").attr("width", 300) .attr("height", 300); svg.selectAll("text") .data(new Integer[] { 0, 150 }) .enter() .append("text") .text(text) .attr("x", new ValueFunction
TextFlow will create tspan children nodes per line of text and set their style attributes as per alignment, padding and other properties configured on the wrapper function. If a property is not configured on the wrapper (e.g. width and height of the desired text extent), the wrapper will use attributes set on the text node itself Wrapper can be accessed through Rave.capabilities.extension("textflow");
and run on the text node selection using call invocation: selection.call(textflow, wrap, fit);
with first argument for wrap (true|false) , and second for fit (true|false). When arguments are omitted, they assumed to be false. Truncation options are set via textOverflow property. If neither wrap, fit or truncation options are indicated, the default behavior is to do nothing Alignments works in a manner similar to align and valign in html, with the text being aligned within the bounding box, closest to the edge specified by the alignment.
*/
var com_ibm_rave_ext_text_wrap_TextFlow = rave['internal']['Declare']({
//_fontChecker : null,
//_overflow_minFn : null,
//_text_overflowFn : null,
//_current_styles : null,
//_alignment : null,
//_alignmentFn : null,
//_valignment : null,
//_valignmentFn : null,
//_padding : null,
//_paddingFn : null,
//_lineSpacing : null,
//_lineSpacingFn : null,
//_extent : null,
//_extentFn : null,
//_maxFontSize : null,
//_maxFontSizeFn : null,
//_minFontSizeFn : null,
_transformMarkerAdded : false,
_wrap : false, _fit : false, _truncate : false,
_drop : true,
_overflow_min : 0,
_text_overflow : "...",
_alignement_set : false,
_minFontSize : 4.0,
_$functionClassMethod : function() {
var _$self = /**
* @see RunFunction#_$self.run(Object, Object...)
*/
function(args) {
if (args !== null || arguments.length > 1){
args = Array.prototype.slice.call(arguments, 0);
}
{
_$self.flow(this);
return null;
}
};
return _$self;
},
constructor : function() {
this._alignment = "left";
this._valignment = "top";
this._padding = com_ibm_rave_ext_text_wrap_TextFlow.DEFAULT_PADDING;
this._extentFn = function(data, index, groupIndex) {
var bBox = this.getBBox();
var css_width = rave.util.parseCSSSize(this.getAttribute("width"));
var width = !css_width ? bBox.width : css_width.value;
var css_heigth = rave.util.parseCSSSize(this.getAttribute("height"));
var height = !css_heigth ? bBox.height : css_heigth.value;
return [width, height];
};
this._maxFontSize = Infinity;
},
/**
* Set fit fail behavior - when fit, wrap, truncate fails text can be dropped completely or left unchanged. This behavior can be toggled on or off. The default is to drop the text which failed to fit
* @param (boolean) drop_lines true to drop text , which failed to fit, false otherwise.
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
dropTextOnFail$0 : function(drop_lines) {
this._drop = drop_lines;
return this;
},
/**
* Returns fit fail behavior - when fit, wrap, truncate fails text can be dropped completely or left unchanged. This behavior can be toggled on or off. The default is to drop text , which failed to fit
* @return (boolean) true to drop text , which failed to fit, false otherwise.
*/
dropTextOnFail$1 : function() {
return this._drop;
},
/**
* Returns wrap functionality flag set to true to wrap lines, false otherwise. Default value is false
* @return (boolean) wrap flag set to true to wrap lines, false otherwise.
*/
wrap$0 : function() {
return this._wrap;
},
/**
* Toggles wrap functionality on and off. Default is set to false
* @param (boolean) wrapping true to toggle wrap functionality on, false to toggle off
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
wrap$1 : function(wrapping) {
this._wrap = wrapping;
return this;
},
/**
* Returns true if fit functionality is on, false otherwise. Default is false
* @return (boolean) true if fit functionality is on, false otherwise.
*/
fit$0 : function() {
return this._fit;
},
/**
* Toggles fit functionality on and off. Default is set to false
* @param (boolean) fitting true to toggle fit functionality on, false otherwise
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
fit$1 : function(fitting) {
this._fit = fitting;
return this;
},
/**
* Returns true if truncate functionality is on, false otherwise
* @return (boolean) true if truncate functionality is on, false otherwise
*/
truncate$0 : function() {
return this._truncate;
},
/**
* Toggles truncation functionality on and off.
* @param (boolean) truncation true to toggle truncation on, false otherwise
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
truncate$1 : function(truncation) {
this._truncate = truncation;
return this;
},
/**
* Sets a node selection based function, which returns minimum string length before ellipses.
* @param (rave['internal']['ValueFunction']) overflowMinFn a node selection based function, which returns minimum string length before ellipses.
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
truncationMinChars$0 : function(overflowMinFn) {
this._overflow_minFn = overflowMinFn;
this._overflow_min = null;
return this;
},
/**
* Returns an integer or a function, which returns minimum string length before ellipses.
* @return (Object) an integer or a function, which returns minimum string length before ellipses.
*/
truncationMinChars$1 : function() {
return !this._overflow_minFn ? this._overflow_min : this._overflow_minFn;
},
/**
* Sets minimum string length before ellipses. If text can not be truncated with minimum characters plus ellipses string, it will be replaced by the ellipses string
* @param (int) minimum minimum string length before ellipses
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
truncationMinChars$2 : function(minimum) {
this._overflow_min = minimum;
this._overflow_minFn = null;
return this;
},
/**
* Sets ellipses string to use for text truncation.
* @param (String) ellipses ellipses string
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
textTruncateIndicator$0 : function(ellipses) {
this._text_overflow = ellipses;
this._text_overflowFn = null;
return this;
},
/**
* Sets ellipses function. The function must return a string , which will be used for text truncation.
* @param (rave['internal']['ValueFunction']) ellipses a function. The function must return a string , which will be used for text truncation
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
textTruncateIndicator$1 : function(ellipses) {
this._text_overflowFn = ellipses;
this._text_overflow = null;
return this;
},
/**
* Returns ellipses string or function. The function takes node selector and it's data as parameters and returns ellipses string, a string , which will be used for text truncation.
* @return (Object) ellipses string or a function. The function must return a string , which will be used for text truncation
*/
textTruncateIndicator$2 : function() {
return this._text_overflow == null ? this._text_overflowFn : this._text_overflow;
},
/**
* Sets constant width and height extent for all nodes in the selection. If the width and height is not explicitly set, a text node's width and height attribute values will be used
* @param (int) width width of the text extent
* @param (int) height height of the text extent
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
extent$0 : function(width, height) {
this._extent = [width, height];
this._extentFn = null;
return this;
},
/**
* Sets a function to access width and height extent of the node in the selection. The function takes text node as a parameter and returns a dimension object with width and height extent for the node.
* @param (rave['internal']['ValueFunction']) extentFn a function, which returns width and height extent of the text node in the selection.
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
extent$1 : function(extentFn) {
this._extentFn = extentFn;
this._extent = null;
return this;
},
/**
* Returns width and height extent for the text or a function to access width and height of the node in the selection. The function takes text node and it's data as a parameter and returns a dimension object with width and height extent for the node.
* @return (Object) width and height extent for the text or a function, which returns width and height extent for the text node
*/
extent$2 : function() {
return !this._extent ? this._extentFn : this._extent;
},
/**
* Set line spacing fraction relative to the font size same for all nodes. E.g. 1.36 will yield a line height of 1.36 of font size. If not set line-height attribute value will be used. If line-height is not set, text node dy attribute value will be used. If dy value is not set, a constant 1.36 line spacing will be applied
* @param (double) lineSpacing line spacing fraction relative to the font size.
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
spacing$0 : function(lineSpacing) {
this._lineSpacing = lineSpacing;
this._lineSpacingFn = null;
return this;
},
/**
* Set a function to access line spacing. The function takes single node selector and it's data as parameters and must return line spacing fraction relative to the font size. E.g. 1.36 will yield a line height of 1.36 of font size. If not set line-height attribute value will be used. If line-height is not set, text node dy attribute value will be used. If dy value is not set, a constant 1.36 line spacing will be applied
* @param (rave['internal']['ValueFunction']) lineSpacingFn a function, which returns line spacing fraction relative to the font size
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
spacing$1 : function(lineSpacingFn) {
this._lineSpacingFn = lineSpacingFn;
this._lineSpacing = null;
return this;
},
/**
* Returns line spacing or a function to access line spacing for individual node. The function takes a text node and it's data as parameters and must return line spacing fraction relative to the font size. E.g. 1.36 will yield a line height of 1.36 of font size. If not set line-height attribute value will be used. If line-height is not set, text node dy attribute value will be used. If dy value is not set, a constant 1.36 line spacing will be applied
* @return (Object) line spacing or a function, which returns line spacing fraction relative to the font size
*/
spacing$2 : function() {
return !this._lineSpacingFn ? this._lineSpacing : this._lineSpacingFn;
},
/**
* Sets text alignment to "left" | "right" | "center" for all nodes in the selection. When alignment is not explicitly set, original alignment will not be affected
* @param (String) h_alignment horizontal alignment value ("left" | "right" | "center")
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
alignment$0 : function(h_alignment) {
if ("center" == h_alignment) {
this._alignment = "center";
} else if ("right" == h_alignment) {
this._alignment = "right";
} else {
this._alignment = "left";
}
this._alignement_set = true;
this._alignmentFn = null;
return this;
},
/**
* Sets alignment function to access horizontal alignment value. The function takes a text node and it's data as parameters and return "left" | "right" | "center" alignment value for the individual node.
* @param (rave['internal']['ValueFunction']) alignmentFn a function, which returns horizontal alignment value as "left" | "right" | "center".
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
alignment$1 : function(alignmentFn) {
this._alignmentFn = alignmentFn;
this._alignement_set = true;
return this;
},
/**
* Returns horizontal alignment string or function to access horizontal alignment value. The function takes a text node and it's data as parameters and return "left" | "right" | "center" alignment value for the individual node.
* @return (Object) horizontal alignment string or function, which returns horizontal alignment value as "left" | "right" | "center"
*/
alignment$2 : function() {
return !this._alignmentFn ? this._alignment : this._alignmentFn;
},
/**
* Sets text vertical alignment for all nodes to "top" | "middle" | "bottom"
* @param (String) v_alignment vertical alignment "top" | "middle" | "bottom"
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
valignment$0 : function(v_alignment) {
if ("middle" == v_alignment) {
this._valignment = "middle";
} else if ("bottom" == v_alignment) {
this._valignment = "bottom";
} else {
this._valignment = "top";
}
this._valignmentFn = null;
return this;
},
/**
* Sets text vertical alignment function. The function takes single node selector and it's data as parameters and returns return a vertical alignment string as "top" | "middle" | "bottom" for the node.
* @param (rave['internal']['ValueFunction']) alignmentFn a function , which must return vertical alignment strings "top", "middle" or "bottom"
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
valignment$1 : function(alignmentFn) {
this._valignmentFn = alignmentFn;
this._valignment = null;
return this;
},
/**
* Returns text vertical alignment string or function. The function takes single node selector and it's data as parameters and returns return a vertical alignment string as "top" | "middle" | "bottom" for the node.
* @return (Object) vertical alignment value "top" | "middle" | "bottom" or function , which returns a vertical alignment string
*/
valignment$2 : function() {
return !this._valignmentFn ? this._valignment : this._valignmentFn;
},
/**
* Run text operation on a selection of SVG text nodes. Depending on parameter values, the operation will wrap, wrap with fit, or fit a string of text on each text node and replace original text with tspan nodes per line of text as children of the original node.
* @param (rave['internal']['Selector']) text node selector, should be of type SVG 'text'
*/
/** @expose */
flow : function(text) {
var wrap = this.wrap(), fit = this.fit(), truncate = this.truncate();
var operation = ((wrap ? 1 : 0) | (fit ? 2 : 0));
var self = this;
if (!this._fontChecker) {
this._fontChecker = new com_ibm_rave_ext_text_nativeImpl_FontChecker();
}
text.each(function(data, index, groupIndex) {
var fontReplaced = self._fontChecker.replaceLimitedFonts(this);
var transform = this.getAttribute("transform");
transform = transform != null ? ""+(transform) : "";
var markerPos = (transform).indexOf(com_ibm_rave_ext_text_wrap_TextFlow.TSPAN_TRANSFORM_MARKER);
if (markerPos != -1) {
if (markerPos == 0) {
this.removeAttribute("transform");
} else {
transform = (transform).substring(0, markerPos);
this.setAttribute("transform", transform);
}
}
self._transformMarkerAdded = false;
var text_operation = self._getOperation(operation, truncate ? this : null, data, index, groupIndex);
if (!text_operation) {
return;
}
text_operation.overflowMin((self._overflow_minFn ? self._overflow_minFn.call(this, data, index, groupIndex) : ~~ (self._overflow_min)));
self._current_styles = this.rave_getComputedStyles();
var insets = self._paddingFn ? self._paddingFn.call(this, data, index, groupIndex) : self._padding;
var bounds = self._getBounds(this, data, index, groupIndex, insets);
text_operation.size(bounds.width, bounds.height);
var font_size = self._calculateFontSize(this, data, index, groupIndex);
text_operation.font(com_ibm_rave_ext_text_wrap_TextFlow.createFontStruct(self._current_styles));
text_operation.fontSize(font_size);
text_operation.maxFontSize(self._maxFontSizeFn ? self._maxFontSizeFn.call(this, data, index, groupIndex) : self._maxFontSize);
text_operation.minFontSize(self._minFontSizeFn ? self._minFontSizeFn.call(this, data, index, groupIndex) : self._minFontSize);
var em = self._calculateSpacing(this, data, index, groupIndex, font_size);
text_operation.em(em);
var text = this.rave_getText();
var rtl = rave.bidi.format.determineDirection(text) == 1;
text_operation.text(text);
var result = text_operation();
var lines = result.lines;
if (lines.length == 0) {
if (self.dropTextOnFail()) {
lines.push("");
} else {
lines.push(this.rave_getText());
}
}
self._applyTextNodeAttributes(bounds.width, bounds.height, this, data, index, groupIndex, insets, rtl);
if (fit || fontReplaced) {
var fontSize = this.rave_getStyle("font-size");
if (fontSize != null && fontSize != "" && !(fontSize == result.font.fontSize)) {
this.rave_setStyle("font", null);
}
this.rave_setStyle("font", result.font.toString(), "important");
}
self._generateTspans(result, bounds, this, data, index, groupIndex, rtl);
});
/*return;*/
},
/** @expose */
_calculateSpacing : function(node, data, index, groupIndex, font_size) {
if (this.spacing() == null) {
var styled_height = rave.util.parseCSSSize(this._current_styles[com_ibm_rave_ext_text_wrap_TextFlow._LINE_HEIGHT]);
var line_height = styled_height ? styled_height.value : 0;
if (line_height > 0) {
return line_height / (font_size == 0 ? 1 : font_size);
}
var dy_attr = rave.util.parseCSSSize(this._current_styles["dy"]);
if (dy_attr) {
return dy_attr.value / font_size;
}
return 1.36;
}
return this._lineSpacingFn ? this._lineSpacingFn.call(node, data, index, groupIndex) : this._lineSpacing;
},
/** @expose */
_calculateFontSize : function(node, data, index, groupIndex) {
var size = rave.util.parseCSSSize(this._current_styles["font-size"]);
var font_size = size ? size.value : node.getBBox().height;
return font_size;
},
/**
* @return (com.ibm.rave.ext.text.internal.wrap.TextOperation) a text operation for the options
*/
/** @expose */
_getOperation : function(operation, node, data, index, groupIndex) {
var overflow;
if (node) {
overflow = this._text_overflowFn ? this._text_overflowFn.call(node, data, index, groupIndex) : this._text_overflow;
}
return com_ibm_rave_ext_text_internal_wrap_TextOperation.getOperation(operation, overflow);
},
/**
* Returns padding insets object or a function to access padding insets. The function takes a single node selector and it's data parameters and returns top, left, bottom, right padding insets for the node
* @return (Object) padding insets or a function, which returns padding insets: top, left, bottom, right
*/
padding$0 : function() {
return !this._padding ? this._paddingFn : this._padding;
},
/**
* Set padding for all nodes in the selection
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
padding$1 : function(top, left, bottom, right) {
this._padding = {};
this._padding["top"] = top;
this._padding["left"] = left;
this._padding["bottom"] = bottom;
this._padding["right"] = right;
this._paddingFn = null;
return this;
},
/**
* Set function to access padding insets. The function takes a single node selector and it's data as parameters and returns top, left, bottom, right padding insets for the node
* @param (rave['internal']['ValueFunction']) paddingFn top, left, bottom, right
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
*/
padding$2 : function(paddingFn) {
this._paddingFn = paddingFn;
this._padding = null;
return this;
},
/**
* Returns minimum font size function. Function takes node selector and it's data as a parameter and returns minimum font size for that text node. Minimum font size is used by the fit functionality
* @return (Object) minimum font size function
* @see this.TextFlow#this.fit()
*/
minFont$0 : function() {
return this._minFontSize == null ? this._minFontSizeFn : this._minFontSize;
},
/**
* Sets minimum font size or a function. Function takes node selector and it's data as a parameter and returns minimum font size for that text node. Minimum font size is used by the fit functionality
* @param (rave['internal']['ValueFunction']) minFontSizeFn
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
* @see this.TextFlow#this.fit()
*/
minFont$1 : function(minFontSizeFn) {
this._minFontSizeFn = minFontSizeFn;
this._minFontSize = null;
return this;
},
/**
* Set minimum font size for all texts in a selection. Minimum font size is used by the fit functionality
* @param (Object) size minimum font size to be used by the fit functionality
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
* @see this.TextFlow#this.fit()
*/
minFont$2 : function(size) {
this._minFontSize = + (size);
this._minFontSizeFn = null;
return this;
},
/**
* Returns maximum font size or a function. Function takes node selector and it's data as a parameter and returns maximum font size for that text node. Maximum font size is used by the fit functionality. If not set, font will be expanded (or contracted) to fit available space
* @return (Object) maximum font size function
* @see this.TextFlow#this.fit()
*/
maxFont$0 : function() {
return !this._maxFontSizeFn ? this._maxFontSize : this._maxFontSizeFn;
},
/**
* Sets maximum font size function. Function takes node selector and it's data as a parameter and returns maximum font size for that text node. Maximum font size is used by the fit functionality.If not set, font will be expanded (or contracted) to fit available space
* @param (rave['internal']['ValueFunction']) fontSizeFn
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
* @see this.TextFlow#this.fit()
*/
maxFont$1 : function(fontSizeFn) {
this._maxFontSizeFn = fontSizeFn;
this._maxFontSize = null;
return this;
},
/**
* Set maximum font size for all texts in a selection. Maximum font size is used by the fit functionality.If not set, font will be expanded (or contracted) to fit available space
* @param (Object) size minimum font size to be used by the fit functionality
* @return (com.ibm.rave.ext.text.wrap.TextFlow) this
* @see this.TextFlow#this.fit()
*/
maxFont$2 : function(size) {
this._maxFontSize = + (size);
this._maxFontSizeFn = null;
return this;
},
_getBounds : function(node, data, index, groupIndex, insets) {
var ext = this._extentFn ? this._extentFn.call(node, data, index, groupIndex) : this._extent;
var size = node.getAttribute("x") != null ? rave.util.parseCSSSize(node.getAttribute("x")) : rave.util.parseCSSSize(this._current_styles["x"]);
var x = !size ? 0 : node.rave_getSizePx(size);
size = node.getAttribute("y") != null ? rave.util.parseCSSSize(node.getAttribute("y")) : rave.util.parseCSSSize(this._current_styles["y"]);
var y = !size ? 0 : node.rave_getSizePx(size);
var width = ext[0] - insets["left"] - insets["right"], height = ext[1] - insets["top"] - insets["bottom"];
return new com_ibm_rave_ext_text_wrap_TextFlow.Bounds(x, y, width, height);
},
_applyTextNodeAttributes : function(width, height, node, data, index, groupIndex, insets, rtl) {
var transform = node.getAttribute("transform");
transform = transform != null ? ""+(transform) : "";
if (insets["left"] != 0 || insets["top"] != 0) {
node.setAttribute("transform", (transform).concat(this._transformMarker() + " translate(" + insets["left"] + "," + insets["top"] + ")"));
}
node.rave_setText(null);
if (rtl) {
node.rave_setStyle(com_ibm_rave_ext_text_wrap_TextFlow._BIDI, com_ibm_rave_ext_text_wrap_TextFlow._BIDI_OVERRIDE);
node.rave_setStyle("direction", "ltr");
}
var h_align = this._alignmentFn ? this._alignmentFn.call(node, data, index, groupIndex) : this._alignment;
var align_rtl = rtl && !this._alignement_set;
if (h_align == "right" || align_rtl) {
node.rave_setStyle(com_ibm_rave_ext_text_wrap_TextFlow._H_ALIGN, "end");
node.setAttribute("transform", (transform).concat(this._transformMarker() + " translate(" + width + ",0)"));
} else if (h_align == "center") {
node.rave_setStyle(com_ibm_rave_ext_text_wrap_TextFlow._H_ALIGN, "middle");
node.setAttribute("transform", (transform).concat(this._transformMarker() + " translate(" + width / 2 + ",0)"));
}
},
/**
* Ensure that the TSPAN_TRANSFORM_MARKER is only added once for the first transform added to the attributes. On subsequent calls, a blank string is returned.
* @return (String) the TSPAN_TRANSFORM_MARKER on the first call, an empty string after
*/
_transformMarker : function() {
if (!this._transformMarkerAdded) {
this._transformMarkerAdded = true;
return com_ibm_rave_ext_text_wrap_TextFlow.TSPAN_TRANSFORM_MARKER;
}
return "";
},
_generateTspans : function(result, bounds, node, data, index, groupIndex, rtl) {
var text_node = rave.select(node);
var lines = result.lines;
var _height = 0;
var dy = result.lineHeight;
for (var n = 0; n < lines.length && _height < bounds.height; ++n) {
var line = lines[n];
var tspan = text_node.append("tspan").attr("name", "line#" + n).attr("width", bounds.width).attr("x", bounds.x).text(line);
var recomputeStyles = function(data, index, groupIndex) {
this.rave_getComputedStyles();
};
tspan.each(recomputeStyles);
tspan.call(this._fontChecker);
if (n != 0) {
tspan.attr("dy", dy);
}
if (rtl) {
tspan.attr(com_ibm_rave_ext_text_wrap_TextFlow._BIDI, "embed");
text_node.append("tspan").text("\n");
}
_height += result.lineHeight;
}
var v_align = this._valignmentFn ? this._valignmentFn.call(node, data, index, groupIndex) : this._valignment;
if (v_align == "top") {
return;
}
var transform = node.getAttribute("transform");
transform = transform != null ? ""+(transform) : "";
var delta_y = bounds.height - _height;
if (v_align == "middle") {
node.setAttribute("transform", (transform).concat(this._transformMarker() + " translate(0," + delta_y / 2 + ")"));
return;
}
node.setAttribute("transform", (transform).concat(this._transformMarker() + " translate(0," + delta_y + ")"));
},
/** @expose */
dropTextOnFail : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.dropTextOnFail$1();
}
return this.dropTextOnFail$0(a0);
},
/** @expose */
wrap : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.wrap$0();
}
return this.wrap$1(a0);
},
/** @expose */
fit : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.fit$0();
}
return this.fit$1(a0);
},
/** @expose */
truncate : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.truncate$0();
}
return this.truncate$1(a0);
},
/** @expose */
truncationMinChars : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.truncationMinChars$1();
}
if (args.length == 1 && typeof a0 === "function") {
return this.truncationMinChars$0(a0);
}
return this.truncationMinChars$2(a0);
},
/** @expose */
textTruncateIndicator : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.textTruncateIndicator$2();
}
if (args.length == 1 && (a0 == null || typeof a0 === "string")) {
return this.textTruncateIndicator$0(a0);
}
return this.textTruncateIndicator$1(a0);
},
/** @expose */
extent : function(a0, a1) {
var args = arguments;
if (args.length == 0) {
return this.extent$2();
}
if (args.length == 1) {
return this.extent$1(a0);
}
return this.extent$0(a0, a1);
},
/** @expose */
spacing : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.spacing$2();
}
if (args.length == 1 && typeof a0 === "function") {
return this.spacing$1(a0);
}
return this.spacing$0(a0);
},
/** @expose */
alignment : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.alignment$2();
}
if (args.length == 1 && (a0 == null || typeof a0 === "string")) {
return this.alignment$0(a0);
}
return this.alignment$1(a0);
},
/** @expose */
valignment : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.valignment$2();
}
if (args.length == 1 && (a0 == null || typeof a0 === "string")) {
return this.valignment$0(a0);
}
return this.valignment$1(a0);
},
/** @expose */
padding : function(a0, a1, a2, a3) {
var args = arguments;
if (args.length == 0) {
return this.padding$0();
}
if (args.length == 1) {
return this.padding$2(a0);
}
return this.padding$1(a0, a1, a2, a3);
},
/** @expose */
minFont : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.minFont$0();
}
if (args.length == 1 && typeof a0 === "function") {
return this.minFont$1(a0);
}
return this.minFont$2(a0);
},
/** @expose */
maxFont : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.maxFont$0();
}
if (args.length == 1 && typeof a0 === "function") {
return this.maxFont$1(a0);
}
return this.maxFont$2(a0);
}
});
/**
* @return (Object) 0 insets object
*/
com_ibm_rave_ext_text_wrap_TextFlow._createInsets = function() {
var result = {};
result["top"] = 0;
result["left"] = 0;
result["bottom"] = 0;
result["right"] = 0;
return result;
};
com_ibm_rave_ext_text_wrap_TextFlow.createFontStruct = function(style) {
var struct = new com_ibm_rave_ext_text_internal_wrap_FontStyleStruct();
struct.fontStyle = style["font-style"];
struct.fontVariant = style[com_ibm_rave_ext_text_wrap_TextFlow.FONT_VARIANT];
struct.fontWeight = style[com_ibm_rave_ext_text_wrap_TextFlow.FONT_WEIGHT];
struct.fontSize = style["font-size"];
struct.lineHeight = style[com_ibm_rave_ext_text_wrap_TextFlow.LINE_HEIGHT];
struct.fontFamily = style[com_ibm_rave_ext_text_wrap_TextFlow.FONT_FAMILY];
return struct;
};
com_ibm_rave_ext_text_wrap_TextFlow.Bounds = rave['internal']['Declare']({
/** @expose */
x : 0,
/** @expose */
y : 0,
/** @expose */
width : 0,
/** @expose */
height : 0,
/** @expose */
constructor : function(x, y, width, height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}
});
/**
* Alignment center
*/
/** @expose */
com_ibm_rave_ext_text_wrap_TextFlow.CENTER = "center";
/**
* Alignment right
*/
/** @expose */
com_ibm_rave_ext_text_wrap_TextFlow.RIGHT = "right";
/**
* Alignment left
*/
/** @expose */
com_ibm_rave_ext_text_wrap_TextFlow.LEFT = "left";
/**
* Vertical alignment text baseline
*/
/** @expose */
com_ibm_rave_ext_text_wrap_TextFlow.TOP = "top";
/**
* Vertical alignment text baseline bottom
*/
/** @expose */
com_ibm_rave_ext_text_wrap_TextFlow.BOTTOM = "bottom";
/**
* Vertical alignment text baseline middle
*/
/** @expose */
com_ibm_rave_ext_text_wrap_TextFlow.MIDDLE = "middle";
/**
* real alignment values
*/
com_ibm_rave_ext_text_wrap_TextFlow._CENTER = "middle";
com_ibm_rave_ext_text_wrap_TextFlow._RIGHT = "end";
com_ibm_rave_ext_text_wrap_TextFlow._LEFT = "start";
com_ibm_rave_ext_text_wrap_TextFlow._DY = "dy";
com_ibm_rave_ext_text_wrap_TextFlow._FONT_SIZE = "font-size";
com_ibm_rave_ext_text_wrap_TextFlow._FONT = "font";
com_ibm_rave_ext_text_wrap_TextFlow._LINE_HEIGHT = "line-height";
com_ibm_rave_ext_text_wrap_TextFlow._WIDTH = "width";
com_ibm_rave_ext_text_wrap_TextFlow._HEIGHT = "height";
com_ibm_rave_ext_text_wrap_TextFlow._X = "x";
com_ibm_rave_ext_text_wrap_TextFlow._Y = "y";
com_ibm_rave_ext_text_wrap_TextFlow._H_ALIGN = "text-anchor";
com_ibm_rave_ext_text_wrap_TextFlow._V_ALIGN = "alignment-baseline";
com_ibm_rave_ext_text_wrap_TextFlow._BIDI = "unicode-bidi";
com_ibm_rave_ext_text_wrap_TextFlow._BIDI_EMBED = "embed";
com_ibm_rave_ext_text_wrap_TextFlow._BIDI_OVERRIDE = "bidi-override";
com_ibm_rave_ext_text_wrap_TextFlow._DIRECTION = "direction";
com_ibm_rave_ext_text_wrap_TextFlow._LTR = "ltr";
com_ibm_rave_ext_text_wrap_TextFlow._NAME = "name";
com_ibm_rave_ext_text_wrap_TextFlow._TRANSFORM = "transform";
com_ibm_rave_ext_text_wrap_TextFlow._TSPAN = "tspan";
com_ibm_rave_ext_text_wrap_TextFlow.FONT_STYLE = "font-style";
com_ibm_rave_ext_text_wrap_TextFlow.FONT_VARIANT = "font-variant";
com_ibm_rave_ext_text_wrap_TextFlow.FONT_WEIGHT = "font-weight";
com_ibm_rave_ext_text_wrap_TextFlow.FONT_SIZE = "font-size";
com_ibm_rave_ext_text_wrap_TextFlow.LINE_HEIGHT = "line-height";
com_ibm_rave_ext_text_wrap_TextFlow.FONT_FAMILY = "font-family";
/** @expose */
com_ibm_rave_ext_text_wrap_TextFlow.TSPAN_TRANSFORM_MARKER = " translate(0.0000,0.0000)";
com_ibm_rave_ext_text_wrap_TextFlow.EM = 1.36;
com_ibm_rave_ext_text_wrap_TextFlow.DEFAULT_PADDING = com_ibm_rave_ext_text_wrap_TextFlow._createInsets();
// $source: com/ibm/rave/ext/text/nativeImpl/FontChecker
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2016, 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
var com_ibm_rave_ext_text_nativeImpl_FontChecker = rave['internal']['Declare']({
_$functionClassMethod : function() {
var _$self = /**
* @see RunFunction#_$self.run(Object, Object...)
*/
function(args) {
return null;
};
return _$self;
},
constructor : function() {
},
/** @expose */
replaceLimitedFonts : function(textNode) {
return false;
},
/** @expose */
nodeFontChecker : function(data, index, groupIndex) {
}
});
// $source: com/ibm/rave/ext/text/internal/wrap/TextOperation
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
//@import com/ibm/rave/ext/text/internal/wrap/FontStyleStruct (runtime) // new
//@import com/ibm/rave/ext/text/internal/nativeImpl/WordSplitter (runtime) // spaceBasedSplit
//@import com/ibm/rave/ext/text/internal/wrap/TextData (runtime) // new
//@import com/ibm/rave/ext/text/internal/wrap/WrapOperation (runtime) // new
//@import com/ibm/rave/ext/text/internal/wrap/FitOperation (runtime) // new
//@import com/ibm/rave/ext/text/internal/wrap/FitWrapOperation (runtime) // new
//@import com/ibm/rave/ext/text/internal/wrap/TruncateOperation (runtime) // new
/**
* Text operation wraps a single text into a width and height provided. Text operations are internal utilities for text wrapping, fitting and truncation. wrapping utility can be accessed via: Rave.capabilities.extension("_textwrap");
*/
var com_ibm_rave_ext_text_internal_wrap_TextOperation = rave['internal']['Declare']({
//_context : null,
//_text : null,
//_font : null,
_width : 0,
_height : 0,
_ems : 1,
_maxFontSize : Infinity,
_fontSize : 10,
_minFontSize : 4,
_textOverflow : "...",
_overflowMin : 0,
_$functionClassMethod : function() {
var _$self = /**
* Runs text operation, returns TextData data structure containing the result of operation and other properties, which explain the result (e.g. truncate or clip flags toggled on, fonts being used, etc)
* @return (com.ibm.rave.ext.text.internal.wrap.TextData) returns TextData data structure containing the result of operation
*/
function() {
var lines = new com_ibm_rave_ext_text_internal_wrap_TextData();
lines.font = _$self._font;
if (_$self._runPrecondition()) {
return lines;
}
_$self._doRun(lines);
if (_$self._context) {
rave.canvas.disposeContext(_$self._context);
_$self._context = null;
}
return lines;
};
return _$self;
},
constructor : function() {
this._font = new com_ibm_rave_ext_text_internal_wrap_FontStyleStruct();
},
/**
* Create new text operation to wrap the text
* @param (String) text text to wrap
*/
text : function(text) {
this._text = text;
return this;
},
/**
* Set width and height of the bounding rectangle to limit the text
* @param (double) width text bounding rectangle width
* @param (double) height text bounding rectangle height
* @return (com.ibm.rave.ext.text.internal.wrap.TextOperation) this
*/
size : function(width, height) {
this._width = width;
this._height = height;
return this;
},
/**
* Set font to a struct of the following 6 properties: font-style font-variant font-weight font-size/line-height font-family. see https://developer.mozilla.org/en-US/docs/Web/CSS/font
* @param (com.ibm.rave.ext.text.internal.wrap.FontStyleStruct) font struct representing a font
* @return (com.ibm.rave.ext.text.internal.wrap.TextOperation) this
*/
font : function(font) {
this._font = font;
return this;
},
/**
* Set font size to line size ratio. E.g. ems of 1.5 will make line height 1.5 times of the font size
* @param (double) ems font size to line size ratio. E.g. ems of 1.5 will make line height 1.5 times of the font size
* @return (com.ibm.rave.ext.text.internal.wrap.TextOperation) this
*/
em : function(ems) {
this._ems = ems;
return this;
},
/**
* Set preferred font size in pixels
* @param (double) size font size in pixels
* @return (com.ibm.rave.ext.text.internal.wrap.TextOperation) this
*/
maxFontSize : function(size) {
this._maxFontSize = size;
return this;
},
/**
* Set preferred font size in pixels
* @param (double) size font size in pixels
* @return (com.ibm.rave.ext.text.internal.wrap.TextOperation) this
*/
fontSize : function(size) {
this._fontSize = size;
return this;
},
/**
* Set minimum font size to be used while performing fit
* @param (double) size minimum font size to be used by fit
* @return (com.ibm.rave.ext.text.internal.wrap.TextOperation) this
*/
minFontSize : function(size) {
this._minFontSize = size;
return this;
},
/**
* @return (boolean) condition that would prevent run
*/
_runPrecondition : function() {
return this._text == null || this._fontSize > this._height || this._text.length === 0;
},
/**
* Create rendering context, used to measure text width
*/
createContext : function() {
this._context = rave.canvas.create(2, 2).getContext("2d");
},
_measureText : function(text) {
return this._context.measureText(text)["width"];
},
_forceFontSize : function(size, font) {
font.fontSize = size + "px";
},
_truncate : function() {
return this._textOverflow != null;
},
_clip$0 : function() {
return !(this._truncate());
},
_truncateOrClip : function(testLine, lines) {
var truncate = this._truncate();
var line = truncate ? this._ellipsize(testLine, lines) : this._clip$1(testLine, lines);
if (line == null || line.length === 0) {
return line;
}
lines.add(line);
return line;
},
/**
* @param (String) text string to clip to fit the max width
* @return (String) clipped string
*/
_clip$1 : function(text, lines) {
lines.truncated = false;
var index = text.length;
if (index == 0) {
lines.clipped = false;
return text;
}
var testLine = text.substring(0, index);
while (this._measureText(testLine) > this._width && --index > 0) {
testLine = testLine.substring(0, index);
lines.clipped = true;
}
return testLine;
},
_doEllipsize : function(text, lines) {
var marker = text.length;
marker = marker < this._overflowMin ? 0 : marker;
var testLine = text.substring(0, marker) + " ";
marker = marker + 1;
var exit = false;
while (this._measureText(testLine.concat(this._textOverflow)) > this._width && !exit) {
marker--;
if (marker < this._overflowMin) {
marker = 0;
exit = true;
}
testLine = testLine.substring(0, marker);
}
if (this._measureText(testLine.concat(this._textOverflow)) > this._width) {
lines.truncated = false;
return null;
}
lines.truncated = true;
return testLine.concat(this._textOverflow);
},
/**
* Returns truncated text, or null, if not enough space. Text is truncated with ellipses set by textOverflow
* @param (String) text text to truncate
* @return (String) truncated text
* @see #this.textOverflow(String)
*/
_ellipsize : function(text, lines) {
lines.clipped = false;
if (this._measureText(text) <= this._width) {
lines.truncated = false;
return text;
}
return this._doEllipsize(text, lines);
},
/**
* @param (String) _overflow ellipses string to be used for text truncation
*/
textOverflow : function(_overflow) {
this._textOverflow = _overflow;
},
/**
* @param (int) _min a minimum string length before ellipses
*/
overflowMin : function(_min) {
this._overflowMin = Math.abs(_min);
},
/**
* Init line height based on font size and assign font to rendering context
* @param (com.ibm.rave.ext.text.internal.wrap.TextData) lines data structure to hold the result of the text operation
*/
_initFont : function(lines, font, font_size) {
lines.lineHeight = Math.ceil(font_size * this._ems);
this._context.font = font.toString();
},
_splitTextIntoWords : function(_text) {
return com_ibm_rave_ext_text_internal_nativeImpl_WordSplitter.spaceBasedSplit(_text);
},
_clip : function(a0, a1) {
var args = arguments;
if (args.length == 0) {
return this._clip$0();
}
return this._clip$1(a0, a1);
}
/**
* Run text operation
*/
//_doRun : function(lines) {}
});
/**
* A factory method that creates a text operation based on option passed
* @param (byte) operation WRAP, FIT, or WRAP_FIT
* @param (String) text_overflow truncation options : value of 'text-overflow' attribute
* @return (com.ibm.rave.ext.text.internal.wrap.TextOperation) an instance of text operation with truncation options to wrap, fit, or wrap-fit
*/
com_ibm_rave_ext_text_internal_wrap_TextOperation.getOperation = function(operation, text_overflow) {
switch (operation) {
case 1:
{
var fitter = new com_ibm_rave_ext_text_internal_wrap_WrapOperation();
fitter.textOverflow(text_overflow);
return fitter;
} case 2:
{
var fitter = new com_ibm_rave_ext_text_internal_wrap_FitOperation();
fitter.textOverflow(text_overflow);
return fitter;
} case 3:
{
var fitter = new com_ibm_rave_ext_text_internal_wrap_FitWrapOperation();
fitter.textOverflow(text_overflow);
return fitter;
} default:
if (text_overflow != null) {
var fitter = new com_ibm_rave_ext_text_internal_wrap_TruncateOperation();
fitter.textOverflow(text_overflow);
return fitter;
}
}
return null;
};
/**
* no operation
*/
com_ibm_rave_ext_text_internal_wrap_TextOperation.NONE = 0;
/**
* WRAP operation
*/
com_ibm_rave_ext_text_internal_wrap_TextOperation.WRAP = 1;
/**
* FIR operation
*/
com_ibm_rave_ext_text_internal_wrap_TextOperation.FIT = 1 << 1;
/**
* WRAP and FIR operation
*/
com_ibm_rave_ext_text_internal_wrap_TextOperation.WRAP_FIT = 1 | 2;
// $source: com/ibm/rave/ext/text/internal/wrap/FontStyleStruct
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
/**
* An internal struct that mimics a CSS font's properties. Has a toString() method that will return a shorthand font string in this format: font-style font-variant font-weight font-size/line-height font-family
*/
var com_ibm_rave_ext_text_internal_wrap_FontStyleStruct = rave['internal']['Declare']({
fontStyle : "normal",
fontVariant : "normal",
fontWeight : "normal",
fontSize : "10px",
lineHeight : "normal",
fontFamily : "'sans serif'",
toString : function() {
return this.fontStyle + " " + this.fontVariant + " " + this.fontWeight + " " + this.fontSize + "/" + this.lineHeight + " " + this.fontFamily;
}
});
// $source: com/ibm/rave/ext/text/internal/nativeImpl/WordSplitter
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2015, 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
var com_ibm_rave_ext_text_internal_nativeImpl_WordSplitter = rave['internal']['Declare']({
});
/** @expose */
com_ibm_rave_ext_text_internal_nativeImpl_WordSplitter.spaceBasedSplit = function(text) {
return text.split(/\s/);
};
/** @expose */
com_ibm_rave_ext_text_internal_nativeImpl_WordSplitter.isWhitespace = function(item) {
// return item == ' ' || item == '\t' || item == '\n' || item == '\r';
return item == 32 || item == 9 || item == 13 || item == 10;
};
// $source: com/ibm/rave/ext/text/internal/wrap/TextData
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
/**
* Data structure that stores data for wrapped text lines
*/
var com_ibm_rave_ext_text_internal_wrap_TextData = rave['internal']['Declare']({
/**
* Lines array
*/
//lines : null,
/**
* font used for wrap-truncate-fit
*/
//font : null,
/**
* true if text was truncated, false otherwise
*/
truncated : false,
/**
* true if text was clipped, false otherwise
*/
clipped : false,
/**
* true if text was too tall for the height. As the result it will either be clipped or truncated
*/
tooTall : false,
/**
* line height (dy offset) between the lines
*/
lineHeight : 0,
/**
* font size used in text operation
*/
fontSize : 0,
constructor : function() {
this.lines = [];
},
/**
* @param (String) line line text string
*/
add : function(line) {
this.lines.push(line);
},
/**
* @return (int) number of lines
*/
length : function() {
return this.lines.length;
}
});
// $source: com/ibm/rave/ext/text/internal/nativeImpl/TextLength
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2016
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
var com_ibm_rave_ext_text_internal_nativeImpl_TextLength = rave['internal']['Declare']({
});
/** @expose */
com_ibm_rave_ext_text_internal_nativeImpl_TextLength.getTenPtLength = function(text, fontStr, fontStyle) {
// re-use canvas object for better performance
var canvas = this.canvas || (this.canvas = document.createElement("canvas"));
var context = canvas.getContext("2d");
context.font = fontStyle + " 10px " + fontStr;
var metrics = context.measureText(text);
return metrics.width;
};
// $source: com/ibm/rave/ext/geo/tile/TileLayout
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
/**
* A layout for determining which 256x256 quadtree tiles to display in a rectangular viewport, based on a scale and translate. This layout can be used to create a simple slippy map, or render standard map tiles (e.g., MapBox, CloudMade) as a base layer behind a geographic projection.
*/
var com_ibm_rave_ext_geo_tile_TileLayout = rave['internal']['Declare']({
//sizeVal : null,
//translateVal : null,
scaleVal : 256,
zoomDeltaVal : 0,
_$functionClassMethod : function() {
var _$self = /**
* Runs the tile algorithm
* @return (com.ibm.rave.ext.geo.tile.TileLayout.TilesData) the tiles data generated, @see {@link (com.ibm.rave.ext.geo.tile.TileLayout.TilesData) TilesData}
*/
function() {
var tiles = new com_ibm_rave_ext_geo_tile_TileLayout.TilesData();
var z = Math.max(Math.log(_$self.scaleVal) / Math["LN2"] - 8, 0);
var z0 = Math.round(z + _$self.zoomDeltaVal);
var k = Math.pow(2, z - z0 + 8);
var origin = [(_$self.translateVal[0] - _$self.scaleVal / 2) / k, (_$self.translateVal[1] - _$self.scaleVal / 2) / k];
var cols = rave.range(Math.max(0, Math.floor(-origin[0])), Math.max(0, Math.ceil(_$self.sizeVal[0] / k - origin[0])));
var rows = rave.range(Math.max(0, Math.floor(-origin[1])), Math.max(0, Math.ceil(_$self.sizeVal[1] / k - origin[1])));
rows.forEach(function(y, index, array) {
cols.forEach(function(x, index, array) {
tiles.push([x, y, z0]);
return null;
});
return null;
});
tiles.translate = origin;
tiles.scale = k;
return tiles;
};
return _$self;
},
constructor : function() {
this.sizeVal = [960, 500];
this.translateVal = [this.sizeVal[0] / 2, this.sizeVal[1] / 2];
},
/**
* Gets the size of the view port used during tiling
* @return (double[]) width and height
*/
size$0 : function() {
return this.sizeVal;
},
/**
* Sets the size of the ViewPort to use during running the tile layout
* @param (double[]) newSize
* @return (com.ibm.rave.ext.geo.tile.TileLayout) this TileLayout instance itself
*/
size$1 : function(newSize) {
this.sizeVal = newSize;
return this;
},
/**
* Returns the current scale factor which defaults to 256
* @return (double) the current scale factor
*/
scale$0 : function() {
return this.scaleVal;
},
/**
* Sets the tile scale factor to the specified value. The scale factor corresponds linearly to the distance between projected points.
* @param (double) newScaleVal the scale factor to set.
* @return (com.ibm.rave.ext.geo.tile.TileLayout) this TileLayout instance itself
*/
scale$1 : function(newScaleVal) {
this.scaleVal = newScaleVal;
return this;
},
/**
* Gets the translate value (the default value is viewPortWidth/2, view portHeight/2)
* @return (double[]) translate value
*/
translate$0 : function() {
return this.translateVal;
},
/**
* Sets the translate value
* @param (double[]) newTranslateVal the new translate value [width,height]
* @return (com.ibm.rave.ext.geo.tile.TileLayout) this layout
*/
translate$1 : function(newTranslateVal) {
this.translateVal = newTranslateVal;
return this;
},
/**
* Gets the current Zoom delta
* @return (double) zoom delta
*/
zoomDelta$0 : function() {
return this.zoomDeltaVal;
},
/**
* Sets the current Zoom Delta
* @param (double) newZoomDeltaVal the new zoom delta
* @return (com.ibm.rave.ext.geo.tile.TileLayout) this layout
*/
zoomDelta$1 : function(newZoomDeltaVal) {
this.zoomDeltaVal = newZoomDeltaVal;
return this;
},
/** @expose */
size : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.size$0();
}
return this.size$1(a0);
},
/** @expose */
scale : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.scale$0();
}
return this.scale$1(a0);
},
/** @expose */
translate : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.translate$0();
}
return this.translate$1(a0);
},
/** @expose */
zoomDelta : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.zoomDelta$0();
}
return this.zoomDelta$1(a0);
}
});
/**
* Simple Array data structure representing a tiles info Each entry represent a tile the data structure contains as well the scale used during the calculations and the translate matrix
*/
com_ibm_rave_ext_geo_tile_TileLayout.TilesData = rave['internal']['Declare'](Array, {
/** @expose */
translate : null,
/** @expose */
scale : 0
});
// $source: com/ibm/rave/ext/geo/tile/TiledMapGenerator
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
//@import com/ibm/rave/ext/geo/RaveGeo (runtime) // tile
/**
* High Level component to make it easier to build a tiled map visualization The default implementation follows the WMTS (Web Map Tile Service) standard to build URLS for the different tiles, but users can provide their own url generator function if they want to use a tile provider that does not follow this standard.
*/
var com_ibm_rave_ext_geo_tile_TiledMapGenerator = rave['internal']['Declare']({
//centerPointVal : null,
//tileLayout : null,
//vecData : null,
//zoomVal : null,
//projectionVal : null,
//vectorLayer : null,
//path : null,
//providerInfoVal : null,
//zoomExtentVal : null,
//urlBuilderFn : null,
widthVal : 960,
heightVal : 960,
projectionScaleVal : 1 << 21,
_$functionClassMethod : function() {
var _$self = function(args) {
if (args !== null || arguments.length > 1){
args = Array.prototype.slice.call(arguments, 0);
}
{
_$self.createTiles(args[0]);
return null;
}
};
return _$self;
},
constructor : function() {
this.centerPointVal = [-100, 40];
this.zoomExtentVal = [0, Infinity];
this.urlBuilderFn = com_ibm_rave_ext_geo_tile_TiledMapGenerator.DEFAULT_URL_GEN;
},
/** @expose */
createTiles : function(selector) {
this.tileLayout = com_ibm_rave_ext_geo_RaveGeo.tile().size([this.widthVal, this.heightVal]);
this.projectionVal = rave.geo.mercator().scale(this.projectionScaleVal / 2 / Math.PI).translate([-this.widthVal / 2, -this.heightVal / 2]);
var projectedCenetr = this.projectionVal([this.centerPointVal[0], this.centerPointVal[1]]);
this.path = rave.geo.path().projection(this.projectionVal);
if (!this.zoomVal) {
this.zoomVal = rave.behavior.zoom();
}
var invertedCenter = projectedCenetr.map(function(currentValue, index, array) {
return -1 * currentValue;
});
this.zoomVal.scale(this.projectionVal.scale() * 2 * Math.PI).scaleExtent([this.zoomExtentVal[0], this.zoomExtentVal[1]]).translate([invertedCenter[0], invertedCenter[1]]);
var outer = this;
var zoomedFn = function(args) {
if (args !== null || arguments.length > 1){
args = Array.prototype.slice.call(arguments, 0);
}
{
var translatePoint = outer.zoomVal.translate();
var arrayExVal = [translatePoint[0], translatePoint[1]];
var zoomScale = outer.zoomVal.scale();
outer.tileLayout.scale(zoomScale).translate([translatePoint[0], translatePoint[1]]);
outer.projectionVal.scale(zoomScale / 2 / Math.PI).translate(arrayExVal);
var tiles = outer.tileLayout();
if (outer.vectorLayer) {
outer.vectorLayer.attr("d", outer.path);
}
var groups = selector.selectAll("g." + com_ibm_rave_ext_geo_tile_TiledMapGenerator.CONTAINER_CLASS).data(outer.providerInfoVal);
groups.exit().remove();
groups.enter().append("g").classed(com_ibm_rave_ext_geo_tile_TiledMapGenerator.CONTAINER_CLASS, true);
groups.each(function(data, index, groupIndex) {
var g = rave.select(this);
var providerInfo = data;
if (providerInfo["type"] == "image") {
outer.handleImages(g, tiles, providerInfo);
} else if (providerInfo["type"] == "path") {
outer.handleVector(g, tiles, providerInfo);
}
});
return null;
}
};
selector.call(this.zoomVal);
zoomedFn.call(null);
this.zoomVal.on("zoom", zoomedFn);
if (this.vecData != null) {
this.vectorLayer = selector.append("path");
this.vectorLayer.datum(this.vecData);
}
},
/**
* Gets the current width
* @return (double) the width
*/
width$0 : function() {
return this.widthVal;
},
/**
* Sets the current width
* @param (double) newVal the new width
* @return (com.ibm.rave.ext.geo.tile.TiledMapGenerator) this tiled Map
*/
width$1 : function(newVal) {
this.widthVal = newVal;
return this;
},
/**
* Gets the current height
* @return (double) the height
*/
height$0 : function() {
return this.heightVal;
},
/**
* Sets the current height
* @param (double) newVal the new height
* @return (com.ibm.rave.ext.geo.tile.TiledMapGenerator) this tiled Map
*/
height$1 : function(newVal) {
this.heightVal = newVal;
return this;
},
/**
* Gets the current scale for the projection
* @return (double) the current projection scale
*/
projectionScale$0 : function() {
return this.projectionScaleVal;
},
/**
* Sets the current scale for the projection
* @param (double) newProjectionScaleVal the new projection scale value
* @return (com.ibm.rave.ext.geo.tile.TiledMapGenerator) this tiled Map
*/
projectionScale$1 : function(newProjectionScaleVal) {
this.projectionScaleVal = newProjectionScaleVal;
return this;
},
/**
* Gets the current providers information {@link (Object) TileProviderInfo}
* @return (com.ibm.rave.ext.geo.tile.TileProviderInfo[]) current providers information
*/
providerInfo$0 : function() {
return this.providerInfoVal;
},
/**
* Sets the current providers information {@link (Object) TileProviderInfo}
* @param (com.ibm.rave.ext.geo.tile.TileProviderInfo[]) newProviderInfoVal An array of provider info to use
* @return (com.ibm.rave.ext.geo.tile.TiledMapGenerator) this tiled Map
*/
providerInfo$1 : function(newProviderInfoVal) {
this.providerInfoVal = newProviderInfoVal;
return this;
},
/**
* Gets the current center for the tiled map in Long/Lat
* @return (double[]) the current center
*/
center$0 : function() {
return this.centerPointVal;
},
/**
* Sets the current center for the tiled map in Long/Lat
* @param (double[]) newCenterPointVal the new center point
* @return (com.ibm.rave.ext.geo.tile.TiledMapGenerator) this tiled Map
*/
center$1 : function(newCenterPointVal) {
this.centerPointVal = newCenterPointVal;
return this;
},
/**
* Gets the current zoom object
* @return (rave['internal']['Zoom']) the current zoom object
*/
zoom$0 : function() {
return this.zoomVal;
},
/**
* Sets the current zoom object
* @param (rave['internal']['Zoom']) newZoomVal The new zoom level
* @return (com.ibm.rave.ext.geo.tile.TiledMapGenerator) this tiled Map
*/
zoom$1 : function(newZoomVal) {
this.zoomVal = newZoomVal;
return this;
},
/**
* Gets the current projection object
* @return (rave['internal']['Projection']) the current projection object
*/
projection$0 : function() {
return this.projectionVal;
},
/**
* Sets the projection
* @param (rave['internal']['Projection']) newProjectionVal The new projection value
* @return (com.ibm.rave.ext.geo.tile.TiledMapGenerator) this tiled Map
*/
projection$1 : function(newProjectionVal) {
this.projectionVal = newProjectionVal;
return this;
},
/**
* Gets the current zoom extent value
* @return (double[]) the current zoom extent
*/
zoomExtent$0 : function() {
return this.zoomExtentVal;
},
/**
* Sets the current zoom extent value, use this API to control the Max and Min zoom level
* @param (double[]) newZoomExtent The new zoom extent value
* @return (com.ibm.rave.ext.geo.tile.TiledMapGenerator) this tiled Map
*/
zoomExtent$1 : function(newZoomExtent) {
this.zoomExtentVal = newZoomExtent;
return this;
},
/**
* Gets the current overlay data
* @return (Object) the current overlay data
*/
vectorOverlayData$0 : function() {
return this.vecData;
},
/**
* Sets the current overlay data
* @param (Object) newVecData The overlay data
* @return (com.ibm.rave.ext.geo.tile.TiledMapGenerator) this tiled Map
*/
vectorOverlayData$1 : function(newVecData) {
this.vecData = newVecData;
return this;
},
/**
* Gets the current URL builder function
* @return (com.ibm.rave.ext.geo.tile.TiledMapGenerator.URLGenerator) the current URL builder function
*/
urlBuilder$0 : function() {
return this.urlBuilderFn;
},
/**
* Sets the current URL builder function
* @param (com.ibm.rave.ext.geo.tile.TiledMapGenerator.URLGenerator) newGen The URL gen function
* @return (com.ibm.rave.ext.geo.tile.TiledMapGenerator) this tiled Map
*/
urlBuilder$1 : function(newGen) {
this.urlBuilderFn = newGen;
return this;
},
handleImages : function(g, tiles, providerInfo) {
var imageSelector = g.attr("transform", "scale(" + tiles.scale + ")translate(" + tiles.translate + ")").selectAll("image").data(tiles, com_ibm_rave_ext_geo_tile_TiledMapGenerator.DATA_FUN);
imageSelector.exit().remove();
var outer = this;
imageSelector.enter().append("image").attr("xlink:href", function(data, index, groupIndex) {
return outer.urlBuilderFn(providerInfo, data);
}).attr("width", 1).attr("height", 1).attr("x", com_ibm_rave_ext_geo_tile_TiledMapGenerator.X_VALUEFUNCTION).attr("y", com_ibm_rave_ext_geo_tile_TiledMapGenerator.Y_VALUEFUNCTION);
},
handleVector : function(g, tiles, providerInfo) {
var tilePath = rave.geo.path().projection(this.projectionVal);
var vectorTiles = g.attr("transform", this.matrix2d(tiles.scale, tiles.translate)).selectAll("g.tile").data(tiles, com_ibm_rave_ext_geo_tile_TiledMapGenerator.DATA_FUN);
vectorTiles.exit().each(function(data, index, groupIndex) {
((this.rave_getProperty("_xhr"))).abort();
}).remove();
var outer = this;
vectorTiles.enter().append("g").attr("class", "tile").attr("transform", com_ibm_rave_ext_geo_tile_TiledMapGenerator.TRANSLATE_FUN).each(function(data, index, groupIndex) {
var current = rave.select(this);
var tileInfo = data;
var url = outer.urlBuilderFn(providerInfo, tileInfo);
this.rave_setProperty("_xhr", rave.json(url, function(error, response) {
var k = Math.pow(2, tileInfo[2]) * 256;
((tilePath.projection())).translate([k / 2 - tileInfo[0] * 256, k / 2 - tileInfo[1] * 256]).scale(k / 2 / Math.PI);
var jsonResponse = response;
var features = jsonResponse["features"];
features.sort(com_ibm_rave_ext_geo_tile_TiledMapGenerator.SORTKEY_COMPARATOR);
current.selectAll("path").data(features).enter().append("path").attr("class", com_ibm_rave_ext_geo_tile_TiledMapGenerator.CLASS_NAME_EXTRACTOR).attr("d", tilePath);
}));
});
},
matrix2d : function(scale, translate) {
var k = scale / 256;
var transform = [k, 0, 0, k, Math.round(translate[0] * scale), Math.round(translate[1] * scale)];
return "matrix(" + (transform) + ")";
},
/** @expose */
width : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.width$0();
}
return this.width$1(a0);
},
/** @expose */
height : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.height$0();
}
return this.height$1(a0);
},
/** @expose */
projectionScale : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.projectionScale$0();
}
return this.projectionScale$1(a0);
},
/** @expose */
providerInfo : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.providerInfo$0();
}
return this.providerInfo$1(a0);
},
/** @expose */
center : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.center$0();
}
return this.center$1(a0);
},
/** @expose */
zoom : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.zoom$0();
}
return this.zoom$1(a0);
},
/** @expose */
projection : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.projection$0();
}
return this.projection$1(a0);
},
/** @expose */
zoomExtent : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.zoomExtent$0();
}
return this.zoomExtent$1(a0);
},
/** @expose */
vectorOverlayData : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.vectorOverlayData$0();
}
return this.vectorOverlayData$1(a0);
},
/** @expose */
urlBuilder : function(a0) {
var args = arguments;
if (args.length == 0) {
return this.urlBuilder$0();
}
return this.urlBuilder$1(a0);
}
});
com_ibm_rave_ext_geo_tile_TiledMapGenerator.TILE_SIZE = 256;
com_ibm_rave_ext_geo_tile_TiledMapGenerator.JSON_KIND = "kind";
com_ibm_rave_ext_geo_tile_TiledMapGenerator.JSON_SORT_KEY = "sort_key";
com_ibm_rave_ext_geo_tile_TiledMapGenerator.JSON_PROPERTIES_FEATURE = "properties";
com_ibm_rave_ext_geo_tile_TiledMapGenerator.TILE_CLASS = "tile";
com_ibm_rave_ext_geo_tile_TiledMapGenerator.TYPE_PATH = "path";
com_ibm_rave_ext_geo_tile_TiledMapGenerator.TYPE_IMAGE = "image";
com_ibm_rave_ext_geo_tile_TiledMapGenerator.CONTAINER_CLASS = "mContainers";
com_ibm_rave_ext_geo_tile_TiledMapGenerator.DEFAULT_URL_GEN = function(providerInfo, tileInfo) {
return "http://" + providerInfo["url"] + tileInfo[2] + "/" + tileInfo[0] + "/" + tileInfo[1] + "." + providerInfo["extension"] + (providerInfo["access_token"] == null ? "" : ("?access_token=" + providerInfo["access_token"]));
};
com_ibm_rave_ext_geo_tile_TiledMapGenerator.TRANSLATE_FUN = function(data, index, groupIndex) {
var currentData = data;
return "translate(" + currentData[0] * 256 + "," + currentData[1] * 256 + ")";
};
com_ibm_rave_ext_geo_tile_TiledMapGenerator.DATA_FUN = function(data, index, groupIndex) {
return data;
};
com_ibm_rave_ext_geo_tile_TiledMapGenerator.X_VALUEFUNCTION = function(data, index, groupIndex) {
return (data)[0];
};
com_ibm_rave_ext_geo_tile_TiledMapGenerator.Y_VALUEFUNCTION = function(data, index, groupIndex) {
return (data)[1];
};
com_ibm_rave_ext_geo_tile_TiledMapGenerator.SORTKEY_COMPARATOR = function(o1, o2) {
var sort_key1 = (o1["properties"])["sort_key"];
var sort_key2 = (o2["properties"])["sort_key"];
return sort_key1 - sort_key2;
};
com_ibm_rave_ext_geo_tile_TiledMapGenerator.CLASS_NAME_EXTRACTOR = function(data, index, groupIndex) {
var currentData = data;
return (currentData["properties"])["kind"];
};
// $source: com/ibm/rave/ext/symbol/RaveSymbol
/************************************************************************
** IBM Confidential
**
** IBM Business Analytics: Rapidly Adaptive Visualization Engine
**
** (C) Copyright IBM Corp. 2017
**
** The source code for this program is not published or otherwise divested of its trade secrets,
** irrespective of what has been deposited with the U.S. Copyright Office.
************************************************************************/
// GENERATED
/**
* A class whose sole purpose is registering extra symbol creator with core's Symbol These new shapes are: