mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-22 06:37:56 +01:00
Mindplot module migration
This commit is contained in:
parent
d515e0bb57
commit
0567dedb88
@ -8,6 +8,6 @@ function coreJs() {
|
||||
require('./Utils'); // eslint-disable-line
|
||||
global.Options = require('@wisemapping/mindplot/lib/components/Options');
|
||||
global.BootstrapDialog = require('@wisemapping/mindplot/lib/components/libraries/bootstrap/BootstrapDialog');
|
||||
//require('@wisemapping/mindplot/lib/components/libraries/bootstrap/BootstrapDialog.Request');
|
||||
require('@wisemapping/mindplot/lib/components/libraries/bootstrap/BootstrapDialog.Request');
|
||||
return global.core; // eslint-disable-line no-undef
|
||||
}
|
||||
|
@ -15,69 +15,67 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const Core = require('@wismapping/core-js')
|
||||
const Core = require('@wismapping/core-js');
|
||||
const core = Core();
|
||||
const Topic = require('./Topic').default;
|
||||
const Shape = require('./util/Shape').default;
|
||||
|
||||
const CentralTopic = new Class(/** @lends CentralTopic*/{
|
||||
const CentralTopic = new Class(
|
||||
/** @lends CentralTopic*/ {
|
||||
Extends: Topic,
|
||||
/**
|
||||
* @extends mindplot.Topic
|
||||
* @constructs
|
||||
* @param model
|
||||
* @param options
|
||||
*/
|
||||
initialize: function (model, options) {
|
||||
this.parent(model, options);
|
||||
},
|
||||
|
||||
Extends:Topic,
|
||||
/**
|
||||
* @extends mindplot.Topic
|
||||
* @constructs
|
||||
* @param model
|
||||
* @param options
|
||||
*/
|
||||
initialize:function (model, options) {
|
||||
this.parent(model, options);
|
||||
},
|
||||
_registerEvents: function () {
|
||||
this.parent();
|
||||
|
||||
_registerEvents:function () {
|
||||
this.parent();
|
||||
// This disable the drag of the central topic. But solves the problem of deselecting the nodes when the screen is clicked.
|
||||
this.addEvent('mousedown', function (event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
},
|
||||
|
||||
// This disable the drag of the central topic. But solves the problem of deselecting the nodes when the screen is clicked.
|
||||
this.addEvent('mousedown', function (event) {
|
||||
event.stopPropagation();
|
||||
});
|
||||
},
|
||||
/** */
|
||||
workoutIncomingConnectionPoint: function () {
|
||||
return this.getPosition();
|
||||
},
|
||||
|
||||
/** */
|
||||
workoutIncomingConnectionPoint:function () {
|
||||
return this.getPosition();
|
||||
},
|
||||
/** */
|
||||
setCursor: function (type) {
|
||||
type = type == 'move' ? 'default' : type;
|
||||
this.parent(type);
|
||||
},
|
||||
|
||||
/** */
|
||||
setCursor:function (type) {
|
||||
type = (type == 'move') ? 'default' : type;
|
||||
this.parent(type);
|
||||
},
|
||||
/** */
|
||||
updateTopicShape: function () {},
|
||||
|
||||
/** */
|
||||
updateTopicShape:function () {
|
||||
_updatePositionOnChangeSize: function () {
|
||||
// Center main topic ...
|
||||
var zeroPoint = new core.Point(0, 0);
|
||||
this.setPosition(zeroPoint);
|
||||
},
|
||||
|
||||
},
|
||||
/** */
|
||||
getShrinkConnector: function () {
|
||||
return null;
|
||||
},
|
||||
|
||||
_updatePositionOnChangeSize:function () {
|
||||
|
||||
// Center main topic ...
|
||||
var zeroPoint = new core.Point(0, 0);
|
||||
this.setPosition(zeroPoint);
|
||||
},
|
||||
|
||||
/** */
|
||||
getShrinkConnector:function () {
|
||||
return null;
|
||||
},
|
||||
|
||||
/** */
|
||||
workoutOutgoingConnectionPoint:function (targetPosition) {
|
||||
$assert(targetPosition, 'targetPoint can not be null');
|
||||
var pos = this.getPosition();
|
||||
var isAtRight = Shape.isAtRight(targetPosition, pos);
|
||||
var size = this.getSize();
|
||||
return Shape.calculateRectConnectionPoint(pos, size, !isAtRight);
|
||||
/** */
|
||||
workoutOutgoingConnectionPoint: function (targetPosition) {
|
||||
$assert(targetPosition, 'targetPoint can not be null');
|
||||
var pos = this.getPosition();
|
||||
var isAtRight = Shape.isAtRight(targetPosition, pos);
|
||||
var size = this.getSize();
|
||||
return Shape.calculateRectConnectionPoint(pos, size, !isAtRight);
|
||||
},
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
export default CentralTopic;
|
||||
|
@ -21,7 +21,7 @@ const web2D = require('@wismapping/web2d');
|
||||
const web2d = web2D();
|
||||
|
||||
const INodeModel = require('./model/INodeModel').default;
|
||||
const { TopicShape } = require('./model/INodeModel').default;
|
||||
const { TopicShape } = require('./model/INodeModel');
|
||||
const Topic = require('./Topic').default;
|
||||
|
||||
const ConnectionLine = new Class({
|
||||
|
@ -24,8 +24,7 @@ const Topic = require('./Topic').default;
|
||||
const { TopicShape } = require('./model/INodeModel');
|
||||
const Shape = require('./util/Shape').default;
|
||||
|
||||
const MainTopic = new Class(
|
||||
/** @lends MainTopic */ {
|
||||
const MainTopic = new Class(/** @lends MainTopic */ {
|
||||
Extends: Topic,
|
||||
/**
|
||||
* @extends mindplot.Topic
|
||||
|
@ -31,7 +31,7 @@ const Messages = new Class({
|
||||
},
|
||||
});
|
||||
|
||||
global.$msg = function (key) {
|
||||
const $msg = function (key) {
|
||||
if (!Messages.__bundle) {
|
||||
Messages.init('en');
|
||||
}
|
||||
|
@ -201,6 +201,7 @@ const NodeGraph = new Class(
|
||||
NodeGraph.create = function (nodeModel, options) {
|
||||
const CentralTopic = require('./CentralTopic').default;
|
||||
const MainTopic = require('./MainTopic').default;
|
||||
|
||||
$assert(nodeModel, 'Model can not be null');
|
||||
|
||||
var type = nodeModel.getType();
|
||||
|
@ -15,14 +15,13 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const RichTextEditor = require('./Ri')
|
||||
const TextEditor = require('./TextEditor').default;
|
||||
|
||||
const TextEditorFactory = {};
|
||||
|
||||
TextEditorFactory.getTextEditorFromName = function (name) {
|
||||
var editorClass = null;
|
||||
if (name == "RichTextEditor") {
|
||||
if (name == 'RichTextEditor') {
|
||||
editorClass = RichTextEditor;
|
||||
} else {
|
||||
editorClass = TextEditor;
|
||||
|
@ -17,7 +17,6 @@
|
||||
*/
|
||||
const Events = require('./Events').default;
|
||||
const MultilineTextEditor = require('./MultilineTextEditor').default;
|
||||
//const TopicEvent = require('./Topic').default;
|
||||
const { TopicShape } = require('./model/INodeModel');
|
||||
|
||||
const TopicEventDispatcher = new Class({
|
||||
|
@ -1,14 +1,16 @@
|
||||
const acitonDispatcher = require('./ActionDispatcher').default;
|
||||
import LocalStorageManager from './LocalStorageManager';
|
||||
|
||||
const actionDispatcher = require('./ActionDispatcher').default;
|
||||
const actionIcon = require('./ActionIcon').default;
|
||||
const centralTopic = require('./CentralTopic').default;
|
||||
const command = require('./Command').default;
|
||||
const connectionLine = require('./ConnectionLine').default;
|
||||
const controlPoint = require('./ControlPoint').default;
|
||||
const designer = require('./Designer').default;
|
||||
const designerAcitonRun = require('./DesignerActionRunner').default;
|
||||
const designerActionRunner = require('./DesignerActionRunner').default;
|
||||
const designerKeyboard = require('./DesignerKeyboard').default;
|
||||
const desginerModel = require('./DesignerModel').default;
|
||||
const desginerUndoManager = require('./DesignerUndoManager').default;
|
||||
const designerModal = require('./DesignerModel').default;
|
||||
const designerUndoManager = require('./DesignerUndoManager').default;
|
||||
const dragConnector = require('./DragConnector').default;
|
||||
const dragManager = require('./DragManager').default;
|
||||
const dragPivot = require('./DragPivot').default;
|
||||
@ -17,36 +19,28 @@ const editorOptions = require('./EditorOptions').default;
|
||||
const editorProperties = require('./EditorProperties').default;
|
||||
const events = require('./Events').default;
|
||||
const footer = require('./footer');
|
||||
//const header =require('./header');
|
||||
const header = require('./header');
|
||||
const icon = require('./Icon').default;
|
||||
const iconGroup = require('./IconGroup').default;
|
||||
const imageIcon = require('./ImageIcon').default;
|
||||
const keyboard = require('./Keyboard').default;
|
||||
const linkIcon = require('./LinkIcon').default;
|
||||
const localStorageManager = require('./LocalStorageManager').default;
|
||||
const localSorageManager = require('./LocalStorageManager').default;
|
||||
const mainTopic = require('./MainTopic').default;
|
||||
const messages = require('./Messages').default;
|
||||
const messageBundle_ca = require('./MessageBundle_ca').default;
|
||||
const messageBundle_de = require('./MessageBundle_de').default;
|
||||
const messageBundle_en = require('./MessageBundle_en').default;
|
||||
const messageBundle_es = require('./MessageBundle_es').default;
|
||||
const messageBundle_fr = require('./MessageBundle_fr').default;
|
||||
const messageBundle_pt_BR = require('./MessageBundle_pt_BR').default;
|
||||
const messageBundle_zh_CN = require('./MessageBundle_zh_CN').default;
|
||||
const messageBundle_zh_TW = require('./MessageBundle_zh_TW').default;
|
||||
const multilineTextEditor = require('./MultilineTextEditor').default;
|
||||
const nodeGraph = require('./NodeGraph').default;
|
||||
const noteIcon = require('./NoteIcon').default;
|
||||
const options = require('./Options').default;
|
||||
const persistenceManger = require('./PersistenceManager').default;
|
||||
const persistenceManager = require('./PersistenceManager').default;
|
||||
const relationship = require('./Relationship').default;
|
||||
const relationshipPivot = require('./RelationshipPivot').default;
|
||||
const restPersistenceManager = require('./RestPersistenceManager').default;
|
||||
const resetPersistenceManager = require('./RestPersistenceManager').default;
|
||||
const screenManager = require('./ScreenManager').default;
|
||||
const shrinkConnector = require('./ShrinkConnector').default;
|
||||
const standaloneActionDispatcher = require('./StandaloneActionDispatcher').default;
|
||||
const textEditor = require('./TextEditor').default;
|
||||
//const textEditorFacotry = require('./TextEditorFactory').default;
|
||||
const textEditorFactory = require('./TextEditorFactory').default;
|
||||
const topic = require('./Topic').default;
|
||||
const topicEventDispatcher = require('./TopicEventDispatcher').default;
|
||||
const topicFeature = require('./TopicFeature').default;
|
||||
@ -54,17 +48,17 @@ const topicStyle = require('./TopicStyle').default;
|
||||
const workspace = require('./Workspace').default;
|
||||
|
||||
export const Components = {
|
||||
ActionDispatcher: acitonDispatcher,
|
||||
ActionDispatcher: actionDispatcher,
|
||||
ActionIcon: actionIcon,
|
||||
CentralTopic: centralTopic,
|
||||
Command: command,
|
||||
ConnectionLine: connectionLine,
|
||||
ControlPoint: controlPoint,
|
||||
Designer: designer,
|
||||
DesignerActionRunner: designerAcitonRun,
|
||||
DesignerActionRunner: designerActionRunner,
|
||||
DesignerKeyboard: designerKeyboard,
|
||||
DesignerModel: desginerModel,
|
||||
DesignerUndoManager: desginerUndoManager,
|
||||
DesignerModel: designerModal,
|
||||
DesignerUndoManager: designerUndoManager,
|
||||
DragConnector: dragConnector,
|
||||
DragManager: dragManager,
|
||||
DragPivot: dragPivot,
|
||||
@ -72,34 +66,30 @@ export const Components = {
|
||||
EditorOptions: editorOptions,
|
||||
EditorProperties: editorProperties,
|
||||
Events: events,
|
||||
footer: footer,
|
||||
header: header,
|
||||
Icon: icon,
|
||||
IconGroup: iconGroup,
|
||||
ImageIcon: imageIcon,
|
||||
Keyboard: keyboard,
|
||||
LinkIcon: linkIcon,
|
||||
LocalStorageManager: localStorageManager,
|
||||
|
||||
localSorageManager: localSorageManager,
|
||||
MainTopic: mainTopic,
|
||||
MessageBundle_ca: messageBundle_ca,
|
||||
MessageBundle_de: messageBundle_de,
|
||||
MessageBundle_en: messageBundle_en,
|
||||
MessageBundle_es: messageBundle_es,
|
||||
MesasgeBundle_fr: messageBundle_fr,
|
||||
MessageBundle_pt_BR: messageBundle_pt_BR,
|
||||
MessageBundle_zh_CN: messageBundle_zh_CN,
|
||||
MessageBundle_zh_TW: messageBundle_zh_TW,
|
||||
Messages: messages,
|
||||
MultilineTextEditor: multilineTextEditor,
|
||||
NodeGraph: nodeGraph,
|
||||
NoteIcon: noteIcon,
|
||||
Options: options,
|
||||
PersistenceManager: persistenceManger,
|
||||
PersistenceManager: persistenceManager,
|
||||
Relationship: relationship,
|
||||
RelationshipPivot: relationshipPivot,
|
||||
RestPersistenceManager: restPersistenceManager,
|
||||
RestPersistenceManager: resetPersistenceManager,
|
||||
ScreenManager: screenManager,
|
||||
ShrinkConnector: shrinkConnector,
|
||||
StandaloneActionDispatcher: standaloneActionDispatcher,
|
||||
TextEditor: textEditor,
|
||||
//TextEditorFactory: textEditorFacotry,
|
||||
TextEditorFactory: textEditorFactory,
|
||||
Topic: topic,
|
||||
TopicEventDispatcher: topicEventDispatcher,
|
||||
TopicFeature: topicFeature,
|
||||
|
@ -15,67 +15,72 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const ChildrenSorterStrategy = require('./ChildrenSorterStrategy').default
|
||||
const ChildrenSorterStrategy = require('./ChildrenSorterStrategy').default;
|
||||
|
||||
/**
|
||||
* @class
|
||||
* @extends mindplot.layout.ChildrenSorterStrategy
|
||||
*/
|
||||
const AbstractBasicSorter = new Class(/** @lends AbstractBasicSorter */{
|
||||
Extends: ChildrenSorterStrategy,
|
||||
const AbstractBasicSorter = new Class(
|
||||
/** @lends AbstractBasicSorter */ {
|
||||
Extends: ChildrenSorterStrategy,
|
||||
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} node
|
||||
* @return the height of a node and its children if existing and not shrunken
|
||||
*/
|
||||
computeChildrenIdByHeights: function(treeSet, node) {
|
||||
var result = {};
|
||||
this._computeChildrenHeight(treeSet, node, result);
|
||||
return result;
|
||||
},
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} node
|
||||
* @return the height of a node and its children if existing and not shrunken
|
||||
*/
|
||||
computeChildrenIdByHeights: function (treeSet, node) {
|
||||
var result = {};
|
||||
this._computeChildrenHeight(treeSet, node, result);
|
||||
return result;
|
||||
},
|
||||
|
||||
_getVerticalPadding: function() {
|
||||
return AbstractBasicSorter.INTERNODE_VERTICAL_PADDING;
|
||||
},
|
||||
_getVerticalPadding: function () {
|
||||
return AbstractBasicSorter.INTERNODE_VERTICAL_PADDING;
|
||||
},
|
||||
|
||||
_computeChildrenHeight : function(treeSet, node, heightCache) {
|
||||
var height = node.getSize().height + (this._getVerticalPadding() * 2); // 2* Top and down padding;
|
||||
_computeChildrenHeight: function (treeSet, node, heightCache) {
|
||||
var height = node.getSize().height + this._getVerticalPadding() * 2; // 2* Top and down padding;
|
||||
|
||||
var result;
|
||||
var children = treeSet.getChildren(node);
|
||||
if (children.length == 0 || node.areChildrenShrunken()) {
|
||||
result = height;
|
||||
} else {
|
||||
var childrenHeight = 0;
|
||||
_.each(children, function(child) {
|
||||
childrenHeight += this._computeChildrenHeight(treeSet, child, heightCache);
|
||||
}, this);
|
||||
var result;
|
||||
var children = treeSet.getChildren(node);
|
||||
if (children.length == 0 || node.areChildrenShrunken()) {
|
||||
result = height;
|
||||
} else {
|
||||
var childrenHeight = 0;
|
||||
_.each(
|
||||
children,
|
||||
function (child) {
|
||||
childrenHeight += this._computeChildrenHeight(treeSet, child, heightCache);
|
||||
},
|
||||
this
|
||||
);
|
||||
|
||||
result = Math.max(height, childrenHeight);
|
||||
}
|
||||
result = Math.max(height, childrenHeight);
|
||||
}
|
||||
|
||||
if (heightCache) {
|
||||
heightCache[node.getId()] = result;
|
||||
}
|
||||
if (heightCache) {
|
||||
heightCache[node.getId()] = result;
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
return result;
|
||||
},
|
||||
|
||||
_getSortedChildren:function(treeSet, node) {
|
||||
var result = treeSet.getChildren(node);
|
||||
result.sort(function(a, b) {
|
||||
return a.getOrder() - b.getOrder()
|
||||
});
|
||||
return result;
|
||||
},
|
||||
_getSortedChildren: function (treeSet, node) {
|
||||
var result = treeSet.getChildren(node);
|
||||
result.sort(function (a, b) {
|
||||
return a.getOrder() - b.getOrder();
|
||||
});
|
||||
return result;
|
||||
},
|
||||
|
||||
_getRelativeDirection: function(reference, position) {
|
||||
var offset = position.x - reference.x;
|
||||
return offset >= 0 ? 1 : -1;
|
||||
_getRelativeDirection: function (reference, position) {
|
||||
var offset = position.x - reference.x;
|
||||
return offset >= 0 ? 1 : -1;
|
||||
},
|
||||
}
|
||||
|
||||
});
|
||||
);
|
||||
|
||||
/**
|
||||
* @constant
|
||||
|
@ -17,250 +17,312 @@
|
||||
*/
|
||||
const AbstractBasicSorter = require('./AbstractBasicSorter').default;
|
||||
|
||||
const BalancedSorter = new Class(/** @lends BalancedSorter */{
|
||||
Extends:AbstractBasicSorter,
|
||||
/**
|
||||
* @constructs
|
||||
* @extends mindplot.layout.AbstractBasicSorter
|
||||
*/
|
||||
initialize:function () {
|
||||
const BalancedSorter = new Class(
|
||||
/** @lends BalancedSorter */ {
|
||||
Extends: AbstractBasicSorter,
|
||||
/**
|
||||
* @constructs
|
||||
* @extends mindplot.layout.AbstractBasicSorter
|
||||
*/
|
||||
initialize: function () {},
|
||||
|
||||
},
|
||||
/**
|
||||
* @param {} graph
|
||||
* @param {} parent
|
||||
* @param {} node
|
||||
* @param {} position
|
||||
* @param {Boolean} free
|
||||
* @return an array with order and position
|
||||
*/
|
||||
predict: function (graph, parent, node, position, free) {
|
||||
// If its a free node...
|
||||
if (free) {
|
||||
$assert(
|
||||
$defined(position),
|
||||
'position cannot be null for predict in free positioning'
|
||||
);
|
||||
$assert($defined(node), 'node cannot be null for predict in free positioning');
|
||||
|
||||
/**
|
||||
* @param {} graph
|
||||
* @param {} parent
|
||||
* @param {} node
|
||||
* @param {} position
|
||||
* @param {Boolean} free
|
||||
* @return an array with order and position
|
||||
*/
|
||||
predict:function (graph, parent, node, position, free) {
|
||||
// If its a free node...
|
||||
if (free) {
|
||||
$assert($defined(position), "position cannot be null for predict in free positioning");
|
||||
$assert($defined(node), "node cannot be null for predict in free positioning");
|
||||
var rootNode = graph.getRootNode(parent);
|
||||
var direction = this._getRelativeDirection(
|
||||
rootNode.getPosition(),
|
||||
node.getPosition()
|
||||
);
|
||||
|
||||
var limitXPos =
|
||||
parent.getPosition().x +
|
||||
direction *
|
||||
(parent.getSize().width / 2 +
|
||||
node.getSize().width / 2 +
|
||||
BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
|
||||
var xPos =
|
||||
direction > 0
|
||||
? position.x >= limitXPos
|
||||
? position.x
|
||||
: limitXPos
|
||||
: position.x <= limitXPos
|
||||
? position.x
|
||||
: limitXPos;
|
||||
|
||||
return [0, { x: xPos, y: position.y }];
|
||||
}
|
||||
|
||||
var rootNode = graph.getRootNode(parent);
|
||||
var direction = this._getRelativeDirection(rootNode.getPosition(), node.getPosition());
|
||||
|
||||
var limitXPos = parent.getPosition().x + direction * (parent.getSize().width / 2 + node.getSize().width / 2 + BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
// If it is a dragged node...
|
||||
if (node) {
|
||||
$assert($defined(position), 'position cannot be null for predict in dragging');
|
||||
var nodeDirection = this._getRelativeDirection(
|
||||
rootNode.getPosition(),
|
||||
node.getPosition()
|
||||
);
|
||||
var positionDirection = this._getRelativeDirection(
|
||||
rootNode.getPosition(),
|
||||
position
|
||||
);
|
||||
var siblings = graph.getSiblings(node);
|
||||
|
||||
var xPos = direction > 0 ?
|
||||
(position.x >= limitXPos ? position.x : limitXPos) :
|
||||
(position.x <= limitXPos ? position.x : limitXPos);
|
||||
|
||||
return [0, {x:xPos, y:position.y}];
|
||||
}
|
||||
|
||||
var rootNode = graph.getRootNode(parent);
|
||||
|
||||
// If it is a dragged node...
|
||||
if (node) {
|
||||
$assert($defined(position), "position cannot be null for predict in dragging");
|
||||
var nodeDirection = this._getRelativeDirection(rootNode.getPosition(), node.getPosition());
|
||||
var positionDirection = this._getRelativeDirection(rootNode.getPosition(), position);
|
||||
var siblings = graph.getSiblings(node);
|
||||
|
||||
var sameParent = parent == graph.getParent(node);
|
||||
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
||||
return [node.getOrder(), node.getPosition()];
|
||||
}
|
||||
}
|
||||
|
||||
if (!position) {
|
||||
var right = this._getChildrenForOrder(parent, graph, 0);
|
||||
var left = this._getChildrenForOrder(parent, graph, 1);
|
||||
}
|
||||
// Filter nodes on one side..
|
||||
var order = position ? (position.x > rootNode.getPosition().x ? 0 : 1) : ((right.length - left.length) > 0 ? 1 : 0);
|
||||
var direction = order % 2 == 0 ? 1 : -1;
|
||||
|
||||
// Exclude the dragged node (if set)
|
||||
var children = this._getChildrenForOrder(parent, graph, order).filter(function (child) {
|
||||
return child != node;
|
||||
});
|
||||
|
||||
// No children?
|
||||
if (children.length == 0) {
|
||||
return [order, {x:parent.getPosition().x + direction * (parent.getSize().width / 2 + BalancedSorter.INTERNODE_HORIZONTAL_PADDING * 2), y:parent.getPosition().y}];
|
||||
}
|
||||
|
||||
// Try to fit within ...
|
||||
var result = null;
|
||||
var last = children.getLast();
|
||||
position = position || {x:last.getPosition().x, y:last.getPosition().y + 1};
|
||||
_.each(children, function (child, index) {
|
||||
var cpos = child.getPosition();
|
||||
if (position.y > cpos.y) {
|
||||
yOffset = child == last ?
|
||||
child.getSize().height + BalancedSorter.INTERNODE_VERTICAL_PADDING * 2 :
|
||||
(children[index + 1].getPosition().y - child.getPosition().y) / 2;
|
||||
result = [child.getOrder() + 2, {x:cpos.x, y:cpos.y + yOffset}];
|
||||
}
|
||||
});
|
||||
|
||||
// Position wasn't below any node, so it must be inserted above
|
||||
if (!result) {
|
||||
var first = children[0];
|
||||
result = [position.x > 0 ? 0 : 1, {
|
||||
x:first.getPosition().x,
|
||||
y:first.getPosition().y - first.getSize().height - BalancedSorter.INTERNODE_VERTICAL_PADDING * 2
|
||||
}];
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} parent
|
||||
* @param {} child
|
||||
* @param {} order
|
||||
*/
|
||||
insert:function (treeSet, parent, child, order) {
|
||||
var children = this._getChildrenForOrder(parent, treeSet, order);
|
||||
|
||||
// If no children, return 0 or 1 depending on the side
|
||||
if (children.length == 0) {
|
||||
child.setOrder(order % 2);
|
||||
return;
|
||||
}
|
||||
|
||||
// Shift all the elements by two, so side is the same.
|
||||
// In case of balanced sorter, order don't need to be continuous...
|
||||
var max = 0;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var node = children[i];
|
||||
max = Math.max(max, node.getOrder());
|
||||
if (node.getOrder() >= order) {
|
||||
max = Math.max(max, node.getOrder() + 2);
|
||||
node.setOrder(node.getOrder() + 2);
|
||||
}
|
||||
}
|
||||
|
||||
var newOrder = order > (max + 1) ? (max + 2) : order;
|
||||
child.setOrder(newOrder);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} node
|
||||
*/
|
||||
detach:function (treeSet, node) {
|
||||
var parent = treeSet.getParent(node);
|
||||
// Filter nodes on one side..
|
||||
var children = this._getChildrenForOrder(parent, treeSet, node.getOrder());
|
||||
|
||||
_.each(children, function (child, index) {
|
||||
if (child.getOrder() > node.getOrder()) {
|
||||
child.setOrder(child.getOrder() - 2);
|
||||
}
|
||||
});
|
||||
node.setOrder(node.getOrder() % 2 == 0 ? 0 : 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} node
|
||||
* @return offsets
|
||||
*/
|
||||
computeOffsets:function (treeSet, node) {
|
||||
$assert(treeSet, "treeSet can no be null.");
|
||||
$assert(node, "node can no be null.");
|
||||
|
||||
var children = this._getSortedChildren(treeSet, node);
|
||||
|
||||
// Compute heights ...
|
||||
var heights = children.map(
|
||||
function (child) {
|
||||
return {id:child.getId(), order:child.getOrder(), width:child.getSize().width, height:this._computeChildrenHeight(treeSet, child)};
|
||||
}, this).reverse();
|
||||
|
||||
|
||||
// Compute the center of the branch ...
|
||||
var totalPHeight = 0;
|
||||
var totalNHeight = 0;
|
||||
|
||||
_.each(heights, function (elem) {
|
||||
if (elem.order % 2 == 0) {
|
||||
totalPHeight += elem.height;
|
||||
} else {
|
||||
totalNHeight += elem.height;
|
||||
}
|
||||
});
|
||||
var psum = totalPHeight / 2;
|
||||
var nsum = totalNHeight / 2;
|
||||
var ysum = 0;
|
||||
|
||||
// Calculate the offsets ...
|
||||
var result = {};
|
||||
for (var i = 0; i < heights.length; i++) {
|
||||
var direction = heights[i].order % 2 ? -1 : 1;
|
||||
|
||||
if (direction > 0) {
|
||||
psum = psum - heights[i].height;
|
||||
ysum = psum;
|
||||
} else {
|
||||
nsum = nsum - heights[i].height;
|
||||
ysum = nsum;
|
||||
var sameParent = parent == graph.getParent(node);
|
||||
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
||||
return [node.getOrder(), node.getPosition()];
|
||||
}
|
||||
}
|
||||
|
||||
var yOffset = ysum + heights[i].height / 2;
|
||||
var xOffset = direction * (node.getSize().width / 2 + heights[i].width / 2 + +BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
if (!position) {
|
||||
var right = this._getChildrenForOrder(parent, graph, 0);
|
||||
var left = this._getChildrenForOrder(parent, graph, 1);
|
||||
}
|
||||
// Filter nodes on one side..
|
||||
var order = position
|
||||
? position.x > rootNode.getPosition().x
|
||||
? 0
|
||||
: 1
|
||||
: right.length - left.length > 0
|
||||
? 1
|
||||
: 0;
|
||||
var direction = order % 2 == 0 ? 1 : -1;
|
||||
|
||||
$assert(!isNaN(xOffset), "xOffset can not be null");
|
||||
$assert(!isNaN(yOffset), "yOffset can not be null");
|
||||
// Exclude the dragged node (if set)
|
||||
var children = this._getChildrenForOrder(parent, graph, order).filter(function (child) {
|
||||
return child != node;
|
||||
});
|
||||
|
||||
result[heights[i].id] = {x:xOffset, y:yOffset};
|
||||
}
|
||||
return result;
|
||||
},
|
||||
// No children?
|
||||
if (children.length == 0) {
|
||||
return [
|
||||
order,
|
||||
{
|
||||
x:
|
||||
parent.getPosition().x +
|
||||
direction *
|
||||
(parent.getSize().width / 2 +
|
||||
BalancedSorter.INTERNODE_HORIZONTAL_PADDING * 2),
|
||||
y: parent.getPosition().y,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} node
|
||||
* @throw will throw an error if order elements are missing
|
||||
*/
|
||||
verify:function (treeSet, node) {
|
||||
// Check that all is consistent ...
|
||||
var children = this._getChildrenForOrder(node, treeSet, node.getOrder());
|
||||
// Try to fit within ...
|
||||
var result = null;
|
||||
var last = children.getLast();
|
||||
position = position || { x: last.getPosition().x, y: last.getPosition().y + 1 };
|
||||
_.each(children, function (child, index) {
|
||||
var cpos = child.getPosition();
|
||||
if (position.y > cpos.y) {
|
||||
let yOffset =
|
||||
child == last
|
||||
? child.getSize().height + BalancedSorter.INTERNODE_VERTICAL_PADDING * 2
|
||||
: (children[index + 1].getPosition().y - child.getPosition().y) / 2;
|
||||
result = [child.getOrder() + 2, { x: cpos.x, y: cpos.y + yOffset }];
|
||||
}
|
||||
});
|
||||
|
||||
// All odd ordered nodes should be "continuous" by themselves
|
||||
// All even numbered nodes should be "continuous" by themselves
|
||||
var factor = node.getOrder() % 2 == 0 ? 2 : 1;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var order = i == 0 && factor == 1 ? 1 : (factor * i);
|
||||
$assert(children[i].getOrder() == order, "Missing order elements. Missing order: " + (i * factor) + ". Parent:" + node.getId() + ",Node:" + children[i].getId());
|
||||
}
|
||||
},
|
||||
// Position wasn't below any node, so it must be inserted above
|
||||
if (!result) {
|
||||
var first = children[0];
|
||||
result = [
|
||||
position.x > 0 ? 0 : 1,
|
||||
{
|
||||
x: first.getPosition().x,
|
||||
y:
|
||||
first.getPosition().y -
|
||||
first.getSize().height -
|
||||
BalancedSorter.INTERNODE_VERTICAL_PADDING * 2,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} child
|
||||
* @return the direction of the child within the treeSet
|
||||
*/
|
||||
getChildDirection:function (treeSet, child) {
|
||||
return child.getOrder() % 2 == 0 ? 1 : -1;
|
||||
},
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {String} the print name of this class
|
||||
*/
|
||||
toString:function () {
|
||||
return "Balanced Sorter";
|
||||
},
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} parent
|
||||
* @param {} child
|
||||
* @param {} order
|
||||
*/
|
||||
insert: function (treeSet, parent, child, order) {
|
||||
var children = this._getChildrenForOrder(parent, treeSet, order);
|
||||
|
||||
_getChildrenForOrder:function (parent, graph, order) {
|
||||
return this._getSortedChildren(graph, parent).filter(function (child) {
|
||||
return child.getOrder() % 2 == order % 2;
|
||||
});
|
||||
},
|
||||
// If no children, return 0 or 1 depending on the side
|
||||
if (children.length == 0) {
|
||||
child.setOrder(order % 2);
|
||||
return;
|
||||
}
|
||||
|
||||
_getVerticalPadding:function () {
|
||||
return BalancedSorter.INTERNODE_VERTICAL_PADDING;
|
||||
// Shift all the elements by two, so side is the same.
|
||||
// In case of balanced sorter, order don't need to be continuous...
|
||||
var max = 0;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var node = children[i];
|
||||
max = Math.max(max, node.getOrder());
|
||||
if (node.getOrder() >= order) {
|
||||
max = Math.max(max, node.getOrder() + 2);
|
||||
node.setOrder(node.getOrder() + 2);
|
||||
}
|
||||
}
|
||||
|
||||
var newOrder = order > max + 1 ? max + 2 : order;
|
||||
child.setOrder(newOrder);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} node
|
||||
*/
|
||||
detach: function (treeSet, node) {
|
||||
var parent = treeSet.getParent(node);
|
||||
// Filter nodes on one side..
|
||||
var children = this._getChildrenForOrder(parent, treeSet, node.getOrder());
|
||||
|
||||
_.each(children, function (child, index) {
|
||||
if (child.getOrder() > node.getOrder()) {
|
||||
child.setOrder(child.getOrder() - 2);
|
||||
}
|
||||
});
|
||||
node.setOrder(node.getOrder() % 2 == 0 ? 0 : 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} node
|
||||
* @return offsets
|
||||
*/
|
||||
computeOffsets: function (treeSet, node) {
|
||||
$assert(treeSet, 'treeSet can no be null.');
|
||||
$assert(node, 'node can no be null.');
|
||||
|
||||
var children = this._getSortedChildren(treeSet, node);
|
||||
|
||||
// Compute heights ...
|
||||
var heights = children
|
||||
.map(function (child) {
|
||||
return {
|
||||
id: child.getId(),
|
||||
order: child.getOrder(),
|
||||
width: child.getSize().width,
|
||||
height: this._computeChildrenHeight(treeSet, child),
|
||||
};
|
||||
}, this)
|
||||
.reverse();
|
||||
|
||||
// Compute the center of the branch ...
|
||||
var totalPHeight = 0;
|
||||
var totalNHeight = 0;
|
||||
|
||||
_.each(heights, function (elem) {
|
||||
if (elem.order % 2 == 0) {
|
||||
totalPHeight += elem.height;
|
||||
} else {
|
||||
totalNHeight += elem.height;
|
||||
}
|
||||
});
|
||||
var psum = totalPHeight / 2;
|
||||
var nsum = totalNHeight / 2;
|
||||
var ysum = 0;
|
||||
|
||||
// Calculate the offsets ...
|
||||
var result = {};
|
||||
for (var i = 0; i < heights.length; i++) {
|
||||
var direction = heights[i].order % 2 ? -1 : 1;
|
||||
|
||||
if (direction > 0) {
|
||||
psum = psum - heights[i].height;
|
||||
ysum = psum;
|
||||
} else {
|
||||
nsum = nsum - heights[i].height;
|
||||
ysum = nsum;
|
||||
}
|
||||
|
||||
var yOffset = ysum + heights[i].height / 2;
|
||||
var xOffset =
|
||||
direction *
|
||||
(node.getSize().width / 2 +
|
||||
heights[i].width / 2 +
|
||||
+BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
|
||||
$assert(!isNaN(xOffset), 'xOffset can not be null');
|
||||
$assert(!isNaN(yOffset), 'yOffset can not be null');
|
||||
|
||||
result[heights[i].id] = { x: xOffset, y: yOffset };
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} node
|
||||
* @throw will throw an error if order elements are missing
|
||||
*/
|
||||
verify: function (treeSet, node) {
|
||||
// Check that all is consistent ...
|
||||
var children = this._getChildrenForOrder(node, treeSet, node.getOrder());
|
||||
|
||||
// All odd ordered nodes should be "continuous" by themselves
|
||||
// All even numbered nodes should be "continuous" by themselves
|
||||
var factor = node.getOrder() % 2 == 0 ? 2 : 1;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var order = i == 0 && factor == 1 ? 1 : factor * i;
|
||||
$assert(
|
||||
children[i].getOrder() == order,
|
||||
'Missing order elements. Missing order: ' +
|
||||
i * factor +
|
||||
'. Parent:' +
|
||||
node.getId() +
|
||||
',Node:' +
|
||||
children[i].getId()
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {} treeSet
|
||||
* @param {} child
|
||||
* @return the direction of the child within the treeSet
|
||||
*/
|
||||
getChildDirection: function (treeSet, child) {
|
||||
return child.getOrder() % 2 == 0 ? 1 : -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {String} the print name of this class
|
||||
*/
|
||||
toString: function () {
|
||||
return 'Balanced Sorter';
|
||||
},
|
||||
|
||||
_getChildrenForOrder: function (parent, graph, order) {
|
||||
return this._getSortedChildren(graph, parent).filter(function (child) {
|
||||
return child.getOrder() % 2 == order % 2;
|
||||
});
|
||||
},
|
||||
|
||||
_getVerticalPadding: function () {
|
||||
return BalancedSorter.INTERNODE_VERTICAL_PADDING;
|
||||
},
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
/**
|
||||
* @constant
|
||||
|
@ -15,257 +15,271 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const Events = require('../Events').default
|
||||
const RootedTreeSet = require('./RootedTreeSet').default
|
||||
const OriginalLayout = require('./OriginalLayout').default
|
||||
const Events = require('../Events').default;
|
||||
const RootedTreeSet = require('./RootedTreeSet').default;
|
||||
const OriginalLayout = require('./OriginalLayout').default;
|
||||
const ChangeEvent = require('./ChangeEvent').default;
|
||||
|
||||
const LayoutManager = new Class(/** @lends LayoutManager */{
|
||||
Extends: Events,
|
||||
/**
|
||||
* @constructs
|
||||
* @extends mindplot.Events
|
||||
* @param {} rootNodeId
|
||||
* @param {} rootSize
|
||||
* @throws will throw an error if the root node id is null or undefined
|
||||
* @throws will throw an error if the root size is null
|
||||
*/
|
||||
initialize: function(rootNodeId, rootSize) {
|
||||
$assert($defined(rootNodeId), "rootNodeId can not be null");
|
||||
$assert(rootSize, "rootSize can not be null");
|
||||
var position = position || {x:0, y:0};
|
||||
const LayoutManager = new Class(
|
||||
/** @lends LayoutManager */ {
|
||||
Extends: Events,
|
||||
/**
|
||||
* @constructs
|
||||
* @extends mindplot.Events
|
||||
* @param {} rootNodeId
|
||||
* @param {} rootSize
|
||||
* @throws will throw an error if the root node id is null or undefined
|
||||
* @throws will throw an error if the root size is null
|
||||
*/
|
||||
initialize: function (rootNodeId, rootSize) {
|
||||
$assert($defined(rootNodeId), 'rootNodeId can not be null');
|
||||
$assert(rootSize, 'rootSize can not be null');
|
||||
var position = position || { x: 0, y: 0 };
|
||||
|
||||
this._treeSet = new RootedTreeSet();
|
||||
this._layout = new OriginalLayout(this._treeSet);
|
||||
this._treeSet = new RootedTreeSet();
|
||||
this._layout = new OriginalLayout(this._treeSet);
|
||||
|
||||
var rootNode = this._layout.createNode(rootNodeId, rootSize, position, 'root');
|
||||
this._treeSet.setRoot(rootNode);
|
||||
this._events = [];
|
||||
},
|
||||
var rootNode = this._layout.createNode(rootNodeId, rootSize, position, 'root');
|
||||
this._treeSet.setRoot(rootNode);
|
||||
this._events = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param size
|
||||
* @throws will throw an error if id is null or undefined
|
||||
*/
|
||||
updateNodeSize: function(id, size) {
|
||||
$assert($defined(id), "id can not be null");
|
||||
/**
|
||||
* @param id
|
||||
* @param size
|
||||
* @throws will throw an error if id is null or undefined
|
||||
*/
|
||||
updateNodeSize: function (id, size) {
|
||||
$assert($defined(id), 'id can not be null');
|
||||
|
||||
var node = this._treeSet.find(id);
|
||||
node.setSize(size);
|
||||
},
|
||||
var node = this._treeSet.find(id);
|
||||
node.setSize(size);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param value
|
||||
* @throws will throw an error if id is null or undefined
|
||||
* @throws will throw an error if value is null or undefined
|
||||
* @return this
|
||||
*/
|
||||
updateShrinkState: function(id, value) {
|
||||
$assert($defined(id), "id can not be null");
|
||||
$assert($defined(value), "value can not be null");
|
||||
/**
|
||||
* @param id
|
||||
* @param value
|
||||
* @throws will throw an error if id is null or undefined
|
||||
* @throws will throw an error if value is null or undefined
|
||||
* @return this
|
||||
*/
|
||||
updateShrinkState: function (id, value) {
|
||||
$assert($defined(id), 'id can not be null');
|
||||
$assert($defined(value), 'value can not be null');
|
||||
|
||||
var node = this._treeSet.find(id);
|
||||
node.setShrunken(value);
|
||||
var node = this._treeSet.find(id);
|
||||
node.setShrunken(value);
|
||||
|
||||
return this;
|
||||
},
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @return {@link RootedTreeSet}.find(id)
|
||||
*/
|
||||
find: function(id) {
|
||||
return this._treeSet.find(id);
|
||||
},
|
||||
/**
|
||||
* @param id
|
||||
* @return {@link RootedTreeSet}.find(id)
|
||||
*/
|
||||
find: function (id) {
|
||||
return this._treeSet.find(id);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param position
|
||||
* @throws will throw an error if id is null or undefined
|
||||
* @throws will throw an error if position is null or undefined
|
||||
* @throws will throw an error if the position's x property is null or undefined
|
||||
* @throws will throw an error if the position's y property is null or undefined
|
||||
*/
|
||||
moveNode: function(id, position) {
|
||||
$assert($defined(id), "id cannot be null");
|
||||
$assert($defined(position), "position cannot be null");
|
||||
$assert($defined(position.x), "x can not be null");
|
||||
$assert($defined(position.y), "y can not be null");
|
||||
/**
|
||||
* @param id
|
||||
* @param position
|
||||
* @throws will throw an error if id is null or undefined
|
||||
* @throws will throw an error if position is null or undefined
|
||||
* @throws will throw an error if the position's x property is null or undefined
|
||||
* @throws will throw an error if the position's y property is null or undefined
|
||||
*/
|
||||
moveNode: function (id, position) {
|
||||
$assert($defined(id), 'id cannot be null');
|
||||
$assert($defined(position), 'position cannot be null');
|
||||
$assert($defined(position.x), 'x can not be null');
|
||||
$assert($defined(position.y), 'y can not be null');
|
||||
|
||||
var node = this._treeSet.find(id);
|
||||
// @Todo: this should not be here. This is broking the isolated node support...
|
||||
// node.setFree(true);
|
||||
// node.setFreeDisplacement({x:position.x - node.getPosition().x, y:position.y - node.getPosition().y});
|
||||
node.setPosition(position);
|
||||
},
|
||||
var node = this._treeSet.find(id);
|
||||
// @Todo: this should not be here. This is broking the isolated node support...
|
||||
// node.setFree(true);
|
||||
// node.setFreeDisplacement({x:position.x - node.getPosition().x, y:position.y - node.getPosition().y});
|
||||
node.setPosition(position);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param parentId
|
||||
* @param childId
|
||||
* @param order
|
||||
* @throws will throw an error if parentId is null or undefined
|
||||
* @throws will throw an error if childId is null or undefined
|
||||
* @throws will throw an error if order is null or undefined
|
||||
* @return this
|
||||
*/
|
||||
connectNode: function(parentId, childId, order) {
|
||||
$assert($defined(parentId), "parentId cannot be null");
|
||||
$assert($defined(childId), "childId cannot be null");
|
||||
$assert($defined(order), "order cannot be null");
|
||||
/**
|
||||
* @param parentId
|
||||
* @param childId
|
||||
* @param order
|
||||
* @throws will throw an error if parentId is null or undefined
|
||||
* @throws will throw an error if childId is null or undefined
|
||||
* @throws will throw an error if order is null or undefined
|
||||
* @return this
|
||||
*/
|
||||
connectNode: function (parentId, childId, order) {
|
||||
$assert($defined(parentId), 'parentId cannot be null');
|
||||
$assert($defined(childId), 'childId cannot be null');
|
||||
$assert($defined(order), 'order cannot be null');
|
||||
|
||||
this._layout.connectNode(parentId, childId, order);
|
||||
this._layout.connectNode(parentId, childId, order);
|
||||
|
||||
return this;
|
||||
},
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @throws will throw an error if id is null or undefined
|
||||
* @return this
|
||||
*/
|
||||
disconnectNode: function(id) {
|
||||
$assert($defined(id), "id can not be null");
|
||||
this._layout.disconnectNode(id);
|
||||
/**
|
||||
* @param id
|
||||
* @throws will throw an error if id is null or undefined
|
||||
* @return this
|
||||
*/
|
||||
disconnectNode: function (id) {
|
||||
$assert($defined(id), 'id can not be null');
|
||||
this._layout.disconnectNode(id);
|
||||
|
||||
return this;
|
||||
},
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param size
|
||||
* @param position
|
||||
* @throws will throw an error if id is null or undefined
|
||||
* @return this
|
||||
*/
|
||||
addNode:function(id, size, position) {
|
||||
$assert($defined(id), "id can not be null");
|
||||
var result = this._layout.createNode(id, size, position, 'topic');
|
||||
this._treeSet.add(result);
|
||||
/**
|
||||
* @param id
|
||||
* @param size
|
||||
* @param position
|
||||
* @throws will throw an error if id is null or undefined
|
||||
* @return this
|
||||
*/
|
||||
addNode: function (id, size, position) {
|
||||
$assert($defined(id), 'id can not be null');
|
||||
var result = this._layout.createNode(id, size, position, 'topic');
|
||||
this._treeSet.add(result);
|
||||
|
||||
return this;
|
||||
},
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* removes a node and its connection to parent if existing
|
||||
* @param id
|
||||
* @throws will throw an error if id is null or undefined
|
||||
* @return this
|
||||
*/
|
||||
removeNode: function(id) {
|
||||
$assert($defined(id), "id can not be null");
|
||||
var node = this._treeSet.find(id);
|
||||
/**
|
||||
* removes a node and its connection to parent if existing
|
||||
* @param id
|
||||
* @throws will throw an error if id is null or undefined
|
||||
* @return this
|
||||
*/
|
||||
removeNode: function (id) {
|
||||
$assert($defined(id), 'id can not be null');
|
||||
var node = this._treeSet.find(id);
|
||||
|
||||
// Is It connected ?
|
||||
if (this._treeSet.getParent(node)) {
|
||||
this.disconnectNode(id);
|
||||
}
|
||||
|
||||
// Remove the all the branch ...
|
||||
this._treeSet.remove(id);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Number} parentId
|
||||
* @param {Number=} nodeId
|
||||
* @param {String=} position the position to use as mindplot.layout.Node.properties position
|
||||
* property as '(x,y)'
|
||||
* @param {Boolean=} free true specifies free node positioning
|
||||
* @throws will throw an error if parentId is null or undefined
|
||||
*/
|
||||
predict: function(parentId, nodeId, position, free) {
|
||||
$assert($defined(parentId), "parentId can not be null");
|
||||
|
||||
var parent = this._treeSet.find(parentId);
|
||||
var node = nodeId ? this._treeSet.find(nodeId) : null;
|
||||
var sorter = parent.getSorter();
|
||||
|
||||
var result = sorter.predict(this._treeSet, parent, node, position, free);
|
||||
return {order:result[0],position:result[1]};
|
||||
},
|
||||
|
||||
/**
|
||||
* logs dump to console
|
||||
*/
|
||||
dump: function() {
|
||||
console.log(this._treeSet.dump());
|
||||
},
|
||||
|
||||
/**
|
||||
* @param containerId
|
||||
* @param {width:Number, height:Number} size
|
||||
* @throws will throw an error if containerId is null or undefined
|
||||
* @return canvas
|
||||
*/
|
||||
plot: function(containerId, size) {
|
||||
$assert(containerId, "containerId cannot be null");
|
||||
size = size || {width:200,height:200};
|
||||
var squaresize = 10;
|
||||
var canvas = Raphael(containerId, size.width, size.height);
|
||||
canvas.drawGrid(0, 0, size.width, size.height, size.width / squaresize, size.height / squaresize);
|
||||
this._treeSet.plot(canvas);
|
||||
|
||||
return canvas;
|
||||
},
|
||||
|
||||
/**
|
||||
* initializes the layout to be updated
|
||||
* @param fireEvents
|
||||
* @return this
|
||||
*/
|
||||
layout: function(fireEvents) {
|
||||
// File repositioning ...
|
||||
this._layout.layout();
|
||||
|
||||
// Collect changes ...
|
||||
this._collectChanges();
|
||||
|
||||
if ($(fireEvents).length>0 || fireEvents) {
|
||||
this._flushEvents();
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_flushEvents: function() {
|
||||
_.each(this._events, function(event) {
|
||||
this.fireEvent('change', event);
|
||||
}, this);
|
||||
this._events = [];
|
||||
},
|
||||
|
||||
_collectChanges: function(nodes) {
|
||||
if (!nodes)
|
||||
nodes = this._treeSet.getTreeRoots();
|
||||
|
||||
_.each(nodes, function(node) {
|
||||
if (node.hasOrderChanged() || node.hasPositionChanged()) {
|
||||
|
||||
// Find or create a event ...
|
||||
var id = node.getId();
|
||||
var event = this._events.some(function(event) {
|
||||
return event.id == id;
|
||||
});
|
||||
if (!event) {
|
||||
event = new ChangeEvent(id);
|
||||
}
|
||||
|
||||
// Update nodes ...
|
||||
event.setOrder(node.getOrder());
|
||||
event.setPosition(node.getPosition());
|
||||
|
||||
node.resetPositionState();
|
||||
node.resetOrderState();
|
||||
node.resetFreeState();
|
||||
this._events.push(event);
|
||||
// Is It connected ?
|
||||
if (this._treeSet.getParent(node)) {
|
||||
this.disconnectNode(id);
|
||||
}
|
||||
this._collectChanges(this._treeSet.getChildren(node));
|
||||
}, this);
|
||||
}
|
||||
|
||||
});
|
||||
// Remove the all the branch ...
|
||||
this._treeSet.remove(id);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {Number} parentId
|
||||
* @param {Number=} nodeId
|
||||
* @param {String=} position the position to use as mindplot.layout.Node.properties position
|
||||
* property as '(x,y)'
|
||||
* @param {Boolean=} free true specifies free node positioning
|
||||
* @throws will throw an error if parentId is null or undefined
|
||||
*/
|
||||
predict: function (parentId, nodeId, position, free) {
|
||||
$assert($defined(parentId), 'parentId can not be null');
|
||||
|
||||
var parent = this._treeSet.find(parentId);
|
||||
var node = nodeId ? this._treeSet.find(nodeId) : null;
|
||||
var sorter = parent.getSorter();
|
||||
|
||||
var result = sorter.predict(this._treeSet, parent, node, position, free);
|
||||
return { order: result[0], position: result[1] };
|
||||
},
|
||||
|
||||
/**
|
||||
* logs dump to console
|
||||
*/
|
||||
dump: function () {
|
||||
console.log(this._treeSet.dump());
|
||||
},
|
||||
|
||||
/**
|
||||
* @param containerId
|
||||
* @param {width:Number, height:Number} size
|
||||
* @throws will throw an error if containerId is null or undefined
|
||||
* @return canvas
|
||||
*/
|
||||
plot: function (containerId, size) {
|
||||
$assert(containerId, 'containerId cannot be null');
|
||||
size = size || { width: 200, height: 200 };
|
||||
var squaresize = 10;
|
||||
var canvas = Raphael(containerId, size.width, size.height);
|
||||
canvas.drawGrid(
|
||||
0,
|
||||
0,
|
||||
size.width,
|
||||
size.height,
|
||||
size.width / squaresize,
|
||||
size.height / squaresize
|
||||
);
|
||||
this._treeSet.plot(canvas);
|
||||
|
||||
return canvas;
|
||||
},
|
||||
|
||||
/**
|
||||
* initializes the layout to be updated
|
||||
* @param fireEvents
|
||||
* @return this
|
||||
*/
|
||||
layout: function (fireEvents) {
|
||||
// File repositioning ...
|
||||
this._layout.layout();
|
||||
|
||||
// Collect changes ...
|
||||
this._collectChanges();
|
||||
|
||||
if ($(fireEvents).length > 0 || fireEvents) {
|
||||
this._flushEvents();
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
_flushEvents: function () {
|
||||
_.each(
|
||||
this._events,
|
||||
function (event) {
|
||||
this.fireEvent('change', event);
|
||||
},
|
||||
this
|
||||
);
|
||||
this._events = [];
|
||||
},
|
||||
|
||||
_collectChanges: function (nodes) {
|
||||
if (!nodes) nodes = this._treeSet.getTreeRoots();
|
||||
|
||||
_.each(
|
||||
nodes,
|
||||
function (node) {
|
||||
if (node.hasOrderChanged() || node.hasPositionChanged()) {
|
||||
// Find or create a event ...
|
||||
var id = node.getId();
|
||||
var event = this._events.some(function (event) {
|
||||
return event.id == id;
|
||||
});
|
||||
if (!event) {
|
||||
event = new ChangeEvent(id);
|
||||
}
|
||||
|
||||
// Update nodes ...
|
||||
event.setOrder(node.getOrder());
|
||||
event.setPosition(node.getPosition());
|
||||
|
||||
node.resetPositionState();
|
||||
node.resetOrderState();
|
||||
node.resetFreeState();
|
||||
this._events.push(event);
|
||||
}
|
||||
this._collectChanges(this._treeSet.getChildren(node));
|
||||
},
|
||||
this
|
||||
);
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
export default LayoutManager;
|
||||
|
@ -16,207 +16,234 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const Node = new Class(/** @lends Node */{
|
||||
/**
|
||||
* @constructs
|
||||
* @param id
|
||||
* @param size
|
||||
* @param position
|
||||
* @param sorter
|
||||
* @throws will throw an error if id is not a finite number or is null or undefined
|
||||
* @throws will throw an error if size is null or undefined
|
||||
* @throws will throw an error if position is null or undefined
|
||||
* @throws will throw an error if sorter is null or undefined
|
||||
*/
|
||||
initialize:function (id, size, position, sorter) {
|
||||
$assert(typeof id === 'number' && isFinite(id), "id can not be null");
|
||||
$assert(size, "size can not be null");
|
||||
$assert(position, "position can not be null");
|
||||
$assert(sorter, "sorter can not be null");
|
||||
const Node = new Class(
|
||||
/** @lends Node */ {
|
||||
/**
|
||||
* @constructs
|
||||
* @param id
|
||||
* @param size
|
||||
* @param position
|
||||
* @param sorter
|
||||
* @throws will throw an error if id is not a finite number or is null or undefined
|
||||
* @throws will throw an error if size is null or undefined
|
||||
* @throws will throw an error if position is null or undefined
|
||||
* @throws will throw an error if sorter is null or undefined
|
||||
*/
|
||||
initialize: function (id, size, position, sorter) {
|
||||
$assert(typeof id === 'number' && isFinite(id), 'id can not be null');
|
||||
$assert(size, 'size can not be null');
|
||||
$assert(position, 'position can not be null');
|
||||
$assert(sorter, 'sorter can not be null');
|
||||
|
||||
this._id = id;
|
||||
this._sorter = sorter;
|
||||
this._properties = {};
|
||||
this._id = id;
|
||||
this._sorter = sorter;
|
||||
this._properties = {};
|
||||
|
||||
this.setSize(size);
|
||||
this.setPosition(position);
|
||||
this.setShrunken(false);
|
||||
},
|
||||
this.setSize(size);
|
||||
this.setPosition(position);
|
||||
this.setShrunken(false);
|
||||
},
|
||||
|
||||
/** */
|
||||
getId:function () {
|
||||
return this._id;
|
||||
},
|
||||
/** */
|
||||
getId: function () {
|
||||
return this._id;
|
||||
},
|
||||
|
||||
/** */
|
||||
setFree:function (value) {
|
||||
this._setProperty('free', value);
|
||||
},
|
||||
/** */
|
||||
setFree: function (value) {
|
||||
this._setProperty('free', value);
|
||||
},
|
||||
|
||||
/** */
|
||||
isFree:function () {
|
||||
return this._getProperty('free');
|
||||
},
|
||||
/** */
|
||||
isFree: function () {
|
||||
return this._getProperty('free');
|
||||
},
|
||||
|
||||
/** */
|
||||
hasFreeChanged:function () {
|
||||
return this._isPropertyChanged('free');
|
||||
},
|
||||
/** */
|
||||
hasFreeChanged: function () {
|
||||
return this._isPropertyChanged('free');
|
||||
},
|
||||
|
||||
/** */
|
||||
hasFreeDisplacementChanged:function () {
|
||||
return this._isPropertyChanged('freeDisplacement');
|
||||
},
|
||||
/** */
|
||||
hasFreeDisplacementChanged: function () {
|
||||
return this._isPropertyChanged('freeDisplacement');
|
||||
},
|
||||
|
||||
/** */
|
||||
setShrunken:function (value) {
|
||||
this._setProperty('shrink', value);
|
||||
},
|
||||
/** */
|
||||
setShrunken: function (value) {
|
||||
this._setProperty('shrink', value);
|
||||
},
|
||||
|
||||
/** */
|
||||
areChildrenShrunken:function () {
|
||||
return this._getProperty('shrink');
|
||||
},
|
||||
/** */
|
||||
areChildrenShrunken: function () {
|
||||
return this._getProperty('shrink');
|
||||
},
|
||||
|
||||
/** */
|
||||
setOrder:function (order) {
|
||||
$assert(typeof order === 'number' && isFinite(order), "Order can not be null. Value:" + order);
|
||||
this._setProperty('order', order);
|
||||
},
|
||||
/** */
|
||||
setOrder: function (order) {
|
||||
$assert(
|
||||
typeof order === 'number' && isFinite(order),
|
||||
'Order can not be null. Value:' + order
|
||||
);
|
||||
this._setProperty('order', order);
|
||||
},
|
||||
|
||||
/** */
|
||||
resetPositionState:function () {
|
||||
var prop = this._properties['position'];
|
||||
if (prop) {
|
||||
prop.hasChanged = false;
|
||||
}
|
||||
},
|
||||
/** */
|
||||
resetPositionState: function () {
|
||||
var prop = this._properties['position'];
|
||||
if (prop) {
|
||||
prop.hasChanged = false;
|
||||
}
|
||||
},
|
||||
|
||||
/** */
|
||||
resetOrderState:function () {
|
||||
var prop = this._properties['order'];
|
||||
if (prop) {
|
||||
prop.hasChanged = false;
|
||||
}
|
||||
},
|
||||
/** */
|
||||
resetOrderState: function () {
|
||||
var prop = this._properties['order'];
|
||||
if (prop) {
|
||||
prop.hasChanged = false;
|
||||
}
|
||||
},
|
||||
|
||||
/** */
|
||||
resetFreeState:function () {
|
||||
var prop = this._properties['freeDisplacement'];
|
||||
if (prop) {
|
||||
prop.hasChanged = false;
|
||||
}
|
||||
},
|
||||
/** */
|
||||
resetFreeState: function () {
|
||||
var prop = this._properties['freeDisplacement'];
|
||||
if (prop) {
|
||||
prop.hasChanged = false;
|
||||
}
|
||||
},
|
||||
|
||||
/** */
|
||||
getOrder:function () {
|
||||
return this._getProperty('order');
|
||||
},
|
||||
/** */
|
||||
getOrder: function () {
|
||||
return this._getProperty('order');
|
||||
},
|
||||
|
||||
/** */
|
||||
hasOrderChanged:function () {
|
||||
return this._isPropertyChanged('order');
|
||||
},
|
||||
/** */
|
||||
hasOrderChanged: function () {
|
||||
return this._isPropertyChanged('order');
|
||||
},
|
||||
|
||||
/** */
|
||||
hasPositionChanged:function () {
|
||||
return this._isPropertyChanged('position');
|
||||
},
|
||||
/** */
|
||||
hasPositionChanged: function () {
|
||||
return this._isPropertyChanged('position');
|
||||
},
|
||||
|
||||
/** */
|
||||
hasSizeChanged:function () {
|
||||
return this._isPropertyChanged('size');
|
||||
},
|
||||
/** */
|
||||
hasSizeChanged: function () {
|
||||
return this._isPropertyChanged('size');
|
||||
},
|
||||
|
||||
/** */
|
||||
getPosition:function () {
|
||||
return this._getProperty('position');
|
||||
},
|
||||
/** */
|
||||
getPosition: function () {
|
||||
return this._getProperty('position');
|
||||
},
|
||||
|
||||
/** */
|
||||
setSize:function (size) {
|
||||
$assert($defined(size), "Size can not be null");
|
||||
this._setProperty('size', Object.clone(size));
|
||||
},
|
||||
/** */
|
||||
setSize: function (size) {
|
||||
$assert($defined(size), 'Size can not be null');
|
||||
this._setProperty('size', Object.clone(size));
|
||||
},
|
||||
|
||||
/** */
|
||||
getSize:function () {
|
||||
return this._getProperty('size');
|
||||
},
|
||||
/** */
|
||||
getSize: function () {
|
||||
return this._getProperty('size');
|
||||
},
|
||||
|
||||
/** */
|
||||
setFreeDisplacement:function (displacement) {
|
||||
$assert($defined(displacement), "Position can not be null");
|
||||
$assert($defined(displacement.x), "x can not be null");
|
||||
$assert($defined(displacement.y), "y can not be null");
|
||||
var oldDisplacement = this.getFreeDisplacement();
|
||||
var newDisplacement = {x:oldDisplacement.x + displacement.x, y:oldDisplacement.y + displacement.y};
|
||||
|
||||
this._setProperty('freeDisplacement', Object.clone(newDisplacement));
|
||||
},
|
||||
|
||||
/** */
|
||||
resetFreeDisplacement:function () {
|
||||
this._setProperty('freeDisplacement', {x:0, y:0});
|
||||
},
|
||||
|
||||
/** */
|
||||
getFreeDisplacement:function () {
|
||||
var freeDisplacement = this._getProperty('freeDisplacement');
|
||||
return (freeDisplacement || {x:0, y:0});
|
||||
},
|
||||
|
||||
/** */
|
||||
setPosition:function (position) {
|
||||
$assert($defined(position), "Position can not be null");
|
||||
$assert($defined(position.x), "x can not be null");
|
||||
$assert($defined(position.y), "y can not be null");
|
||||
|
||||
// This is a performance improvement to avoid movements that really could be avoided.
|
||||
var currentPos = this.getPosition();
|
||||
if (currentPos == null || Math.abs(currentPos.x - position.x) > 2 || Math.abs(currentPos.y - position.y) > 2)
|
||||
this._setProperty('position', position);
|
||||
},
|
||||
|
||||
_setProperty:function (key, value) {
|
||||
var prop = this._properties[key];
|
||||
if (!prop) {
|
||||
prop = {
|
||||
hasChanged:false,
|
||||
value:null,
|
||||
oldValue:null
|
||||
/** */
|
||||
setFreeDisplacement: function (displacement) {
|
||||
$assert($defined(displacement), 'Position can not be null');
|
||||
$assert($defined(displacement.x), 'x can not be null');
|
||||
$assert($defined(displacement.y), 'y can not be null');
|
||||
var oldDisplacement = this.getFreeDisplacement();
|
||||
var newDisplacement = {
|
||||
x: oldDisplacement.x + displacement.x,
|
||||
y: oldDisplacement.y + displacement.y,
|
||||
};
|
||||
}
|
||||
|
||||
// Only update if the property has changed ...
|
||||
if (JSON.stringify(prop.value) != JSON.stringify(value)) {
|
||||
prop.oldValue = prop.value;
|
||||
prop.value = value;
|
||||
prop.hasChanged = true;
|
||||
}
|
||||
this._properties[key] = prop;
|
||||
},
|
||||
this._setProperty('freeDisplacement', Object.clone(newDisplacement));
|
||||
},
|
||||
|
||||
_getProperty:function (key) {
|
||||
var prop = this._properties[key];
|
||||
return $defined(prop) ? prop.value : null;
|
||||
},
|
||||
/** */
|
||||
resetFreeDisplacement: function () {
|
||||
this._setProperty('freeDisplacement', { x: 0, y: 0 });
|
||||
},
|
||||
|
||||
_isPropertyChanged:function (key) {
|
||||
var prop = this._properties[key];
|
||||
return prop ? prop.hasChanged : false;
|
||||
},
|
||||
/** */
|
||||
getFreeDisplacement: function () {
|
||||
var freeDisplacement = this._getProperty('freeDisplacement');
|
||||
return freeDisplacement || { x: 0, y: 0 };
|
||||
},
|
||||
|
||||
/** */
|
||||
getSorter:function () {
|
||||
return this._sorter;
|
||||
},
|
||||
/** */
|
||||
setPosition: function (position) {
|
||||
$assert($defined(position), 'Position can not be null');
|
||||
$assert($defined(position.x), 'x can not be null');
|
||||
$assert($defined(position.y), 'y can not be null');
|
||||
|
||||
/** @return {String} returns id, order, position, size and shrink information*/
|
||||
toString:function () {
|
||||
return "[id:" + this.getId() + ", order:" + this.getOrder() + ", position: {" + this.getPosition().x + "," + this.getPosition().y + "}, size: {" + this.getSize().width + "," + this.getSize().height + "}, shrink:" + this.areChildrenShrunken() + "]";
|
||||
// This is a performance improvement to avoid movements that really could be avoided.
|
||||
var currentPos = this.getPosition();
|
||||
if (
|
||||
currentPos == null ||
|
||||
Math.abs(currentPos.x - position.x) > 2 ||
|
||||
Math.abs(currentPos.y - position.y) > 2
|
||||
)
|
||||
this._setProperty('position', position);
|
||||
},
|
||||
|
||||
_setProperty: function (key, value) {
|
||||
var prop = this._properties[key];
|
||||
if (!prop) {
|
||||
prop = {
|
||||
hasChanged: false,
|
||||
value: null,
|
||||
oldValue: null,
|
||||
};
|
||||
}
|
||||
|
||||
// Only update if the property has changed ...
|
||||
if (JSON.stringify(prop.value) != JSON.stringify(value)) {
|
||||
prop.oldValue = prop.value;
|
||||
prop.value = value;
|
||||
prop.hasChanged = true;
|
||||
}
|
||||
this._properties[key] = prop;
|
||||
},
|
||||
|
||||
_getProperty: function (key) {
|
||||
var prop = this._properties[key];
|
||||
return $defined(prop) ? prop.value : null;
|
||||
},
|
||||
|
||||
_isPropertyChanged: function (key) {
|
||||
var prop = this._properties[key];
|
||||
return prop ? prop.hasChanged : false;
|
||||
},
|
||||
|
||||
/** */
|
||||
getSorter: function () {
|
||||
return this._sorter;
|
||||
},
|
||||
|
||||
/** @return {String} returns id, order, position, size and shrink information*/
|
||||
toString: function () {
|
||||
return (
|
||||
'[id:' +
|
||||
this.getId() +
|
||||
', order:' +
|
||||
this.getOrder() +
|
||||
', position: {' +
|
||||
this.getPosition().x +
|
||||
',' +
|
||||
this.getPosition().y +
|
||||
'}, size: {' +
|
||||
this.getSize().width +
|
||||
',' +
|
||||
this.getSize().height +
|
||||
'}, shrink:' +
|
||||
this.areChildrenShrunken() +
|
||||
']'
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
});
|
||||
);
|
||||
|
||||
export default Node;
|
||||
|
@ -15,236 +15,274 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const Node = require('./Node').default;
|
||||
const SymmetricSorter = require('./SymmetricSorter').default
|
||||
const BalancedSorter = require('./BalancedSorter').default;
|
||||
const SymmetricSorter = require('./SymmetricSorter').default;
|
||||
const BalancedSorter = require('./BalancedSorter').default;
|
||||
|
||||
const OriginalLayout = new Class(/** @lends OriginalLayout */{
|
||||
/**
|
||||
* @constructs
|
||||
* @param treeSet
|
||||
*/
|
||||
initialize:function (treeSet) {
|
||||
this._treeSet = treeSet;
|
||||
},
|
||||
const OriginalLayout = new Class(
|
||||
/** @lends OriginalLayout */ {
|
||||
/**
|
||||
* @constructs
|
||||
* @param treeSet
|
||||
*/
|
||||
initialize: function (treeSet) {
|
||||
this._treeSet = treeSet;
|
||||
},
|
||||
|
||||
/** */
|
||||
createNode:function (id, size, position, type) {
|
||||
$assert($defined(id), "id can not be null");
|
||||
$assert(size, "size can not be null");
|
||||
$assert(position, "position can not be null");
|
||||
$assert(type, "type can not be null");
|
||||
/** */
|
||||
createNode: function (id, size, position, type) {
|
||||
$assert($defined(id), 'id can not be null');
|
||||
$assert(size, 'size can not be null');
|
||||
$assert(position, 'position can not be null');
|
||||
$assert(type, 'type can not be null');
|
||||
|
||||
var strategy = type === 'root' ?
|
||||
OriginalLayout.BALANCED_SORTER :
|
||||
OriginalLayout.SYMMETRIC_SORTER;
|
||||
return new Node(id, size, position, strategy);
|
||||
},
|
||||
var strategy =
|
||||
type === 'root' ? OriginalLayout.BALANCED_SORTER : OriginalLayout.SYMMETRIC_SORTER;
|
||||
return new Node(id, size, position, strategy);
|
||||
},
|
||||
|
||||
/** */
|
||||
connectNode:function (parentId, childId, order) {
|
||||
/** */
|
||||
connectNode: function (parentId, childId, order) {
|
||||
var parent = this._treeSet.find(parentId);
|
||||
var child = this._treeSet.find(childId);
|
||||
|
||||
var parent = this._treeSet.find(parentId);
|
||||
var child = this._treeSet.find(childId);
|
||||
// Insert the new node ...
|
||||
var sorter = parent.getSorter();
|
||||
sorter.insert(this._treeSet, parent, child, order);
|
||||
|
||||
// Insert the new node ...
|
||||
var sorter = parent.getSorter();
|
||||
sorter.insert(this._treeSet, parent, child, order);
|
||||
// Connect the new node ...
|
||||
this._treeSet.connect(parentId, childId);
|
||||
|
||||
// Connect the new node ...
|
||||
this._treeSet.connect(parentId, childId);
|
||||
// Fire a basic validation ...
|
||||
sorter.verify(this._treeSet, parent);
|
||||
},
|
||||
|
||||
// Fire a basic validation ...
|
||||
sorter.verify(this._treeSet, parent);
|
||||
},
|
||||
/** */
|
||||
disconnectNode: function (nodeId) {
|
||||
var node = this._treeSet.find(nodeId);
|
||||
var parent = this._treeSet.getParent(node);
|
||||
$assert(parent, 'Node already disconnected');
|
||||
|
||||
/** */
|
||||
disconnectNode:function (nodeId) {
|
||||
var node = this._treeSet.find(nodeId);
|
||||
var parent = this._treeSet.getParent(node);
|
||||
$assert(parent, "Node already disconnected");
|
||||
// Make it fixed
|
||||
node.setFree(false);
|
||||
node.resetFreeDisplacement();
|
||||
|
||||
// Make it fixed
|
||||
node.setFree(false);
|
||||
node.resetFreeDisplacement();
|
||||
// Remove from children list.
|
||||
var sorter = parent.getSorter();
|
||||
sorter.detach(this._treeSet, node);
|
||||
|
||||
// Remove from children list.
|
||||
var sorter = parent.getSorter();
|
||||
sorter.detach(this._treeSet, node);
|
||||
// Disconnect the new node ...
|
||||
this._treeSet.disconnect(nodeId);
|
||||
|
||||
// Disconnect the new node ...
|
||||
this._treeSet.disconnect(nodeId);
|
||||
// Fire a basic validation ...
|
||||
parent.getSorter().verify(this._treeSet, parent);
|
||||
},
|
||||
|
||||
// Fire a basic validation ...
|
||||
parent.getSorter().verify(this._treeSet, parent);
|
||||
},
|
||||
/** */
|
||||
layout: function () {
|
||||
var roots = this._treeSet.getTreeRoots();
|
||||
_.each(
|
||||
roots,
|
||||
function (node) {
|
||||
// Calculate all node heights ...
|
||||
var sorter = node.getSorter();
|
||||
|
||||
/** */
|
||||
layout:function () {
|
||||
var roots = this._treeSet.getTreeRoots();
|
||||
_.each(roots, function (node) {
|
||||
var heightById = sorter.computeChildrenIdByHeights(this._treeSet, node);
|
||||
|
||||
// Calculate all node heights ...
|
||||
var sorter = node.getSorter();
|
||||
this._layoutChildren(node, heightById);
|
||||
|
||||
var heightById = sorter.computeChildrenIdByHeights(this._treeSet, node);
|
||||
this._fixOverlapping(node, heightById);
|
||||
},
|
||||
this
|
||||
);
|
||||
},
|
||||
|
||||
this._layoutChildren(node, heightById);
|
||||
|
||||
this._fixOverlapping(node, heightById);
|
||||
}, this);
|
||||
},
|
||||
|
||||
_layoutChildren:function (node, heightById) {
|
||||
|
||||
var nodeId = node.getId();
|
||||
var children = this._treeSet.getChildren(node);
|
||||
var parent = this._treeSet.getParent(node);
|
||||
var childrenOrderMoved = children.some(function (child) {
|
||||
return child.hasOrderChanged();
|
||||
});
|
||||
var childrenSizeChanged = children.some(function (child) {
|
||||
return child.hasSizeChanged();
|
||||
});
|
||||
|
||||
// If ether any of the nodes has been changed of position or the height of the children is not
|
||||
// the same, children nodes must be repositioned ....
|
||||
var newBranchHeight = heightById[nodeId];
|
||||
|
||||
var parentHeightChanged = $defined(parent) ? parent._heightChanged : false;
|
||||
var heightChanged = node._branchHeight != newBranchHeight;
|
||||
node._heightChanged = heightChanged || parentHeightChanged;
|
||||
|
||||
if (childrenOrderMoved || childrenSizeChanged || heightChanged || parentHeightChanged) {
|
||||
var sorter = node.getSorter();
|
||||
var offsetById = sorter.computeOffsets(this._treeSet, node);
|
||||
var parentPosition = node.getPosition();
|
||||
var me = this;
|
||||
_.each(children, function (child) {
|
||||
var offset = offsetById[child.getId()];
|
||||
|
||||
var childFreeDisplacement = child.getFreeDisplacement();
|
||||
var direction = node.getSorter().getChildDirection(me._treeSet, child);
|
||||
|
||||
if ((direction > 0 && childFreeDisplacement.x < 0) || (direction < 0 && childFreeDisplacement.x > 0)) {
|
||||
child.resetFreeDisplacement();
|
||||
child.setFreeDisplacement({x:-childFreeDisplacement.x, y:childFreeDisplacement.y});
|
||||
}
|
||||
|
||||
offset.x += child.getFreeDisplacement().x;
|
||||
offset.y += child.getFreeDisplacement().y;
|
||||
|
||||
var parentX = parentPosition.x;
|
||||
var parentY = parentPosition.y;
|
||||
|
||||
var newPos = {x:parentX + offset.x, y:parentY + offset.y + me._calculateAlignOffset(node, child, heightById)};
|
||||
me._treeSet.updateBranchPosition(child, newPos);
|
||||
_layoutChildren: function (node, heightById) {
|
||||
var nodeId = node.getId();
|
||||
var children = this._treeSet.getChildren(node);
|
||||
var parent = this._treeSet.getParent(node);
|
||||
var childrenOrderMoved = children.some(function (child) {
|
||||
return child.hasOrderChanged();
|
||||
});
|
||||
var childrenSizeChanged = children.some(function (child) {
|
||||
return child.hasSizeChanged();
|
||||
});
|
||||
|
||||
node._branchHeight = newBranchHeight;
|
||||
}
|
||||
// If ether any of the nodes has been changed of position or the height of the children is not
|
||||
// the same, children nodes must be repositioned ....
|
||||
var newBranchHeight = heightById[nodeId];
|
||||
|
||||
// Continue reordering the children nodes ...
|
||||
_.each(children, function (child) {
|
||||
this._layoutChildren(child, heightById);
|
||||
}, this);
|
||||
},
|
||||
var parentHeightChanged = $defined(parent) ? parent._heightChanged : false;
|
||||
var heightChanged = node._branchHeight != newBranchHeight;
|
||||
node._heightChanged = heightChanged || parentHeightChanged;
|
||||
|
||||
_calculateAlignOffset:function (node, child, heightById) {
|
||||
if (child.isFree()) {
|
||||
return 0;
|
||||
}
|
||||
if (childrenOrderMoved || childrenSizeChanged || heightChanged || parentHeightChanged) {
|
||||
var sorter = node.getSorter();
|
||||
var offsetById = sorter.computeOffsets(this._treeSet, node);
|
||||
var parentPosition = node.getPosition();
|
||||
var me = this;
|
||||
_.each(children, function (child) {
|
||||
var offset = offsetById[child.getId()];
|
||||
|
||||
var offset = 0;
|
||||
var childFreeDisplacement = child.getFreeDisplacement();
|
||||
var direction = node.getSorter().getChildDirection(me._treeSet, child);
|
||||
|
||||
var nodeHeight = node.getSize().height;
|
||||
var childHeight = child.getSize().height;
|
||||
if (
|
||||
(direction > 0 && childFreeDisplacement.x < 0) ||
|
||||
(direction < 0 && childFreeDisplacement.x > 0)
|
||||
) {
|
||||
child.resetFreeDisplacement();
|
||||
child.setFreeDisplacement({
|
||||
x: -childFreeDisplacement.x,
|
||||
y: childFreeDisplacement.y,
|
||||
});
|
||||
}
|
||||
|
||||
if (this._treeSet.isStartOfSubBranch(child) && this._branchIsTaller(child, heightById)) {
|
||||
if (this._treeSet.hasSinglePathToSingleLeaf(child)) {
|
||||
offset = heightById[child.getId()] / 2 - (childHeight + child.getSorter()._getVerticalPadding() * 2) / 2;
|
||||
} else {
|
||||
offset = this._treeSet.isLeaf(child) ? 0 : -(childHeight - nodeHeight) / 2;
|
||||
offset.x += child.getFreeDisplacement().x;
|
||||
offset.y += child.getFreeDisplacement().y;
|
||||
|
||||
var parentX = parentPosition.x;
|
||||
var parentY = parentPosition.y;
|
||||
|
||||
var newPos = {
|
||||
x: parentX + offset.x,
|
||||
y: parentY + offset.y + me._calculateAlignOffset(node, child, heightById),
|
||||
};
|
||||
me._treeSet.updateBranchPosition(child, newPos);
|
||||
});
|
||||
|
||||
node._branchHeight = newBranchHeight;
|
||||
}
|
||||
} else if (nodeHeight > childHeight) {
|
||||
if (this._treeSet.getSiblings(child).length > 0) {
|
||||
offset = 0;
|
||||
} else {
|
||||
offset = nodeHeight / 2 - childHeight / 2;
|
||||
|
||||
// Continue reordering the children nodes ...
|
||||
_.each(
|
||||
children,
|
||||
function (child) {
|
||||
this._layoutChildren(child, heightById);
|
||||
},
|
||||
this
|
||||
);
|
||||
},
|
||||
|
||||
_calculateAlignOffset: function (node, child, heightById) {
|
||||
if (child.isFree()) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (childHeight > nodeHeight) {
|
||||
if (this._treeSet.getSiblings(child).length > 0) {
|
||||
offset = 0;
|
||||
} else {
|
||||
offset = -(childHeight / 2 - nodeHeight / 2);
|
||||
|
||||
var offset = 0;
|
||||
|
||||
var nodeHeight = node.getSize().height;
|
||||
var childHeight = child.getSize().height;
|
||||
|
||||
if (
|
||||
this._treeSet.isStartOfSubBranch(child) &&
|
||||
this._branchIsTaller(child, heightById)
|
||||
) {
|
||||
if (this._treeSet.hasSinglePathToSingleLeaf(child)) {
|
||||
offset =
|
||||
heightById[child.getId()] / 2 -
|
||||
(childHeight + child.getSorter()._getVerticalPadding() * 2) / 2;
|
||||
} else {
|
||||
offset = this._treeSet.isLeaf(child) ? 0 : -(childHeight - nodeHeight) / 2;
|
||||
}
|
||||
} else if (nodeHeight > childHeight) {
|
||||
if (this._treeSet.getSiblings(child).length > 0) {
|
||||
offset = 0;
|
||||
} else {
|
||||
offset = nodeHeight / 2 - childHeight / 2;
|
||||
}
|
||||
} else if (childHeight > nodeHeight) {
|
||||
if (this._treeSet.getSiblings(child).length > 0) {
|
||||
offset = 0;
|
||||
} else {
|
||||
offset = -(childHeight / 2 - nodeHeight / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return offset;
|
||||
},
|
||||
return offset;
|
||||
},
|
||||
|
||||
_branchIsTaller:function (node, heightById) {
|
||||
return heightById[node.getId()] > (node.getSize().height + node.getSorter()._getVerticalPadding() * 2);
|
||||
},
|
||||
_branchIsTaller: function (node, heightById) {
|
||||
return (
|
||||
heightById[node.getId()] >
|
||||
node.getSize().height + node.getSorter()._getVerticalPadding() * 2
|
||||
);
|
||||
},
|
||||
|
||||
_fixOverlapping:function (node, heightById) {
|
||||
var children = this._treeSet.getChildren(node);
|
||||
_fixOverlapping: function (node, heightById) {
|
||||
var children = this._treeSet.getChildren(node);
|
||||
|
||||
if (node.isFree()) {
|
||||
this._shiftBranches(node, heightById);
|
||||
}
|
||||
|
||||
_.each(children, function (child) {
|
||||
this._fixOverlapping(child, heightById);
|
||||
}, this);
|
||||
},
|
||||
|
||||
_shiftBranches:function (node, heightById) {
|
||||
var shiftedBranches = [node];
|
||||
|
||||
var siblingsToShift = this._treeSet.getSiblingsInVerticalDirection(node, node.getFreeDisplacement().y);
|
||||
var last = node;
|
||||
_.each(siblingsToShift, function (sibling) {
|
||||
var overlappingOccurs = shiftedBranches.some(function (shiftedBranch) {
|
||||
return this._branchesOverlap(shiftedBranch, sibling, heightById);
|
||||
}, this);
|
||||
|
||||
if (!sibling.isFree() || overlappingOccurs) {
|
||||
var sAmount = node.getFreeDisplacement().y;
|
||||
this._treeSet.shiftBranchPosition(sibling, 0, sAmount);
|
||||
shiftedBranches.push(sibling);
|
||||
if (node.isFree()) {
|
||||
this._shiftBranches(node, heightById);
|
||||
}
|
||||
}, this);
|
||||
|
||||
var branchesToShift = this._treeSet.getBranchesInVerticalDirection(node, node.getFreeDisplacement().y).filter(function (branch) {
|
||||
return !shiftedBranches.contains(branch);
|
||||
});
|
||||
_.each(
|
||||
children,
|
||||
function (child) {
|
||||
this._fixOverlapping(child, heightById);
|
||||
},
|
||||
this
|
||||
);
|
||||
},
|
||||
|
||||
_.each(branchesToShift, function (branch) {
|
||||
var bAmount = node.getFreeDisplacement().y;
|
||||
this._treeSet.shiftBranchPosition(branch, 0, bAmount);
|
||||
shiftedBranches.push(branch);
|
||||
last = branch;
|
||||
}, this);
|
||||
},
|
||||
_shiftBranches: function (node, heightById) {
|
||||
var shiftedBranches = [node];
|
||||
|
||||
_branchesOverlap:function (branchA, branchB, heightById) {
|
||||
// a branch doesn't really overlap with itself
|
||||
if (branchA == branchB) {
|
||||
return false;
|
||||
}
|
||||
var siblingsToShift = this._treeSet.getSiblingsInVerticalDirection(
|
||||
node,
|
||||
node.getFreeDisplacement().y
|
||||
);
|
||||
var last = node;
|
||||
_.each(
|
||||
siblingsToShift,
|
||||
function (sibling) {
|
||||
var overlappingOccurs = shiftedBranches.some(function (shiftedBranch) {
|
||||
return this._branchesOverlap(shiftedBranch, sibling, heightById);
|
||||
}, this);
|
||||
|
||||
var topA = branchA.getPosition().y - heightById[branchA.getId()] / 2;
|
||||
var bottomA = branchA.getPosition().y + heightById[branchA.getId()] / 2;
|
||||
var topB = branchB.getPosition().y - heightById[branchB.getId()] / 2;
|
||||
var bottomB = branchB.getPosition().y + heightById[branchB.getId()] / 2;
|
||||
if (!sibling.isFree() || overlappingOccurs) {
|
||||
var sAmount = node.getFreeDisplacement().y;
|
||||
this._treeSet.shiftBranchPosition(sibling, 0, sAmount);
|
||||
shiftedBranches.push(sibling);
|
||||
}
|
||||
},
|
||||
this
|
||||
);
|
||||
|
||||
return !(topA >= bottomB || bottomA <= topB);
|
||||
var branchesToShift = this._treeSet
|
||||
.getBranchesInVerticalDirection(node, node.getFreeDisplacement().y)
|
||||
.filter(function (branch) {
|
||||
return !shiftedBranches.contains(branch);
|
||||
});
|
||||
|
||||
_.each(
|
||||
branchesToShift,
|
||||
function (branch) {
|
||||
var bAmount = node.getFreeDisplacement().y;
|
||||
this._treeSet.shiftBranchPosition(branch, 0, bAmount);
|
||||
shiftedBranches.push(branch);
|
||||
last = branch;
|
||||
},
|
||||
this
|
||||
);
|
||||
},
|
||||
|
||||
_branchesOverlap: function (branchA, branchB, heightById) {
|
||||
// a branch doesn't really overlap with itself
|
||||
if (branchA == branchB) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var topA = branchA.getPosition().y - heightById[branchA.getId()] / 2;
|
||||
var bottomA = branchA.getPosition().y + heightById[branchA.getId()] / 2;
|
||||
var topB = branchB.getPosition().y - heightById[branchB.getId()] / 2;
|
||||
var bottomB = branchB.getPosition().y + heightById[branchB.getId()] / 2;
|
||||
|
||||
return !(topA >= bottomB || bottomA <= topB);
|
||||
},
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
);
|
||||
|
||||
/**
|
||||
* @type {mindplot.layout.SymmetricSorter}
|
||||
|
@ -16,381 +16,444 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const RootedTreeSet = new Class(/** @lends RootedTreeSet */{
|
||||
/** @constructs */
|
||||
initialize:function () {
|
||||
this._rootNodes = [];
|
||||
},
|
||||
const RootedTreeSet = new Class(
|
||||
/** @lends RootedTreeSet */ {
|
||||
/** @constructs */
|
||||
initialize: function () {
|
||||
this._rootNodes = [];
|
||||
},
|
||||
|
||||
/**
|
||||
* @param root
|
||||
* @throws will throw an error if root is null or undefined
|
||||
*/
|
||||
setRoot:function (root) {
|
||||
$assert(root, 'root can not be null');
|
||||
this._rootNodes.push(this._decodate(root));
|
||||
},
|
||||
/**
|
||||
* @param root
|
||||
* @throws will throw an error if root is null or undefined
|
||||
*/
|
||||
setRoot: function (root) {
|
||||
$assert(root, 'root can not be null');
|
||||
this._rootNodes.push(this._decodate(root));
|
||||
},
|
||||
|
||||
/** getter */
|
||||
getTreeRoots:function () {
|
||||
return this._rootNodes;
|
||||
},
|
||||
/** getter */
|
||||
getTreeRoots: function () {
|
||||
return this._rootNodes;
|
||||
},
|
||||
|
||||
_decodate:function (node) {
|
||||
node._children = [];
|
||||
return node;
|
||||
},
|
||||
_decodate: function (node) {
|
||||
node._children = [];
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {mindplot.model.NodeModel} node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @throws will throw an error if node with id already exists
|
||||
* @throws will throw an error if node has been added already
|
||||
*/
|
||||
add:function (node) {
|
||||
$assert(node, 'node can not be null');
|
||||
$assert(!this.find(node.getId(), false), 'node already exits with this id. Id:' + node.getId());
|
||||
$assert(!node._children, 'node already added');
|
||||
this._rootNodes.push(this._decodate(node));
|
||||
},
|
||||
/**
|
||||
* @param {mindplot.model.NodeModel} node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @throws will throw an error if node with id already exists
|
||||
* @throws will throw an error if node has been added already
|
||||
*/
|
||||
add: function (node) {
|
||||
$assert(node, 'node can not be null');
|
||||
$assert(
|
||||
!this.find(node.getId(), false),
|
||||
'node already exits with this id. Id:' + node.getId()
|
||||
);
|
||||
$assert(!node._children, 'node already added');
|
||||
this._rootNodes.push(this._decodate(node));
|
||||
},
|
||||
|
||||
/**
|
||||
* @param nodeId
|
||||
* @throws will throw an error if nodeId is null or undefined
|
||||
*/
|
||||
remove: function (nodeId) {
|
||||
$assert($defined(nodeId), 'nodeId can not be null');
|
||||
var node = this.find(nodeId);
|
||||
this._rootNodes.erase(node);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param nodeId
|
||||
* @throws will throw an error if nodeId is null or undefined
|
||||
*/
|
||||
remove:function (nodeId) {
|
||||
$assert($defined(nodeId), 'nodeId can not be null');
|
||||
var node = this.find(nodeId);
|
||||
this._rootNodes.erase(node);
|
||||
},
|
||||
/**
|
||||
* @param parentId
|
||||
* @param childId
|
||||
* @throws will throw an error if parentId is null or undefined
|
||||
* @throws will throw an error if childId is null or undefined
|
||||
* @throws will throw an error if node with id childId is already a child of parent
|
||||
*/
|
||||
connect: function (parentId, childId) {
|
||||
$assert($defined(parentId), 'parent can not be null');
|
||||
$assert($defined(childId), 'child can not be null');
|
||||
|
||||
/**
|
||||
* @param parentId
|
||||
* @param childId
|
||||
* @throws will throw an error if parentId is null or undefined
|
||||
* @throws will throw an error if childId is null or undefined
|
||||
* @throws will throw an error if node with id childId is already a child of parent
|
||||
*/
|
||||
connect:function (parentId, childId) {
|
||||
$assert($defined(parentId), 'parent can not be null');
|
||||
$assert($defined(childId), 'child can not be null');
|
||||
var parent = this.find(parentId);
|
||||
var child = this.find(childId, true);
|
||||
$assert(
|
||||
!child._parent,
|
||||
'node already connected. Id:' + child.getId() + ',previous:' + child._parent
|
||||
);
|
||||
|
||||
var parent = this.find(parentId);
|
||||
var child = this.find(childId, true);
|
||||
$assert(!child._parent, 'node already connected. Id:' + child.getId() + ",previous:" + child._parent);
|
||||
parent._children.push(child);
|
||||
child._parent = parent;
|
||||
this._rootNodes.erase(child);
|
||||
},
|
||||
|
||||
parent._children.push(child);
|
||||
child._parent = parent;
|
||||
this._rootNodes.erase(child);
|
||||
},
|
||||
/**
|
||||
* @param nodeId
|
||||
* @throws will throw an error if nodeId is null or undefined
|
||||
* @throws will throw an error if node is not connected
|
||||
*/
|
||||
disconnect: function (nodeId) {
|
||||
$assert($defined(nodeId), 'nodeId can not be null');
|
||||
var node = this.find(nodeId);
|
||||
$assert(node._parent, 'Node is not connected');
|
||||
|
||||
/**
|
||||
* @param nodeId
|
||||
* @throws will throw an error if nodeId is null or undefined
|
||||
* @throws will throw an error if node is not connected
|
||||
*/
|
||||
disconnect:function (nodeId) {
|
||||
$assert($defined(nodeId), 'nodeId can not be null');
|
||||
var node = this.find(nodeId);
|
||||
$assert(node._parent, "Node is not connected");
|
||||
node._parent._children.erase(node);
|
||||
this._rootNodes.push(node);
|
||||
node._parent = null;
|
||||
},
|
||||
|
||||
node._parent._children.erase(node);
|
||||
this._rootNodes.push(node);
|
||||
node._parent = null;
|
||||
},
|
||||
/**
|
||||
* @param id
|
||||
* @param validate
|
||||
* @throws will throw an error if id is null or undefined
|
||||
* @throws will throw an error if node cannot be found
|
||||
* @return node
|
||||
*/
|
||||
find: function (id, validate) {
|
||||
$assert($defined(id), 'id can not be null');
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param validate
|
||||
* @throws will throw an error if id is null or undefined
|
||||
* @throws will throw an error if node cannot be found
|
||||
* @return node
|
||||
*/
|
||||
find:function (id, validate) {
|
||||
$assert($defined(id), 'id can not be null');
|
||||
|
||||
var graphs = this._rootNodes;
|
||||
var result = null;
|
||||
for (var i = 0; i < graphs.length; i++) {
|
||||
var node = graphs[i];
|
||||
result = this._find(id, node);
|
||||
if (result) {
|
||||
break;
|
||||
var graphs = this._rootNodes;
|
||||
var result = null;
|
||||
for (var i = 0; i < graphs.length; i++) {
|
||||
var node = graphs[i];
|
||||
result = this._find(id, node);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
validate = !$defined(validate) ? true : validate;
|
||||
$assert(validate ? result : true, 'node could not be found id:' + id + "\n,RootedTreeSet" + this.dump());
|
||||
return result;
|
||||
validate = !$defined(validate) ? true : validate;
|
||||
$assert(
|
||||
validate ? result : true,
|
||||
'node could not be found id:' + id + '\n,RootedTreeSet' + this.dump()
|
||||
);
|
||||
return result;
|
||||
},
|
||||
|
||||
},
|
||||
_find: function (id, parent) {
|
||||
if (parent.getId() == id) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
_find:function (id, parent) {
|
||||
if (parent.getId() == id) {
|
||||
return parent;
|
||||
var result = null;
|
||||
var children = parent._children;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
result = this._find(id, child);
|
||||
if (result) break;
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
var result = null;
|
||||
var children = parent._children;
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
result = this._find(id, child);
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if nodeId is null or undefined
|
||||
* @return children
|
||||
*/
|
||||
getChildren: function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
return node._children;
|
||||
},
|
||||
|
||||
return result;
|
||||
},
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @return root node or the provided node, if it has no parent
|
||||
*/
|
||||
getRootNode: function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
var parent = this.getParent(node);
|
||||
if ($defined(parent)) {
|
||||
return this.getRootNode(parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if nodeId is null or undefined
|
||||
* @return children
|
||||
*/
|
||||
getChildren:function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
return node._children;
|
||||
},
|
||||
return node;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @return root node or the provided node, if it has no parent
|
||||
*/
|
||||
getRootNode:function (node) {
|
||||
$assert(node, "node cannot be null");
|
||||
var parent = this.getParent(node);
|
||||
if ($defined(parent)) {
|
||||
return this.getRootNode(parent);
|
||||
}
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @return {Array} ancestors*/
|
||||
getAncestors: function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
return this._getAncestors(this.getParent(node), []);
|
||||
},
|
||||
|
||||
return node;
|
||||
},
|
||||
_getAncestors: function (node, ancestors) {
|
||||
var result = ancestors;
|
||||
if (node) {
|
||||
result.push(node);
|
||||
this._getAncestors(this.getParent(node), result);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @return {Array} ancestors*/
|
||||
getAncestors:function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
return this._getAncestors(this.getParent(node), []);
|
||||
},
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @return {Array} siblings
|
||||
*/
|
||||
getSiblings: function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
if (!$defined(node._parent)) {
|
||||
return [];
|
||||
}
|
||||
var siblings = node._parent._children.filter(function (child) {
|
||||
return child != node;
|
||||
});
|
||||
return siblings;
|
||||
},
|
||||
|
||||
_getAncestors:function (node, ancestors) {
|
||||
var result = ancestors;
|
||||
if (node) {
|
||||
result.push(node);
|
||||
this._getAncestors(this.getParent(node), result);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @return {Boolean} whether the node has a single path to a single leaf (no branching)
|
||||
*/
|
||||
hasSinglePathToSingleLeaf: function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
return this._hasSinglePathToSingleLeaf(node);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @return {Array} siblings
|
||||
*/
|
||||
getSiblings:function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
if (!$defined(node._parent)) {
|
||||
return [];
|
||||
}
|
||||
var siblings = node._parent._children.filter(function (child) {
|
||||
return child != node;
|
||||
});
|
||||
return siblings;
|
||||
},
|
||||
_hasSinglePathToSingleLeaf: function (node) {
|
||||
var children = this.getChildren(node);
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @return {Boolean} whether the node has a single path to a single leaf (no branching)
|
||||
*/
|
||||
hasSinglePathToSingleLeaf:function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
return this._hasSinglePathToSingleLeaf(node);
|
||||
},
|
||||
if (children.length == 1) {
|
||||
return this._hasSinglePathToSingleLeaf(children[0]);
|
||||
}
|
||||
|
||||
_hasSinglePathToSingleLeaf:function (node) {
|
||||
var children = this.getChildren(node);
|
||||
return children.length == 0;
|
||||
},
|
||||
|
||||
if (children.length == 1) {
|
||||
return this._hasSinglePathToSingleLeaf(children[0]);
|
||||
}
|
||||
/**
|
||||
* @param node
|
||||
* @return {Boolean} whether the node is the start of a subbranch*/
|
||||
isStartOfSubBranch: function (node) {
|
||||
return this.getSiblings(node).length > 0 && this.getChildren(node).length == 1;
|
||||
},
|
||||
|
||||
return children.length == 0;
|
||||
},
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @return {Boolean} whether the node is a leaf
|
||||
*/
|
||||
isLeaf: function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
return this.getChildren(node).length == 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @return {Boolean} whether the node is the start of a subbranch*/
|
||||
isStartOfSubBranch:function (node) {
|
||||
return this.getSiblings(node).length > 0 && this.getChildren(node).length == 1;
|
||||
},
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @return parent
|
||||
*/
|
||||
getParent: function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
return node._parent;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @return {Boolean} whether the node is a leaf
|
||||
*/
|
||||
isLeaf:function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
return this.getChildren(node).length == 0;
|
||||
},
|
||||
/**
|
||||
* @return result
|
||||
*/
|
||||
dump: function () {
|
||||
var branches = this._rootNodes;
|
||||
var result = '';
|
||||
for (var i = 0; i < branches.length; i++) {
|
||||
var branch = branches[i];
|
||||
result += this._dump(branch, '');
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @return parent
|
||||
*/
|
||||
getParent:function (node) {
|
||||
$assert(node, 'node cannot be null');
|
||||
return node._parent;
|
||||
},
|
||||
_dump: function (node, indent) {
|
||||
var result = indent + node + '\n';
|
||||
var children = this.getChildren(node);
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
result += this._dump(child, indent + ' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return result
|
||||
*/
|
||||
dump:function () {
|
||||
var branches = this._rootNodes;
|
||||
var result = "";
|
||||
for (var i = 0; i < branches.length; i++) {
|
||||
var branch = branches[i];
|
||||
result += this._dump(branch, "");
|
||||
}
|
||||
return result;
|
||||
},
|
||||
return result;
|
||||
},
|
||||
|
||||
_dump:function (node, indent) {
|
||||
var result = indent + node + "\n";
|
||||
var children = this.getChildren(node);
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
result += this._dump(child, indent + " ");
|
||||
}
|
||||
/**
|
||||
* @param canvas
|
||||
*/
|
||||
plot: function (canvas) {
|
||||
var branches = this._rootNodes;
|
||||
for (var i = 0; i < branches.length; i++) {
|
||||
var branch = branches[i];
|
||||
this._plot(canvas, branch);
|
||||
}
|
||||
},
|
||||
|
||||
return result;
|
||||
},
|
||||
_plot: function (canvas, node, root) {
|
||||
var children = this.getChildren(node);
|
||||
var cx = node.getPosition().x + canvas.width / 2 - node.getSize().width / 2;
|
||||
var cy = node.getPosition().y + canvas.height / 2 - node.getSize().height / 2;
|
||||
var rect = canvas.rect(cx, cy, node.getSize().width, node.getSize().height);
|
||||
var order = node.getOrder() == null ? 'r' : node.getOrder();
|
||||
var text = canvas.text(
|
||||
node.getPosition().x + canvas.width / 2,
|
||||
node.getPosition().y + canvas.height / 2,
|
||||
node.getId() + '[' + order + ']'
|
||||
);
|
||||
text.attr('fill', '#FFF');
|
||||
var fillColor = this._rootNodes.contains(node)
|
||||
? '#000'
|
||||
: node.isFree()
|
||||
? '#abc'
|
||||
: '#c00';
|
||||
rect.attr('fill', fillColor);
|
||||
|
||||
/**
|
||||
* @param canvas
|
||||
*/
|
||||
plot:function (canvas) {
|
||||
var branches = this._rootNodes;
|
||||
for (var i = 0; i < branches.length; i++) {
|
||||
var branch = branches[i];
|
||||
this._plot(canvas, branch);
|
||||
}
|
||||
},
|
||||
var rectPosition = {
|
||||
x: rect.attr('x') - canvas.width / 2 + rect.attr('width') / 2,
|
||||
y: rect.attr('y') - canvas.height / 2 + rect.attr('height') / 2,
|
||||
};
|
||||
var rectSize = { width: rect.attr('width'), height: rect.attr('height') };
|
||||
rect.click(function () {
|
||||
console.log(
|
||||
'[id:' +
|
||||
node.getId() +
|
||||
', order:' +
|
||||
node.getOrder() +
|
||||
', position:(' +
|
||||
rectPosition.x +
|
||||
',' +
|
||||
rectPosition.y +
|
||||
'), size:' +
|
||||
rectSize.width +
|
||||
'x' +
|
||||
rectSize.height +
|
||||
', freeDisplacement:(' +
|
||||
node.getFreeDisplacement().x +
|
||||
',' +
|
||||
node.getFreeDisplacement().y +
|
||||
')]'
|
||||
);
|
||||
});
|
||||
text.click(function () {
|
||||
console.log(
|
||||
'[id:' +
|
||||
node.getId() +
|
||||
', order:' +
|
||||
node.getOrder() +
|
||||
', position:(' +
|
||||
rectPosition.x +
|
||||
',' +
|
||||
rectPosition.y +
|
||||
'), size:' +
|
||||
rectSize.width +
|
||||
'x' +
|
||||
rectSize.height +
|
||||
', freeDisplacement:(' +
|
||||
node.getFreeDisplacement().x +
|
||||
',' +
|
||||
node.getFreeDisplacement().y +
|
||||
')]'
|
||||
);
|
||||
});
|
||||
|
||||
_plot:function (canvas, node, root) {
|
||||
var children = this.getChildren(node);
|
||||
var cx = node.getPosition().x + canvas.width / 2 - node.getSize().width / 2;
|
||||
var cy = node.getPosition().y + canvas.height / 2 - node.getSize().height / 2;
|
||||
var rect = canvas.rect(cx, cy, node.getSize().width, node.getSize().height);
|
||||
var order = node.getOrder() == null ? "r" : node.getOrder();
|
||||
var text = canvas.text(node.getPosition().x + canvas.width / 2, node.getPosition().y + canvas.height / 2, node.getId() + "[" + order + "]");
|
||||
text.attr('fill', '#FFF');
|
||||
var fillColor = this._rootNodes.contains(node) ? "#000" : (node.isFree() ? "#abc" : "#c00");
|
||||
rect.attr('fill', fillColor);
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
this._plot(canvas, child);
|
||||
}
|
||||
},
|
||||
|
||||
var rectPosition = {x:rect.attr("x") - canvas.width / 2 + rect.attr("width") / 2, y:rect.attr("y") - canvas.height / 2 + rect.attr("height") / 2};
|
||||
var rectSize = {width:rect.attr("width"), height:rect.attr("height")};
|
||||
rect.click(function () {
|
||||
console.log("[id:" + node.getId() + ", order:" + node.getOrder() + ", position:(" + rectPosition.x + "," + rectPosition.y + "), size:" + rectSize.width + "x" + rectSize.height + ", freeDisplacement:(" + node.getFreeDisplacement().x + "," + node.getFreeDisplacement().y + ")]");
|
||||
});
|
||||
text.click(function () {
|
||||
console.log("[id:" + node.getId() + ", order:" + node.getOrder() + ", position:(" + rectPosition.x + "," + rectPosition.y + "), size:" + rectSize.width + "x" + rectSize.height + ", freeDisplacement:(" + node.getFreeDisplacement().x + "," + node.getFreeDisplacement().y + ")]");
|
||||
});
|
||||
/**
|
||||
* @param node
|
||||
* @param position
|
||||
*/
|
||||
updateBranchPosition: function (node, position) {
|
||||
var oldPos = node.getPosition();
|
||||
node.setPosition(position);
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
this._plot(canvas, child);
|
||||
}
|
||||
},
|
||||
var xOffset = oldPos.x - position.x;
|
||||
var yOffset = oldPos.y - position.y;
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param position
|
||||
*/
|
||||
updateBranchPosition:function (node, position) {
|
||||
var children = this.getChildren(node);
|
||||
var me = this;
|
||||
_.each(children, function (child) {
|
||||
me.shiftBranchPosition(child, xOffset, yOffset);
|
||||
});
|
||||
},
|
||||
|
||||
var oldPos = node.getPosition();
|
||||
node.setPosition(position);
|
||||
/**
|
||||
* @param node
|
||||
* @param xOffset
|
||||
* @param yOffset
|
||||
*/
|
||||
shiftBranchPosition: function (node, xOffset, yOffset) {
|
||||
var position = node.getPosition();
|
||||
node.setPosition({ x: position.x + xOffset, y: position.y + yOffset });
|
||||
|
||||
var xOffset = oldPos.x - position.x;
|
||||
var yOffset = oldPos.y - position.y;
|
||||
var children = this.getChildren(node);
|
||||
var me = this;
|
||||
_.each(children, function (child) {
|
||||
me.shiftBranchPosition(child, xOffset, yOffset);
|
||||
});
|
||||
},
|
||||
|
||||
var children = this.getChildren(node);
|
||||
var me = this;
|
||||
_.each(children, function (child) {
|
||||
me.shiftBranchPosition(child, xOffset, yOffset);
|
||||
});
|
||||
/**
|
||||
* @param node
|
||||
* @param yOffset
|
||||
* @return siblings in the offset (vertical) direction, i.e. with lower or higher order, respectively
|
||||
*/
|
||||
getSiblingsInVerticalDirection: function (node, yOffset) {
|
||||
// siblings with lower or higher order, depending on the direction of the offset and on the same side as their parent
|
||||
var parent = this.getParent(node);
|
||||
var siblings = this.getSiblings(node).filter(function (sibling) {
|
||||
var sameSide =
|
||||
node.getPosition().x > parent.getPosition().x
|
||||
? sibling.getPosition().x > parent.getPosition().x
|
||||
: sibling.getPosition().x < parent.getPosition().x;
|
||||
var orderOK =
|
||||
yOffset < 0
|
||||
? sibling.getOrder() < node.getOrder()
|
||||
: sibling.getOrder() > node.getOrder();
|
||||
return orderOK && sameSide;
|
||||
});
|
||||
|
||||
},
|
||||
if (yOffset < 0) {
|
||||
siblings.reverse();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param xOffset
|
||||
* @param yOffset
|
||||
*/
|
||||
shiftBranchPosition:function (node, xOffset, yOffset) {
|
||||
var position = node.getPosition();
|
||||
node.setPosition({x:position.x + xOffset, y:position.y + yOffset});
|
||||
return siblings;
|
||||
},
|
||||
|
||||
var children = this.getChildren(node);
|
||||
var me = this;
|
||||
_.each(children, function (child) {
|
||||
me.shiftBranchPosition(child, xOffset, yOffset);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @param node
|
||||
* @param yOffset
|
||||
* @return branches of the root node on the same side as the given node's, in the given
|
||||
* vertical direction
|
||||
*/
|
||||
getBranchesInVerticalDirection: function (node, yOffset) {
|
||||
// direct descendants of the root that do not contain the node and are on the same side
|
||||
// and on the direction of the offset
|
||||
var rootNode = this.getRootNode(node);
|
||||
var branches = this.getChildren(rootNode).filter(function (child) {
|
||||
return this._find(node.getId(), child);
|
||||
}, this);
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param yOffset
|
||||
* @return siblings in the offset (vertical) direction, i.e. with lower or higher order, respectively
|
||||
*/
|
||||
getSiblingsInVerticalDirection:function (node, yOffset) {
|
||||
// siblings with lower or higher order, depending on the direction of the offset and on the same side as their parent
|
||||
var parent = this.getParent(node);
|
||||
var siblings = this.getSiblings(node).filter(function (sibling) {
|
||||
var sameSide = node.getPosition().x > parent.getPosition().x ? sibling.getPosition().x > parent.getPosition().x : sibling.getPosition().x < parent.getPosition().x;
|
||||
var orderOK = yOffset < 0 ? sibling.getOrder() < node.getOrder() : sibling.getOrder() > node.getOrder();
|
||||
return orderOK && sameSide;
|
||||
});
|
||||
var branch = branches[0];
|
||||
var rootDescendants = this.getSiblings(branch).filter(function (sibling) {
|
||||
var sameSide =
|
||||
node.getPosition().x > rootNode.getPosition().x
|
||||
? sibling.getPosition().x > rootNode.getPosition().x
|
||||
: sibling.getPosition().x < rootNode.getPosition().x;
|
||||
var sameDirection =
|
||||
yOffset < 0
|
||||
? sibling.getOrder() < branch.getOrder()
|
||||
: sibling.getOrder() > branch.getOrder();
|
||||
return sameSide && sameDirection;
|
||||
}, this);
|
||||
|
||||
if (yOffset < 0) {
|
||||
siblings.reverse();
|
||||
}
|
||||
|
||||
return siblings;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param node
|
||||
* @param yOffset
|
||||
* @return branches of the root node on the same side as the given node's, in the given
|
||||
* vertical direction
|
||||
*/
|
||||
getBranchesInVerticalDirection:function (node, yOffset) {
|
||||
// direct descendants of the root that do not contain the node and are on the same side
|
||||
// and on the direction of the offset
|
||||
var rootNode = this.getRootNode(node);
|
||||
var branches = this.getChildren(rootNode).filter(function (child) {
|
||||
return this._find(node.getId(), child);
|
||||
}, this);
|
||||
|
||||
var branch = branches[0];
|
||||
var rootDescendants = this.getSiblings(branch).filter(function (sibling) {
|
||||
var sameSide = node.getPosition().x > rootNode.getPosition().x ? sibling.getPosition().x > rootNode.getPosition().x : sibling.getPosition().x < rootNode.getPosition().x;
|
||||
var sameDirection = yOffset < 0 ? sibling.getOrder() < branch.getOrder() : sibling.getOrder() > branch.getOrder();
|
||||
return sameSide && sameDirection;
|
||||
}, this);
|
||||
|
||||
return rootDescendants;
|
||||
return rootDescendants;
|
||||
},
|
||||
}
|
||||
|
||||
});
|
||||
);
|
||||
|
||||
export default RootedTreeSet;
|
||||
|
@ -17,255 +17,314 @@
|
||||
*/
|
||||
const AbstractBasicSorter = require('./AbstractBasicSorter').default;
|
||||
|
||||
const SymmetricSorter = new Class(/** @lends SymmetricSorter */{
|
||||
Extends: AbstractBasicSorter,
|
||||
/**
|
||||
* @constructs
|
||||
* @extends mindplot.layout.AbstractBasicSorter
|
||||
*/
|
||||
initialize:function () {
|
||||
const SymmetricSorter = new Class(
|
||||
/** @lends SymmetricSorter */ {
|
||||
Extends: AbstractBasicSorter,
|
||||
/**
|
||||
* @constructs
|
||||
* @extends mindplot.layout.AbstractBasicSorter
|
||||
*/
|
||||
initialize: function () {},
|
||||
|
||||
},
|
||||
/**
|
||||
* Predict the order and position of a dragged node.
|
||||
*
|
||||
* @param graph The tree set
|
||||
* @param parent The parent of the node
|
||||
* @param node The node
|
||||
* @param position The position of the drag
|
||||
* @param free Free drag or not
|
||||
* @return {*}
|
||||
*/
|
||||
predict: function (graph, parent, node, position, free) {
|
||||
var self = this;
|
||||
var rootNode = graph.getRootNode(parent);
|
||||
|
||||
/**
|
||||
* Predict the order and position of a dragged node.
|
||||
*
|
||||
* @param graph The tree set
|
||||
* @param parent The parent of the node
|
||||
* @param node The node
|
||||
* @param position The position of the drag
|
||||
* @param free Free drag or not
|
||||
* @return {*}
|
||||
*/
|
||||
predict:function (graph, parent, node, position, free) {
|
||||
// If its a free node...
|
||||
if (free) {
|
||||
$assert(
|
||||
$defined(position),
|
||||
'position cannot be null for predict in free positioning'
|
||||
);
|
||||
$assert($defined(node), 'node cannot be null for predict in free positioning');
|
||||
|
||||
var self = this;
|
||||
var rootNode = graph.getRootNode(parent);
|
||||
var direction = this._getRelativeDirection(
|
||||
rootNode.getPosition(),
|
||||
parent.getPosition()
|
||||
);
|
||||
var limitXPos =
|
||||
parent.getPosition().x +
|
||||
direction *
|
||||
(parent.getSize().width / 2 +
|
||||
node.getSize().width / 2 +
|
||||
SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
|
||||
// If its a free node...
|
||||
if (free) {
|
||||
$assert($defined(position), "position cannot be null for predict in free positioning");
|
||||
$assert($defined(node), "node cannot be null for predict in free positioning");
|
||||
var xPos =
|
||||
direction > 0
|
||||
? position.x >= limitXPos
|
||||
? position.x
|
||||
: limitXPos
|
||||
: position.x <= limitXPos
|
||||
? position.x
|
||||
: limitXPos;
|
||||
|
||||
var direction = this._getRelativeDirection(rootNode.getPosition(), parent.getPosition());
|
||||
var limitXPos = parent.getPosition().x + direction * (parent.getSize().width / 2 + node.getSize().width / 2 + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
return [0, { x: xPos, y: position.y }];
|
||||
}
|
||||
|
||||
var xPos = direction > 0 ?
|
||||
(position.x >= limitXPos ? position.x : limitXPos) :
|
||||
(position.x <= limitXPos ? position.x : limitXPos);
|
||||
// Its not a dragged node (it is being added)
|
||||
if (!node) {
|
||||
var parentDirection = self._getRelativeDirection(
|
||||
rootNode.getPosition(),
|
||||
parent.getPosition()
|
||||
);
|
||||
|
||||
return [0, {x:xPos, y:position.y}];
|
||||
}
|
||||
var position = {
|
||||
x:
|
||||
parent.getPosition().x +
|
||||
parentDirection *
|
||||
(parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
||||
y: parent.getPosition().y,
|
||||
};
|
||||
return [graph.getChildren(parent).length, position];
|
||||
}
|
||||
|
||||
// Its not a dragged node (it is being added)
|
||||
if (!node) {
|
||||
var parentDirection = self._getRelativeDirection(rootNode.getPosition(), parent.getPosition());
|
||||
var position = {
|
||||
x:parent.getPosition().x + parentDirection * (parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
||||
y:parent.getPosition().y
|
||||
};
|
||||
return [graph.getChildren(parent).length, position];
|
||||
}
|
||||
// If it is a dragged node...
|
||||
$assert($defined(position), 'position cannot be null for predict in dragging');
|
||||
var nodeDirection = this._getRelativeDirection(
|
||||
rootNode.getPosition(),
|
||||
node.getPosition()
|
||||
);
|
||||
var positionDirection = this._getRelativeDirection(rootNode.getPosition(), position);
|
||||
var siblings = graph.getSiblings(node);
|
||||
|
||||
// If it is a dragged node...
|
||||
$assert($defined(position), "position cannot be null for predict in dragging");
|
||||
var nodeDirection = this._getRelativeDirection(rootNode.getPosition(), node.getPosition());
|
||||
var positionDirection = this._getRelativeDirection(rootNode.getPosition(), position);
|
||||
var siblings = graph.getSiblings(node);
|
||||
// node has no siblings and its trying to reconnect to its own parent
|
||||
var sameParent = parent == graph.getParent(node);
|
||||
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
||||
return [node.getOrder(), node.getPosition()];
|
||||
}
|
||||
|
||||
// node has no siblings and its trying to reconnect to its own parent
|
||||
var sameParent = parent == graph.getParent(node);
|
||||
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
||||
return [node.getOrder(), node.getPosition()];
|
||||
}
|
||||
var parentChildren = graph.getChildren(parent);
|
||||
|
||||
var parentChildren = graph.getChildren(parent);
|
||||
if (parentChildren.length == 0) {
|
||||
// Fit as a child of the parent node...
|
||||
var position = {
|
||||
x:
|
||||
parent.getPosition().x +
|
||||
positionDirection *
|
||||
(parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
||||
y: parent.getPosition().y,
|
||||
};
|
||||
return [0, position];
|
||||
} else {
|
||||
// Try to fit within ...
|
||||
var result = null;
|
||||
var last = parentChildren.getLast();
|
||||
for (var i = 0; i < parentChildren.length; i++) {
|
||||
var parentChild = parentChildren[i];
|
||||
var nodeAfter = i + 1 == parentChild.length ? null : parentChildren[i + 1];
|
||||
|
||||
if (parentChildren.length == 0) {
|
||||
// Fit as a child of the parent node...
|
||||
var position = {
|
||||
x:parent.getPosition().x + positionDirection * (parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
||||
y:parent.getPosition().y
|
||||
};
|
||||
return [0, position];
|
||||
} else {
|
||||
// Try to fit within ...
|
||||
var result = null;
|
||||
var last = parentChildren.getLast();
|
||||
for (var i = 0; i < parentChildren.length; i++) {
|
||||
var parentChild = parentChildren[i];
|
||||
var nodeAfter = (i + 1) == parentChild.length ? null : parentChildren[i + 1];
|
||||
|
||||
// Fit at the bottom
|
||||
if (!nodeAfter && position.y > parentChild.getPosition().y) {
|
||||
var order = (graph.getParent(node) && graph.getParent(node).getId() == parent.getId()) ?
|
||||
last.getOrder() : last.getOrder() + 1;
|
||||
var position = {
|
||||
x:parentChild.getPosition().x,
|
||||
y:parentChild.getPosition().y + parentChild.getSize().height + SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2
|
||||
};
|
||||
return [order, position];
|
||||
}
|
||||
|
||||
// Fit after this node
|
||||
if (nodeAfter && position.y > parentChild.getPosition().y && position.y < nodeAfter.getPosition().y) {
|
||||
if (nodeAfter.getId() == node.getId() || parentChild.getId() == node.getId()) {
|
||||
return [node.getOrder(), node.getPosition()];
|
||||
} else {
|
||||
var order = position.y > node.getPosition().y ?
|
||||
nodeAfter.getOrder() - 1 : parentChild.getOrder() + 1;
|
||||
// Fit at the bottom
|
||||
if (!nodeAfter && position.y > parentChild.getPosition().y) {
|
||||
var order =
|
||||
graph.getParent(node) && graph.getParent(node).getId() == parent.getId()
|
||||
? last.getOrder()
|
||||
: last.getOrder() + 1;
|
||||
var position = {
|
||||
x:parentChild.getPosition().x,
|
||||
y:parentChild.getPosition().y + (nodeAfter.getPosition().y - parentChild.getPosition().y) / 2
|
||||
x: parentChild.getPosition().x,
|
||||
y:
|
||||
parentChild.getPosition().y +
|
||||
parentChild.getSize().height +
|
||||
SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2,
|
||||
};
|
||||
|
||||
return [order, position];
|
||||
}
|
||||
|
||||
// Fit after this node
|
||||
if (
|
||||
nodeAfter &&
|
||||
position.y > parentChild.getPosition().y &&
|
||||
position.y < nodeAfter.getPosition().y
|
||||
) {
|
||||
if (
|
||||
nodeAfter.getId() == node.getId() ||
|
||||
parentChild.getId() == node.getId()
|
||||
) {
|
||||
return [node.getOrder(), node.getPosition()];
|
||||
} else {
|
||||
var order =
|
||||
position.y > node.getPosition().y
|
||||
? nodeAfter.getOrder() - 1
|
||||
: parentChild.getOrder() + 1;
|
||||
var position = {
|
||||
x: parentChild.getPosition().x,
|
||||
y:
|
||||
parentChild.getPosition().y +
|
||||
(nodeAfter.getPosition().y - parentChild.getPosition().y) / 2,
|
||||
};
|
||||
return [order, position];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Position wasn't below any node, so it must be fitted above the first
|
||||
var first = parentChildren[0];
|
||||
var position = {
|
||||
x:first.getPosition().x,
|
||||
y:first.getPosition().y - first.getSize().height - SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2
|
||||
};
|
||||
return [0, position];
|
||||
},
|
||||
// Position wasn't below any node, so it must be fitted above the first
|
||||
var first = parentChildren[0];
|
||||
var position = {
|
||||
x: first.getPosition().x,
|
||||
y:
|
||||
first.getPosition().y -
|
||||
first.getSize().height -
|
||||
SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2,
|
||||
};
|
||||
return [0, position];
|
||||
},
|
||||
|
||||
/**
|
||||
* @param treeSet
|
||||
* @param parent
|
||||
* @param child
|
||||
* @param order
|
||||
* @throws will throw an error if the order is not strictly continuous
|
||||
*/
|
||||
insert:function (treeSet, parent, child, order) {
|
||||
var children = this._getSortedChildren(treeSet, parent);
|
||||
$assert(order <= children.length, "Order must be continues and can not have holes. Order:" + order);
|
||||
/**
|
||||
* @param treeSet
|
||||
* @param parent
|
||||
* @param child
|
||||
* @param order
|
||||
* @throws will throw an error if the order is not strictly continuous
|
||||
*/
|
||||
insert: function (treeSet, parent, child, order) {
|
||||
var children = this._getSortedChildren(treeSet, parent);
|
||||
$assert(
|
||||
order <= children.length,
|
||||
'Order must be continues and can not have holes. Order:' + order
|
||||
);
|
||||
|
||||
// Shift all the elements in one .
|
||||
for (var i = order; i < children.length; i++) {
|
||||
var node = children[i];
|
||||
node.setOrder(i + 1);
|
||||
}
|
||||
child.setOrder(order);
|
||||
},
|
||||
// Shift all the elements in one .
|
||||
for (var i = order; i < children.length; i++) {
|
||||
var node = children[i];
|
||||
node.setOrder(i + 1);
|
||||
}
|
||||
child.setOrder(order);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param treeSet
|
||||
* @param node
|
||||
* @throws will throw an error if the node is in the wrong position*/
|
||||
detach:function (treeSet, node) {
|
||||
var parent = treeSet.getParent(node);
|
||||
var children = this._getSortedChildren(treeSet, parent);
|
||||
var order = node.getOrder();
|
||||
$assert(children[order] === node, "Node seems not to be in the right position");
|
||||
/**
|
||||
* @param treeSet
|
||||
* @param node
|
||||
* @throws will throw an error if the node is in the wrong position*/
|
||||
detach: function (treeSet, node) {
|
||||
var parent = treeSet.getParent(node);
|
||||
var children = this._getSortedChildren(treeSet, parent);
|
||||
var order = node.getOrder();
|
||||
$assert(children[order] === node, 'Node seems not to be in the right position');
|
||||
|
||||
// Shift all the nodes ...
|
||||
for (var i = node.getOrder() + 1; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
child.setOrder(child.getOrder() - 1);
|
||||
}
|
||||
node.setOrder(0);
|
||||
},
|
||||
// Shift all the nodes ...
|
||||
for (var i = node.getOrder() + 1; i < children.length; i++) {
|
||||
var child = children[i];
|
||||
child.setOrder(child.getOrder() - 1);
|
||||
}
|
||||
node.setOrder(0);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param treeSet
|
||||
* @param node
|
||||
* @throws will throw an error if treeSet is null or undefined
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @throws will throw an error if the calculated x offset cannot be converted to a numeric
|
||||
* value, is null or undefined
|
||||
* @throws will throw an error if the calculated y offset cannot be converted to a numeric
|
||||
* value, is null or undefined
|
||||
* @return offsets
|
||||
*/
|
||||
computeOffsets:function (treeSet, node) {
|
||||
$assert(treeSet, "treeSet can no be null.");
|
||||
$assert(node, "node can no be null.");
|
||||
/**
|
||||
* @param treeSet
|
||||
* @param node
|
||||
* @throws will throw an error if treeSet is null or undefined
|
||||
* @throws will throw an error if node is null or undefined
|
||||
* @throws will throw an error if the calculated x offset cannot be converted to a numeric
|
||||
* value, is null or undefined
|
||||
* @throws will throw an error if the calculated y offset cannot be converted to a numeric
|
||||
* value, is null or undefined
|
||||
* @return offsets
|
||||
*/
|
||||
computeOffsets: function (treeSet, node) {
|
||||
$assert(treeSet, 'treeSet can no be null.');
|
||||
$assert(node, 'node can no be null.');
|
||||
|
||||
var children = this._getSortedChildren(treeSet, node);
|
||||
var children = this._getSortedChildren(treeSet, node);
|
||||
|
||||
// Compute heights ...
|
||||
var heights = children.map(
|
||||
function (child) {
|
||||
return {id:child.getId(), order:child.getOrder(), position:child.getPosition(), width:child.getSize().width, height:this._computeChildrenHeight(treeSet, child)};
|
||||
}, this).reverse();
|
||||
// Compute heights ...
|
||||
var heights = children
|
||||
.map(function (child) {
|
||||
return {
|
||||
id: child.getId(),
|
||||
order: child.getOrder(),
|
||||
position: child.getPosition(),
|
||||
width: child.getSize().width,
|
||||
height: this._computeChildrenHeight(treeSet, child),
|
||||
};
|
||||
}, this)
|
||||
.reverse();
|
||||
|
||||
// Compute the center of the branch ...
|
||||
var totalHeight = 0;
|
||||
_.each(heights, function (elem) {
|
||||
totalHeight += elem.height;
|
||||
});
|
||||
var ysum = totalHeight / 2;
|
||||
// Compute the center of the branch ...
|
||||
var totalHeight = 0;
|
||||
_.each(heights, function (elem) {
|
||||
totalHeight += elem.height;
|
||||
});
|
||||
var ysum = totalHeight / 2;
|
||||
|
||||
// Calculate the offsets ...
|
||||
var result = {};
|
||||
for (var i = 0; i < heights.length; i++) {
|
||||
ysum = ysum - heights[i].height;
|
||||
var childNode = treeSet.find(heights[i].id);
|
||||
var direction = this.getChildDirection(treeSet, childNode);
|
||||
// Calculate the offsets ...
|
||||
var result = {};
|
||||
for (var i = 0; i < heights.length; i++) {
|
||||
ysum = ysum - heights[i].height;
|
||||
var childNode = treeSet.find(heights[i].id);
|
||||
var direction = this.getChildDirection(treeSet, childNode);
|
||||
|
||||
var yOffset = ysum + heights[i].height / 2;
|
||||
var xOffset = direction * (heights[i].width / 2 + node.getSize().width / 2 + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
var yOffset = ysum + heights[i].height / 2;
|
||||
var xOffset =
|
||||
direction *
|
||||
(heights[i].width / 2 +
|
||||
node.getSize().width / 2 +
|
||||
SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||
|
||||
$assert(!isNaN(xOffset), "xOffset can not be null");
|
||||
$assert(!isNaN(yOffset), "yOffset can not be null");
|
||||
$assert(!isNaN(xOffset), 'xOffset can not be null');
|
||||
$assert(!isNaN(yOffset), 'yOffset can not be null');
|
||||
|
||||
result[heights[i].id] = {x:xOffset, y:yOffset};
|
||||
}
|
||||
return result;
|
||||
},
|
||||
result[heights[i].id] = { x: xOffset, y: yOffset };
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param treeSet
|
||||
* @param node
|
||||
* @throws will throw an error if order elements are missing
|
||||
*/
|
||||
verify:function (treeSet, node) {
|
||||
// Check that all is consistent ...
|
||||
var children = this._getSortedChildren(treeSet, node);
|
||||
/**
|
||||
* @param treeSet
|
||||
* @param node
|
||||
* @throws will throw an error if order elements are missing
|
||||
*/
|
||||
verify: function (treeSet, node) {
|
||||
// Check that all is consistent ...
|
||||
var children = this._getSortedChildren(treeSet, node);
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
$assert(children[i].getOrder() == i, "missing order elements");
|
||||
}
|
||||
},
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
$assert(children[i].getOrder() == i, 'missing order elements');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @param treeSet
|
||||
* @param child
|
||||
* @return direction of the given child from its parent or from the root node, if isolated*/
|
||||
getChildDirection:function (treeSet, child) {
|
||||
$assert(treeSet, "treeSet can no be null.");
|
||||
$assert(treeSet.getParent(child), "This should not happen");
|
||||
/**
|
||||
* @param treeSet
|
||||
* @param child
|
||||
* @return direction of the given child from its parent or from the root node, if isolated*/
|
||||
getChildDirection: function (treeSet, child) {
|
||||
$assert(treeSet, 'treeSet can no be null.');
|
||||
$assert(treeSet.getParent(child), 'This should not happen');
|
||||
|
||||
var result;
|
||||
var rootNode = treeSet.getRootNode(child);
|
||||
if (treeSet.getParent(child) == rootNode) {
|
||||
// This is the case of a isolated child ... In this case, the directions is based on the root.
|
||||
result = Math.sign(rootNode.getPosition().x);
|
||||
} else {
|
||||
// if this is not the case, honor the direction of the parent ...
|
||||
var parent = treeSet.getParent(child);
|
||||
var grandParent = treeSet.getParent(parent);
|
||||
var sorter = grandParent.getSorter();
|
||||
result = sorter.getChildDirection(treeSet, parent);
|
||||
var result;
|
||||
var rootNode = treeSet.getRootNode(child);
|
||||
if (treeSet.getParent(child) == rootNode) {
|
||||
// This is the case of a isolated child ... In this case, the directions is based on the root.
|
||||
result = Math.sign(rootNode.getPosition().x);
|
||||
} else {
|
||||
// if this is not the case, honor the direction of the parent ...
|
||||
var parent = treeSet.getParent(child);
|
||||
var grandParent = treeSet.getParent(parent);
|
||||
var sorter = grandParent.getSorter();
|
||||
result = sorter.getChildDirection(treeSet, parent);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
}
|
||||
return result;
|
||||
},
|
||||
/** @return {String} the print name of this class */
|
||||
toString: function () {
|
||||
return 'Symmetric Sorter';
|
||||
},
|
||||
|
||||
/** @return {String} the print name of this class */
|
||||
toString:function () {
|
||||
return "Symmetric Sorter";
|
||||
},
|
||||
|
||||
_getVerticalPadding:function () {
|
||||
return SymmetricSorter.INTERNODE_VERTICAL_PADDING;
|
||||
_getVerticalPadding: function () {
|
||||
return SymmetricSorter.INTERNODE_VERTICAL_PADDING;
|
||||
},
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
/**
|
||||
* @constant
|
||||
@ -280,4 +339,4 @@ SymmetricSorter.INTERNODE_VERTICAL_PADDING = 5;
|
||||
*/
|
||||
SymmetricSorter.INTERNODE_HORIZONTAL_PADDING = 30;
|
||||
|
||||
export default SymmetricSorter
|
||||
export default SymmetricSorter;
|
||||
|
76
packages/mindplot/lib/components/libraries/mootools/mootools-core-1.4.5.js
vendored
Normal file
76
packages/mindplot/lib/components/libraries/mootools/mootools-core-1.4.5.js
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
---
|
||||
MooTools: the javascript framework
|
||||
|
||||
web build:
|
||||
- http://mootools.net/core/b28139f033891d55fabb70ffafd6813b
|
||||
|
||||
packager build:
|
||||
- packager build Core/Core Core/Array Core/Class Core/Class.Extras
|
||||
|
||||
copyrights:
|
||||
- [MooTools](http://mootools.net)
|
||||
|
||||
licenses:
|
||||
- [MIT License](http://mootools.net/license.txt)
|
||||
...
|
||||
*/
|
||||
|
||||
(function(){this.MooTools={version:"1.4.5",build:"ab8ea8824dc3b24b6666867a2c4ed58ebb762cf0"};var o=this.typeOf=function(i){if(i==null){return"null";}if(i.$family!=null){return i.$family();
|
||||
}if(i.nodeName){if(i.nodeType==1){return"element";}if(i.nodeType==3){return(/\S/).test(i.nodeValue)?"textnode":"whitespace";}}else{if(typeof i.length=="number"){if(i.callee){return"arguments";
|
||||
}if("item" in i){return"collection";}}}return typeof i;};var j=this.instanceOf=function(t,i){if(t==null){return false;}var s=t.$constructor||t.constructor;
|
||||
while(s){if(s===i){return true;}s=s.parent;}if(!t.hasOwnProperty){return false;}return t instanceof i;};var f=this.Function;var p=true;for(var k in {toString:1}){p=null;
|
||||
}if(p){p=["hasOwnProperty","valueOf","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","constructor"];}f.prototype.overloadSetter=function(s){var i=this;
|
||||
return function(u,t){if(u==null){return this;}if(s||typeof u!="string"){for(var v in u){i.call(this,v,u[v]);}if(p){for(var w=p.length;w--;){v=p[w];if(u.hasOwnProperty(v)){i.call(this,v,u[v]);
|
||||
}}}}else{i.call(this,u,t);}return this;};};f.prototype.overloadGetter=function(s){var i=this;return function(u){var v,t;if(typeof u!="string"){v=u;}else{if(arguments.length>1){v=arguments;
|
||||
}else{if(s){v=[u];}}}if(v){t={};for(var w=0;w<v.length;w++){t[v[w]]=i.call(this,v[w]);}}else{t=i.call(this,u);}return t;};};f.prototype.extend=function(i,s){this[i]=s;
|
||||
}.overloadSetter();f.prototype.implement=function(i,s){this.prototype[i]=s;}.overloadSetter();var n=Array.prototype.slice;f.from=function(i){return(o(i)=="function")?i:function(){return i;
|
||||
};};Array.from=function(i){if(i==null){return[];}return(a.isEnumerable(i)&&typeof i!="string")?(o(i)=="array")?i:n.call(i):[i];};Number.from=function(s){var i=parseFloat(s);
|
||||
return isFinite(i)?i:null;};String.from=function(i){return i+"";};f.implement({hide:function(){this.$hidden=true;return this;},protect:function(){this.$protected=true;
|
||||
return this;}});var a=this.Type=function(u,t){if(u){var s=u.toLowerCase();var i=function(v){return(o(v)==s);};a["is"+u]=i;if(t!=null){t.prototype.$family=(function(){return s;
|
||||
}).hide();}}if(t==null){return null;}t.extend(this);t.$constructor=a;t.prototype.$constructor=t;return t;};var e=Object.prototype.toString;a.isEnumerable=function(i){return(i!=null&&typeof i.length=="number"&&e.call(i)!="[object Function]");
|
||||
};var q={};var r=function(i){var s=o(i.prototype);return q[s]||(q[s]=[]);};var b=function(t,x){if(x&&x.$hidden){return;}var s=r(this);for(var u=0;u<s.length;
|
||||
u++){var w=s[u];if(o(w)=="type"){b.call(w,t,x);}else{w.call(this,t,x);}}var v=this.prototype[t];if(v==null||!v.$protected){this.prototype[t]=x;}if(this[t]==null&&o(x)=="function"){m.call(this,t,function(i){return x.apply(i,n.call(arguments,1));
|
||||
});}};var m=function(i,t){if(t&&t.$hidden){return;}var s=this[i];if(s==null||!s.$protected){this[i]=t;}};a.implement({implement:b.overloadSetter(),extend:m.overloadSetter(),alias:function(i,s){b.call(this,i,this.prototype[s]);
|
||||
}.overloadSetter(),mirror:function(i){r(this).push(i);return this;}});new a("Type",a);var d=function(s,x,v){var u=(x!=Object),B=x.prototype;if(u){x=new a(s,x);
|
||||
}for(var y=0,w=v.length;y<w;y++){var C=v[y],A=x[C],z=B[C];if(A){A.protect();}if(u&&z){x.implement(C,z.protect());}}if(u){var t=B.propertyIsEnumerable(v[0]);
|
||||
x.forEachMethod=function(G){if(!t){for(var F=0,D=v.length;F<D;F++){G.call(B,B[v[F]],v[F]);}}for(var E in B){G.call(B,B[E],E);}};}return d;};d("String",String,["charAt","charCodeAt","concat","indexOf","lastIndexOf","match","quote","replace","search","slice","split","substr","substring","trim","toLowerCase","toUpperCase"])("Array",Array,["pop","push","reverse","shift","sort","splice","unshift","concat","join","slice","indexOf","lastIndexOf","filter","forEach","every","map","some","reduce","reduceRight"])("Number",Number,["toExponential","toFixed","toLocaleString","toPrecision"])("Function",f,["apply","call","bind"])("RegExp",RegExp,["exec","test"])("Object",Object,["create","defineProperty","defineProperties","keys","getPrototypeOf","getOwnPropertyDescriptor","getOwnPropertyNames","preventExtensions","isExtensible","seal","isSealed","freeze","isFrozen"])("Date",Date,["now"]);
|
||||
Object.extend=m.overloadSetter();Date.extend("now",function(){return +(new Date);});new a("Boolean",Boolean);Number.prototype.$family=function(){return isFinite(this)?"number":"null";
|
||||
}.hide();Number.extend("random",function(s,i){return Math.floor(Math.random()*(i-s+1)+s);});var g=Object.prototype.hasOwnProperty;Object.extend("forEach",function(i,t,u){for(var s in i){if(g.call(i,s)){t.call(u,i[s],s,i);
|
||||
}}});Object.each=Object.forEach;Array.implement({forEach:function(u,v){for(var t=0,s=this.length;t<s;t++){if(t in this){u.call(v,this[t],t,this);}}},each:function(i,s){Array.forEach(this,i,s);
|
||||
return this;}});var l=function(i){switch(o(i)){case"array":return i.clone();case"object":return Object.clone(i);default:return i;}};Array.implement("clone",function(){var s=this.length,t=new Array(s);
|
||||
while(s--){t[s]=l(this[s]);}return t;});var h=function(s,i,t){switch(o(t)){case"object":if(o(s[i])=="object"){Object.merge(s[i],t);}else{s[i]=Object.clone(t);
|
||||
}break;case"array":s[i]=t.clone();break;default:s[i]=t;}return s;};Object.extend({merge:function(z,u,t){if(o(u)=="string"){return h(z,u,t);}for(var y=1,s=arguments.length;
|
||||
y<s;y++){var w=arguments[y];for(var x in w){h(z,x,w[x]);}}return z;},clone:function(i){var t={};for(var s in i){t[s]=l(i[s]);}return t;},append:function(w){for(var v=1,t=arguments.length;
|
||||
v<t;v++){var s=arguments[v]||{};for(var u in s){w[u]=s[u];}}return w;}});["Object","WhiteSpace","TextNode","Collection","Arguments"].each(function(i){new a(i);
|
||||
});var c=Date.now();String.extend("uniqueID",function(){return(c++).toString(36);});})();Array.implement({every:function(c,d){for(var b=0,a=this.length>>>0;
|
||||
b<a;b++){if((b in this)&&!c.call(d,this[b],b,this)){return false;}}return true;},filter:function(d,f){var c=[];for(var e,b=0,a=this.length>>>0;b<a;b++){if(b in this){e=this[b];
|
||||
if(d.call(f,e,b,this)){c.push(e);}}}return c;},indexOf:function(c,d){var b=this.length>>>0;for(var a=(d<0)?Math.max(0,b+d):d||0;a<b;a++){if(this[a]===c){return a;
|
||||
}}return -1;},map:function(c,e){var d=this.length>>>0,b=Array(d);for(var a=0;a<d;a++){if(a in this){b[a]=c.call(e,this[a],a,this);}}return b;},some:function(c,d){for(var b=0,a=this.length>>>0;
|
||||
b<a;b++){if((b in this)&&c.call(d,this[b],b,this)){return true;}}return false;},clean:function(){return this.filter(function(a){return a!=null;});},invoke:function(a){var b=Array.slice(arguments,1);
|
||||
return this.map(function(c){return c[a].apply(c,b);});},associate:function(c){var d={},b=Math.min(this.length,c.length);for(var a=0;a<b;a++){d[c[a]]=this[a];
|
||||
}return d;},link:function(c){var a={};for(var e=0,b=this.length;e<b;e++){for(var d in c){if(c[d](this[e])){a[d]=this[e];delete c[d];break;}}}return a;},contains:function(a,b){return this.indexOf(a,b)!=-1;
|
||||
},append:function(a){this.push.apply(this,a);return this;},getLast:function(){return(this.length)?this[this.length-1]:null;},getRandom:function(){return(this.length)?this[Number.random(0,this.length-1)]:null;
|
||||
},include:function(a){if(!this.contains(a)){this.push(a);}return this;},combine:function(c){for(var b=0,a=c.length;b<a;b++){this.include(c[b]);}return this;
|
||||
},erase:function(b){for(var a=this.length;a--;){if(this[a]===b){this.splice(a,1);}}return this;},empty:function(){this.length=0;return this;},flatten:function(){var d=[];
|
||||
for(var b=0,a=this.length;b<a;b++){var c=typeOf(this[b]);if(c=="null"){continue;}d=d.concat((c=="array"||c=="collection"||c=="arguments"||instanceOf(this[b],Array))?Array.flatten(this[b]):this[b]);
|
||||
}return d;},pick:function(){for(var b=0,a=this.length;b<a;b++){if(this[b]!=null){return this[b];}}return null;},rgbToHex:function(d){if(this.length<3){return null;}if(this.length==4&&this[3]==0&&!d){return"transparent";
|
||||
}var b=[];for(var a=0;a<3;a++){var c=(this[a]-0).toString(16);b.push((c.length==1)?"0"+c:c);}return(d)?b:"#"+b.join("");}});String.implement({test:function(a,b){return((typeOf(a)=="regexp")?a:new RegExp(""+a,b)).test(this);
|
||||
},contains:function(a,b){return(b)?(b+this+b).indexOf(b+a+b)>-1:String(this).indexOf(a)>-1;},trim:function(){return String(this).replace(/^\s+|\s+$/g,"");
|
||||
},clean:function(){return String(this).replace(/\s+/g," ").trim();},camelCase:function(){return String(this).replace(/-\D/g,function(a){return a.charAt(1).toUpperCase();
|
||||
});},hyphenate:function(){return String(this).replace(/[A-Z]/g,function(a){return("-"+a.charAt(0).toLowerCase());});},capitalize:function(){return String(this).replace(/\b[a-z]/g,function(a){return a.toUpperCase();
|
||||
});},escapeRegExp:function(){return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1");},rgbToHex:function(b){var a=String(this).match(/\d{1,3}/g);
|
||||
return(a)?a.rgbToHex(b):null;},substitute:function(a,b){return String(this).replace(b||(/\\?\{([^{}]+)\}/g),function(d,c){if(d.charAt(0)=="\\"){return d.slice(1);
|
||||
}return(a[c]!=null)?a[c]:"";});}});
|
||||
Function.implement({bind:function(e){var a=this,b=arguments.length>1?Array.slice(arguments,1):null,d=function(){};var c=function(){var g=e,h=arguments.length;if(this instanceof c){d.prototype=a.prototype;g=new d;}var f=(!b&&!h)?a.call(g):a.apply(g,b&&h?b.concat(Array.slice(arguments)):b||arguments);return g==e?f:g;};return c;},pass:function(b,c){var a=this;if(b!=null){b=Array.from(b);}return function(){return a.apply(c,b||arguments);};},delay:function(b,c,a){return setTimeout(this.pass((a==null?[]:a),c),b);},});
|
||||
Number.alias("each","times");(function(b){var a={};b.each(function(c){if(!Number[c]){a[c]=function(){return Math[c].apply(null,[this].concat(Array.from(arguments)));
|
||||
};}});Number.implement(a);})(["abs","acos","asin","atan","atan2","ceil","cos","exp","floor","log","max","min","pow","sin","sqrt","tan"]);(function(){var a=this.Class=new Type("Class",function(h){if(instanceOf(h,Function)){h={initialize:h};
|
||||
}var g=function(){e(this);if(g.$prototyping){return this;}this.$caller=null;var i=(this.initialize)?this.initialize.apply(this,arguments):this;this.$caller=this.caller=null;
|
||||
return i;}.extend(this).implement(h);g.$constructor=a;g.prototype.$constructor=g;g.prototype.parent=c;return g;});var c=function(){if(!this.$caller){throw new Error('The method "parent" cannot be called.');
|
||||
}var g=this.$caller.$name,h=this.$caller.$owner.parent,i=(h)?h.prototype[g]:null;if(!i){throw new Error('The method "'+g+'" has no parent.');}return i.apply(this,arguments);
|
||||
};var e=function(g){for(var h in g){var j=g[h];switch(typeOf(j)){case"object":var i=function(){};i.prototype=j;g[h]=e(new i);break;case"array":g[h]=j.clone();
|
||||
break;}}return g;};var b=function(g,h,j){if(j.$origin){j=j.$origin;}var i=function(){if(j.$protected&&this.$caller==null){throw new Error('The method "'+h+'" cannot be called.');
|
||||
}var l=this.caller,m=this.$caller;this.caller=m;this.$caller=i;var k=j.apply(this,arguments);this.$caller=m;this.caller=l;return k;}.extend({$owner:g,$origin:j,$name:h});
|
||||
return i;};var f=function(h,i,g){if(a.Mutators.hasOwnProperty(h)){i=a.Mutators[h].call(this,i);if(i==null){return this;}}if(typeOf(i)=="function"){if(i.$hidden){return this;
|
||||
}this.prototype[h]=(g)?i:b(this,h,i);}else{Object.merge(this.prototype,h,i);}return this;};var d=function(g){g.$prototyping=true;var h=new g;delete g.$prototyping;
|
||||
return h;};a.implement("implement",f.overloadSetter());a.Mutators={Extends:function(g){this.parent=g;this.prototype=d(g);},Implements:function(g){Array.from(g).each(function(j){var h=new j;for(var i in h){f.call(this,i,h[i],true);}},this);}};})();
|
6382
packages/mindplot/lib/components/libraries/mootools/mootools-core-1.6.0.js
vendored
Normal file
6382
packages/mindplot/lib/components/libraries/mootools/mootools-core-1.6.0.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -421,5 +421,5 @@ INodeModel._nextUUID = function () {
|
||||
};
|
||||
INodeModel._uuid = 0;
|
||||
|
||||
export default INodeModel;
|
||||
export { TopicShape };
|
||||
export default INodeModel;
|
||||
|
@ -1,21 +1,21 @@
|
||||
const featureModel = require('./FeatureModel').default;
|
||||
const iconModel = require('./IconModel').default;
|
||||
const imindmap = require('./IMindmap').default;
|
||||
const inodeModel = require('./INodeModel').default;
|
||||
const iMindmap = require('./IMindmap').default;
|
||||
const iNodeModel = require('./INodeModel').default;
|
||||
const linkModel = require('./LinkModel').default;
|
||||
const noteModel = require('./NoteModel').default;
|
||||
const mindmap = require('./Mindmap').default;
|
||||
const nodeModel = require('./NodeModel').default;
|
||||
const noteModel = require('./NoteModel').default;
|
||||
const relationshipModel = require('./RelationshipModel').default;
|
||||
|
||||
export const Models = {
|
||||
export const Model = {
|
||||
FeatureModel: featureModel,
|
||||
IconModel: iconModel,
|
||||
IMindmap: imindmap,
|
||||
INodeModel: inodeModel,
|
||||
IMindmap: iMindmap,
|
||||
INodeModel: iNodeModel,
|
||||
LinkModel: linkModel,
|
||||
NoteModel: noteModel,
|
||||
Mindmap: mindmap,
|
||||
NodeModel: nodeModel,
|
||||
NoteModel: noteModel,
|
||||
RelationshipModel: relationshipModel,
|
||||
};
|
||||
|
7
packages/mindplot/lib/components/util/index.js
Normal file
7
packages/mindplot/lib/components/util/index.js
Normal file
@ -0,0 +1,7 @@
|
||||
const fadeEffect = require('./FadeEffect').default;
|
||||
const shape = require('./Shape').default;
|
||||
|
||||
export const Utils = {
|
||||
FadeEffect: fadeEffect,
|
||||
Shape: shape,
|
||||
};
|
@ -18,47 +18,46 @@
|
||||
const ToolbarPaneItem = require('./ToolbarPaneItem').default;
|
||||
|
||||
const ColorPalettePanel = new Class({
|
||||
Extends:ToolbarPaneItem,
|
||||
Extends: ToolbarPaneItem,
|
||||
|
||||
initialize:function (buttonId, model, baseUrl) {
|
||||
initialize: function (buttonId, model, baseUrl) {
|
||||
this._baseUrl = baseUrl;
|
||||
this.parent(buttonId, model);
|
||||
$assert($defined(baseUrl), "baseUrl can not be null");
|
||||
$assert($defined(baseUrl), 'baseUrl can not be null');
|
||||
},
|
||||
|
||||
_load:function () {
|
||||
|
||||
_load: function () {
|
||||
if (!ColorPalettePanel._panelContent) {
|
||||
|
||||
// Load all the CSS styles ...
|
||||
$('<link>')
|
||||
.appendTo($('head'))
|
||||
.attr({type : 'text/css', rel : 'stylesheet'})
|
||||
.attr({ type: 'text/css', rel: 'stylesheet' })
|
||||
.attr('href', this._baseUrl + '/colorPalette.css');
|
||||
|
||||
// Load panel html fragment ...
|
||||
var result;
|
||||
$.ajax({
|
||||
url:this._baseUrl + '/colorPalette.html',
|
||||
method:'get',
|
||||
async:false,
|
||||
success:function (responseText) {
|
||||
url: `${this._baseUrl}/colorPalette.html`,
|
||||
method: 'GET',
|
||||
async: false,
|
||||
success: function (responseText) {
|
||||
result = responseText;
|
||||
},
|
||||
error:function () {
|
||||
error: function () {
|
||||
result = '<div>Sorry, your request failed :(</div>';
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
ColorPalettePanel._panelContent = result;
|
||||
|
||||
}
|
||||
return ColorPalettePanel._panelContent;
|
||||
},
|
||||
|
||||
|
||||
buildPanel:function () {
|
||||
var content = $('<div class="toolbarPanel"></div>').attr('id', this._buttonId + 'colorPalette');
|
||||
buildPanel: function () {
|
||||
var content = $('<div class="toolbarPanel"></div>').attr(
|
||||
'id',
|
||||
this._buttonId + 'colorPalette'
|
||||
);
|
||||
content.html(this._load());
|
||||
|
||||
// Register on toolbar elements ...
|
||||
@ -67,7 +66,7 @@ const ColorPalettePanel = new Class({
|
||||
var me = this;
|
||||
_.each(colorCells, function (elem) {
|
||||
$(elem).on('click', function () {
|
||||
var color = $(elem).css("background-color");
|
||||
var color = $(elem).css('background-color');
|
||||
model.setValue(color);
|
||||
me.hide();
|
||||
});
|
||||
@ -76,18 +75,20 @@ const ColorPalettePanel = new Class({
|
||||
return content;
|
||||
},
|
||||
|
||||
_updateSelectedItem:function () {
|
||||
_updateSelectedItem: function () {
|
||||
var panelElem = this.getPanelElem();
|
||||
|
||||
// Clear selected cell based on the color ...
|
||||
panelElem.find("td[class='palette-cell palette-cell-selected']").attr('class', 'palette-cell');
|
||||
panelElem
|
||||
.find("td[class='palette-cell palette-cell-selected']")
|
||||
.attr('class', 'palette-cell');
|
||||
|
||||
// Mark the cell as selected ...
|
||||
var colorCells = panelElem.find('div[class=palette-colorswatch]');
|
||||
var model = this.getModel();
|
||||
var modelValue = model.getValue();
|
||||
_.each(colorCells, function (elem) {
|
||||
var color = $(elem).css("background-color").rgbToHex();
|
||||
var color = $(elem).css('background-color').rgbToHex();
|
||||
if (modelValue != null && modelValue[0] == 'r') {
|
||||
modelValue = modelValue.rgbToHex();
|
||||
}
|
||||
@ -97,8 +98,7 @@ const ColorPalettePanel = new Class({
|
||||
}
|
||||
});
|
||||
return panelElem;
|
||||
}
|
||||
|
||||
},
|
||||
});
|
||||
|
||||
export default ColorPalettePanel;
|
||||
|
@ -6,7 +6,6 @@
|
||||
* "powered by wisemapping" text requirement on every single page;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the license at
|
||||
*
|
||||
* http://www.wisemapping.org/license
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
@ -50,5 +49,7 @@ const ModalDialogNotifier = new Class({
|
||||
|
||||
var dialogNotifier = new ModalDialogNotifier();
|
||||
const $notifyModal = dialogNotifier.show.bind(dialogNotifier);
|
||||
$notifyModal;
|
||||
|
||||
export { $notifyModal };
|
||||
export default ModalDialogNotifier;
|
||||
|
@ -46,4 +46,5 @@ const $notify = function (msg) {
|
||||
toolbarNotifier.logMessage(msg);
|
||||
};
|
||||
|
||||
export { $notify };
|
||||
export default ToolbarNotifier;
|
||||
|
@ -3,7 +3,7 @@ const floatingTip = require('./FloatingTip').default;
|
||||
const fontFamilyPanel = require('./FontFamilyPanel').default;
|
||||
const fontSizePanel = require('./FontSizePanel').default;
|
||||
const iconPanel = require('./IconPanel').default;
|
||||
const imenu = require('./IMenu').default;
|
||||
const iMenu = require('./IMenu').default;
|
||||
const keyboardShortcutTooltip = require('./KeyboardShortcutTooltip').default;
|
||||
const linkEditor = require('./LinkEditor').default;
|
||||
const linkIconTooltip = require('./LinkIconTooltip').default;
|
||||
@ -22,7 +22,7 @@ export const Widgets = {
|
||||
FontFamilyPanel: fontFamilyPanel,
|
||||
FontSizePanel: fontSizePanel,
|
||||
IconPanel: iconPanel,
|
||||
Imenu: imenu,
|
||||
IMenu: iMenu,
|
||||
KeyboardShortcutTooltip: keyboardShortcutTooltip,
|
||||
LinkEditor: linkEditor,
|
||||
LinkIconTooltip: linkIconTooltip,
|
||||
|
@ -9,23 +9,27 @@ function mindplot() {
|
||||
const { Layout } = require('./components/layout');
|
||||
|
||||
// Model
|
||||
const { Models } = require('./components/model');
|
||||
const { Model } = require('./components/model');
|
||||
|
||||
// Persistence
|
||||
const { Persistence } = require('./components/persistence');
|
||||
|
||||
// Utils
|
||||
const { Utils } = require('./components/util');
|
||||
|
||||
// Widgets
|
||||
const { Widgets } = require('./components/widget');
|
||||
|
||||
// Commponents
|
||||
// Components
|
||||
const { Components } = require('./components');
|
||||
|
||||
return {
|
||||
commands: Commands,
|
||||
layout: Layout,
|
||||
models: Models,
|
||||
layouts: Layout,
|
||||
models: Model,
|
||||
persistence: Persistence,
|
||||
widget: Widgets,
|
||||
component: Components,
|
||||
utils: Utils,
|
||||
widgets: Widgets,
|
||||
components: Components,
|
||||
};
|
||||
}
|
||||
|
@ -20,9 +20,9 @@
|
||||
"url": "git+https://ezequielVega@bitbucket.org/lilabyus/wisemapping-frontend.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn build:dev && yarn build:test",
|
||||
"build:dev": "webpack --config webpack.prod.js",
|
||||
"build:test": "webpack --config webpack.test.js",
|
||||
"build": "yarn mindplot:build && yarn test:build",
|
||||
"test:build": "webpack --config webpack.test.js",
|
||||
"mindplot:build": "webpack --config webpack.prod.js",
|
||||
"start": "webpack serve --config webpack.dev.js"
|
||||
},
|
||||
"dependencies": {
|
||||
@ -31,7 +31,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.14.6",
|
||||
"@babel/preset-env": "^7.14.7",
|
||||
"babel-loader": "^8.2.2",
|
||||
"clean-webpack-plugin": "^4.0.0-alpha.0",
|
||||
"webpack": "^5.44.0",
|
||||
|
@ -1,180 +1,174 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="../../../lib/components/libraries/jquery/jquery-2.1.0.min.js"
|
||||
></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="../../../lib/components/libraries/mootools/mootools-core-1.4.5-full-nocompat-yc.js"
|
||||
></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="../../../lib/components/libraries/underscorejs/underscore-min.js"
|
||||
></script>
|
||||
|
||||
<script type="text/javascript" src="../../../../core-js/dist/core.js"></script>
|
||||
<script type="text/javascript" src="../../../lib/components/header.js"></script>
|
||||
<script type="text/javascript" src="../../../dist/main.js"></script>
|
||||
<head>
|
||||
<script src="../../../lib/components/libraries/jquery/jquery-2.1.0.min.js"></script>
|
||||
<script type='text/javascript' src='../../../lib/components/libraries/mootools/mootools-core-1.4.5-full-nocompat-yc.js'></script>
|
||||
<script src="../../../lib/components/libraries/underscorejs/underscore-min.js"></script>
|
||||
<script type='text/javascript' src='../../../../core-js/dist/core.js'></script>
|
||||
<script src="../../../dist/main.js"></script>
|
||||
|
||||
<script type="text/javascript" src="test/raphael-min.js"></script>
|
||||
<script type="text/javascript" src="test/raphael-plugins.js"></script>
|
||||
<script type="text/javascript" src="test/raphael-min.js"></script>
|
||||
<script type="text/javascript" src="test/raphael-plugins.js"></script>
|
||||
|
||||
<script type="text/javascript" src="../../../dist/test/layout.test.js"></script>
|
||||
<script src="../../../dist/test/layout.test.js"></script>
|
||||
|
||||
<style type="text/css">
|
||||
div.col {
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
}
|
||||
div.col.last {
|
||||
float: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="basicTest" style="display: none">
|
||||
<h1>Basic Tests</h1>
|
||||
<style type="text/css">
|
||||
div.col {
|
||||
float: left;
|
||||
margin-right: 20px;
|
||||
}
|
||||
div.col.last {
|
||||
float: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h3>testAligned:</h3>
|
||||
<div id="testAligned"></div>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h3>testBaselineAligned:</h3>
|
||||
<div id="testBaselineAligned1"></div>
|
||||
<div id="testBaselineAligned2"></div>
|
||||
|
||||
<h3>testEvents:</h3>
|
||||
<div id="testEvents1" class="col"></div>
|
||||
<div id="testEvents2" class="col last"></div>
|
||||
<div id="basicTest" style="display: none;">
|
||||
<h1>Basic Tests</h1>
|
||||
|
||||
<h3>testEventsComplex:</h3>
|
||||
<div id="testEventsComplex1" class="col"></div>
|
||||
<div id="testEventsComplex2" class="col last"></div>
|
||||
<h3>testAligned:</h3>
|
||||
<div id="testAligned"></div>
|
||||
|
||||
<h3>testDisconnect:</h3>
|
||||
<div id="testDisconnect1" class="col"></div>
|
||||
<div id="testDisconnect2" class="col"></div>
|
||||
<div id="testDisconnect3" class="col last"></div>
|
||||
<h3>testBaselineAligned:</h3>
|
||||
<div id="testBaselineAligned1"></div>
|
||||
<div id="testBaselineAligned2"></div>
|
||||
|
||||
<h3>testReconnect:</h3>
|
||||
<div id="testReconnect1" class="col"></div>
|
||||
<div id="testReconnect2" class="col last"></div>
|
||||
<h3>testEvents:</h3>
|
||||
<div id="testEvents1" class="col"></div>
|
||||
<div id="testEvents2" class="col last"></div>
|
||||
|
||||
<h3>testRemoveNode:</h3>
|
||||
<div id="testRemoveNode1" class="col"></div>
|
||||
<div id="testRemoveNode2" class="col last"></div>
|
||||
<div id="testRemoveNode3" class="col last"></div>
|
||||
<div id="testRemoveNode4" class="col last"></div>
|
||||
<h3>testEventsComplex:</h3>
|
||||
<div id="testEventsComplex1" class="col"></div>
|
||||
<div id="testEventsComplex2" class="col last"></div>
|
||||
|
||||
<h3>testSize:</h3>
|
||||
<div id="testSize1" class="col"></div>
|
||||
<div id="testSize2" class="col last"></div>
|
||||
<div id="testSize3" class="col last"></div>
|
||||
<div id="testSize4" class="col last"></div>
|
||||
<div id="testSize5" class="col last"></div>
|
||||
<div id="testSize6" class="col last"></div>
|
||||
<h3>testDisconnect:</h3>
|
||||
<div id="testDisconnect1" class="col"></div>
|
||||
<div id="testDisconnect2" class="col"></div>
|
||||
<div id="testDisconnect3" class="col last"></div>
|
||||
|
||||
<h3>testReconnectSingleNode:</h3>
|
||||
<div id="testReconnectSingleNode1" class="col"></div>
|
||||
<div id="testReconnectSingleNode2" class="col"></div>
|
||||
</div>
|
||||
<h3>testReconnect:</h3>
|
||||
<div id="testReconnect1" class="col"></div>
|
||||
<div id="testReconnect2" class="col last"></div>
|
||||
|
||||
<div id="balancedTest" style="display: none">
|
||||
<h1>Balanced Sorter Tests</h1>
|
||||
<h3>testRemoveNode:</h3>
|
||||
<div id="testRemoveNode1" class="col"></div>
|
||||
<div id="testRemoveNode2" class="col last"></div>
|
||||
<div id="testRemoveNode3" class="col last"></div>
|
||||
<div id="testRemoveNode4" class="col last"></div>
|
||||
|
||||
<h3>testBalanced:</h3>
|
||||
<div id="testBalanced1" class="col"></div>
|
||||
<div id="testBalanced2" class="col"></div>
|
||||
<div id="testBalanced3" class="col last"></div>
|
||||
<div id="testBalanced4" class="col"></div>
|
||||
<div id="testBalanced5" class="col"></div>
|
||||
<div id="testBalanced6" class="col last"></div>
|
||||
<div id="testBalanced7" class="col"></div>
|
||||
<div id="testBalanced8" class="col last"></div>
|
||||
<div id="testBalanced9" class="col last"></div>
|
||||
<div id="testBalanced10" class="col last"></div>
|
||||
<div id="testBalanced11" class="col last"></div>
|
||||
<div id="testBalanced12" class="col last"></div>
|
||||
<div id="testBalanced13" class="col last"></div>
|
||||
<h3>testSize:</h3>
|
||||
<div id="testSize1" class="col"></div>
|
||||
<div id="testSize2" class="col last"></div>
|
||||
<div id="testSize3" class="col last"></div>
|
||||
<div id="testSize4" class="col last"></div>
|
||||
<div id="testSize5" class="col last"></div>
|
||||
<div id="testSize6" class="col last"></div>
|
||||
|
||||
<h3>testBalancedPredict:</h3>
|
||||
<div id="testBalancedPredict1"></div>
|
||||
<div id="testBalancedPredict2"></div>
|
||||
<div id="testBalancedPredict3"></div>
|
||||
<div id="testBalancedPredict4"></div>
|
||||
<div id="testBalancedPredict5"></div>
|
||||
<h3>testReconnectSingleNode:</h3>
|
||||
<div id="testReconnectSingleNode1" class="col"></div>
|
||||
<div id="testReconnectSingleNode2" class="col"></div>
|
||||
</div>
|
||||
|
||||
<h3>testBalancedNodeDragPredict</h3>
|
||||
<div id="testBalancedNodeDragPredict1"></div>
|
||||
<div id="testBalancedNodeDragPredict2"></div>
|
||||
<div id="testBalancedNodeDragPredict3"></div>
|
||||
</div>
|
||||
<div id="balancedTest" style="display: none;">
|
||||
<h1>Balanced Sorter Tests</h1>
|
||||
|
||||
<div id="symmetricTest" style="display: none">
|
||||
<h1>Symmetric Sorter Tests</h1>
|
||||
<h3>testSymmetry:</h3>
|
||||
<div id="testSymmetry"></div>
|
||||
<h3>testBalanced:</h3>
|
||||
<div id="testBalanced1" class="col"></div>
|
||||
<div id="testBalanced2" class="col"></div>
|
||||
<div id="testBalanced3" class="col last"></div>
|
||||
<div id="testBalanced4" class="col"></div>
|
||||
<div id="testBalanced5" class="col"></div>
|
||||
<div id="testBalanced6" class="col last"></div>
|
||||
<div id="testBalanced7" class="col"></div>
|
||||
<div id="testBalanced8" class="col last"></div>
|
||||
<div id="testBalanced9" class="col last"></div>
|
||||
<div id="testBalanced10" class="col last"></div>
|
||||
<div id="testBalanced11" class="col last"></div>
|
||||
<div id="testBalanced12" class="col last"></div>
|
||||
<div id="testBalanced13" class="col last"></div>
|
||||
|
||||
<h3>testSymmetricPredict:</h3>
|
||||
<div id="testSymmetricPredict1"></div>
|
||||
<div id="testSymmetricPredict2"></div>
|
||||
<div id="testSymmetricPredict3"></div>
|
||||
<div id="testSymmetricPredict4"></div>
|
||||
<div id="testSymmetricPredict5"></div>
|
||||
<h3>testBalancedPredict:</h3>
|
||||
<div id="testBalancedPredict1"></div>
|
||||
<div id="testBalancedPredict2"></div>
|
||||
<div id="testBalancedPredict3"></div>
|
||||
<div id="testBalancedPredict4"></div>
|
||||
<div id="testBalancedPredict5"></div>
|
||||
|
||||
<h3>testBalancedNodeDragPredict</h3>
|
||||
<div id="testBalancedNodeDragPredict1"></div>
|
||||
<div id="testBalancedNodeDragPredict2"></div>
|
||||
<div id="testBalancedNodeDragPredict3"></div>
|
||||
</div>
|
||||
|
||||
<h3>testSymmetricDragPredict:</h3>
|
||||
<div id="testSymmetricDragPredict1"></div>
|
||||
</div>
|
||||
<div id="symmetricTest" style="display: none;">
|
||||
<h1>Symmetric Sorter Tests</h1>
|
||||
<h3>testSymmetry:</h3>
|
||||
<div id="testSymmetry"></div>
|
||||
|
||||
<div id="freeTest" style="display: none">
|
||||
<h1>Free Positioning Tests</h1>
|
||||
<h3>testSymmetricPredict:</h3>
|
||||
<div id="testSymmetricPredict1"></div>
|
||||
<div id="testSymmetricPredict2"></div>
|
||||
<div id="testSymmetricPredict3"></div>
|
||||
<div id="testSymmetricPredict4"></div>
|
||||
<div id="testSymmetricPredict5"></div>
|
||||
|
||||
<h3>testSymmetricDragPredict:</h3>
|
||||
<div id="testSymmetricDragPredict1"></div>
|
||||
</div>
|
||||
|
||||
<h3>testFreePosition:</h3>
|
||||
<div id="testFreePosition1" class="col"></div>
|
||||
<div id="testFreePosition2" class="col last"></div>
|
||||
<div id="testFreePosition3" class="col last"></div>
|
||||
<div id="testFreePosition4" class="col last"></div>
|
||||
<div id="testFreePosition5" class="col last"></div>
|
||||
<div id="testFreePosition6" class="col last"></div>
|
||||
<div id="testFreePosition7" class="col last"></div>
|
||||
<div id="testFreePosition8" class="col last"></div>
|
||||
<div id="testFreePosition9" class="col last"></div>
|
||||
<div id="freeTest" style="display: none;">
|
||||
<h1>Free Positioning Tests</h1>
|
||||
|
||||
<h3>testFreePredict:</h3>
|
||||
<div id="testFreePredict1" class="col"></div>
|
||||
<h3>testFreePosition:</h3>
|
||||
<div id="testFreePosition1" class="col"></div>
|
||||
<div id="testFreePosition2" class="col last"></div>
|
||||
<div id="testFreePosition3" class="col last"></div>
|
||||
<div id="testFreePosition4" class="col last"></div>
|
||||
<div id="testFreePosition5" class="col last"></div>
|
||||
<div id="testFreePosition6" class="col last"></div>
|
||||
<div id="testFreePosition7" class="col last"></div>
|
||||
<div id="testFreePosition8" class="col last"></div>
|
||||
<div id="testFreePosition9" class="col last"></div>
|
||||
|
||||
<h3>testReconnectFreeNode:</h3>
|
||||
<div id="testReconnectFreeNode1" class="col"></div>
|
||||
<div id="testReconnectFreeNode2" class="col"></div>
|
||||
<div id="testReconnectFreeNode3" class="col"></div>
|
||||
<div id="testReconnectFreeNode4" class="col"></div>
|
||||
<div id="testReconnectFreeNode5" class="col"></div>
|
||||
<div id="testReconnectFreeNode6" class="col"></div>
|
||||
<div id="testReconnectFreeNode7" class="col"></div>
|
||||
<h3>testFreePredict:</h3>
|
||||
<div id="testFreePredict1" class="col"></div>
|
||||
|
||||
<h3>testSiblingOverlapping:</h3>
|
||||
<div id="testSiblingOverlapping1" class="col"></div>
|
||||
<div id="testSiblingOverlapping2" class="col"></div>
|
||||
<div id="testSiblingOverlapping3" class="col"></div>
|
||||
<h3>testReconnectFreeNode:</h3>
|
||||
<div id="testReconnectFreeNode1" class="col"></div>
|
||||
<div id="testReconnectFreeNode2" class="col"></div>
|
||||
<div id="testReconnectFreeNode3" class="col"></div>
|
||||
<div id="testReconnectFreeNode4" class="col"></div>
|
||||
<div id="testReconnectFreeNode5" class="col"></div>
|
||||
<div id="testReconnectFreeNode6" class="col"></div>
|
||||
<div id="testReconnectFreeNode7" class="col"></div>
|
||||
|
||||
<h3>testRootNodeChildrenPositioning:</h3>
|
||||
<div id="testRootNodeChildrenPositioning1" class="col"></div>
|
||||
<div id="testRootNodeChildrenPositioning2" class="col"></div>
|
||||
<div id="testRootNodeChildrenPositioning3" class="col"></div>
|
||||
<div id="testRootNodeChildrenPositioning4" class="col"></div>
|
||||
<div id="testRootNodeChildrenPositioning5" class="col"></div>
|
||||
<h3>testSiblingOverlapping:</h3>
|
||||
<div id="testSiblingOverlapping1" class="col"></div>
|
||||
<div id="testSiblingOverlapping2" class="col"></div>
|
||||
<div id="testSiblingOverlapping3" class="col"></div>
|
||||
|
||||
<h3>testRootNodeChildrenPositioning:</h3>
|
||||
<div id="testRootNodeChildrenPositioning1" class="col"></div>
|
||||
<div id="testRootNodeChildrenPositioning2" class="col"></div>
|
||||
<div id="testRootNodeChildrenPositioning3" class="col"></div>
|
||||
<div id="testRootNodeChildrenPositioning4" class="col"></div>
|
||||
<div id="testRootNodeChildrenPositioning5" class="col"></div>
|
||||
|
||||
<h3>testBalancedFreePredict:</h3>
|
||||
<div id="testBalancedFreePredict1" class="col"></div>
|
||||
|
||||
<h3>testBalancedFreePredict:</h3>
|
||||
<div id="testBalancedFreePredict1" class="col"></div>
|
||||
<h3>testFreeReorder:</h3>
|
||||
<div id="testFreeReorder1" class="col"></div>
|
||||
|
||||
<h3>testFreeReorder:</h3>
|
||||
<div id="testFreeReorder1" class="col"></div>
|
||||
<h3>testFreeOverlap:</h3>
|
||||
<div id="testFreeOverlap1" class="col"></div>
|
||||
<div id="testFreeOverlap2" class="col"></div>
|
||||
</div>
|
||||
|
||||
<h3>testFreeOverlap:</h3>
|
||||
<div id="testFreeOverlap1" class="col"></div>
|
||||
<div id="testFreeOverlap2" class="col"></div>
|
||||
</div>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,16 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<script src="../../../lib/components/libraries/jquery/jquery-2.1.0.min.js"></script>
|
||||
<script src="../../../lib/components/libraries/mootools/mootools-core-1.4.5-full-nocompat-yc.js"></script>
|
||||
<script src="../../../lib/components/libraries/underscorejs/underscore-min.js"></script>
|
||||
<script src="../../../lib/components/libraries/bootstrap/js/bootstrap.min.js"></script>
|
||||
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Document</title>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="../../../lib/components/libraries/jquery/jquery-2.1.0.js"
|
||||
></script>
|
||||
<script type="text/javascript" src="../../../../core-js/dist/core.js"></script>
|
||||
<script type="text/javascript" src="../../../dist/test/palette.test.js"></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="../../../lib/components/libraries/mootools/mootools-core-1.4.5-full-nocompat-yc.js"
|
||||
></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="../../../lib/components/libraries/underscorejs/underscore-min.js"
|
||||
></script>
|
||||
<script
|
||||
type="text/javascript"
|
||||
src="../../../lib/components/libraries/bootstrap/js/bootstrap.min.js"
|
||||
></script>
|
||||
|
||||
<script type="text/javascript" src="../../../dist/main.js"></script>
|
||||
<script type="text/javascript" src="../../../dist/test/palette.test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="myButton" style="border: 1px red solid">The button</div>
|
||||
<body>
|
||||
<div id="myButton" style="border: 1px red solid">The button</div>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -17,6 +17,9 @@
|
||||
*/
|
||||
const TestSuite = require('./TestSuite').default;
|
||||
|
||||
const Mindplot = require('../../../../lib/mindplot');
|
||||
const mindplot = Mindplot();
|
||||
|
||||
const BalancedTestSuite = new Class({
|
||||
Extends: TestSuite,
|
||||
|
||||
|
@ -16,6 +16,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
const TestSuite = require('./TestSuite').default;
|
||||
const Mindplot = require('../../../../lib/mindplot');
|
||||
const mindplot = Mindplot();
|
||||
|
||||
const FreeTestSuite = new Class({
|
||||
Extends: TestSuite,
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
const TestSuite = require('./TestSuite').default;
|
||||
const Mindplot = require('../../../../lib/mindplot');
|
||||
const mindplot = Mindplot();
|
||||
|
||||
const SymmetricTestSuite = new Class({
|
||||
Extends: TestSuite,
|
||||
@ -154,6 +156,8 @@ const SymmetricTestSuite = new Class({
|
||||
console.log('\tAdded as child of node 5 and dropped at (380, -30):');
|
||||
var prediction2d = manager.predict(5, null, { x: 380, y: -30 });
|
||||
this._plotPrediction(graph2, prediction2d);
|
||||
|
||||
// Prediction calculator error
|
||||
$assert(
|
||||
prediction2d.position.y < manager.find(7).getPosition().y &&
|
||||
prediction2d.position.x == manager.find(7).getPosition().x,
|
||||
@ -164,6 +168,7 @@ const SymmetricTestSuite = new Class({
|
||||
console.log('\tAdded as child of node 5 and dropped at (375, 15):');
|
||||
var prediction2a = manager.predict(5, null, { x: 375, y: 15 });
|
||||
this._plotPrediction(graph2, prediction2a);
|
||||
|
||||
$assert(
|
||||
prediction2a.position.y > manager.find(7).getPosition().y &&
|
||||
prediction2a.position.y < manager.find(8).getPosition().y &&
|
||||
@ -278,6 +283,7 @@ const SymmetricTestSuite = new Class({
|
||||
console.log('testSymmetricDragPredict:');
|
||||
var position = { x: 0, y: 0 };
|
||||
var manager = new mindplot.layout.LayoutManager(0, TestSuite.ROOT_NODE_SIZE);
|
||||
|
||||
manager.addNode(1, TestSuite.NODE_SIZE, position).connectNode(0, 1, 1);
|
||||
manager.addNode(2, TestSuite.NODE_SIZE, position).connectNode(1, 2, 0);
|
||||
manager.layout();
|
||||
|
@ -15,12 +15,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
const Mindplot = require('../../../../lib/mindplot');
|
||||
const mindplot = Mindplot();
|
||||
|
||||
const TestSuite = new Class({
|
||||
Extends: mindplot.layout.ChildrenSorterStrategy,
|
||||
|
||||
initialize: function () {
|
||||
$('#basicTest').css('display', 'block');
|
||||
|
||||
// this.testAligned();
|
||||
this.testBaselineAligned1();
|
||||
this.testBaselineAligned2();
|
||||
@ -230,6 +232,9 @@ const TestSuite = new Class({
|
||||
manager.plot('testEventsComplex2', { width: 800, height: 200 });
|
||||
|
||||
// Check only 4 nodes were repositioned
|
||||
|
||||
console.log(events.length);
|
||||
|
||||
$assert(events.length == 4, 'Only 4 nodes should be repositioned.');
|
||||
|
||||
console.log('OK!\n\n');
|
||||
|
14
packages/mindplot/test/javascript/static/testing.html
Normal file
14
packages/mindplot/test/javascript/static/testing.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Document</title>
|
||||
<script src="../../../lib/components/libraries/jquery/jquery-2.1.0.min.js"></script>
|
||||
<script src="../../../lib/components/libraries/mootools/mootools-core-1.6.0.js"></script>
|
||||
<script src="../../../../core-js/dist/core.js"></script>
|
||||
<script src="../../../dist/main.js"></script>
|
||||
<script src="../../../dist/24.js"></script>
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
@ -4,15 +4,21 @@ const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||
/** @type {import('webpack').Configuration} */
|
||||
module.exports = {
|
||||
entry: {
|
||||
palette: path.resolve(__dirname, './test/javascript/static/test/testPalette'),
|
||||
layout: path.resolve(__dirname, './test/javascript/static/test/testLayout'),
|
||||
testingLayout: './test/javascript/static/test/testingLayout',
|
||||
testingPallete: './test/javascript/static/test/testingPalette',
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist', 'test'),
|
||||
filename: '[name].test.js',
|
||||
path: path.resolve(__dirname, 'dist', 'tests'),
|
||||
filename: '[name].js',
|
||||
publicPath: '',
|
||||
},
|
||||
mode: 'production',
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
minSize: 2000000,
|
||||
},
|
||||
},
|
||||
devtool: 'source-map',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
|
@ -35,7 +35,7 @@ function web2D() {
|
||||
const verdanaFont = require('./components/peer/svg/VerdanaFont').default; //eslint-disable-line
|
||||
const point = require('./components/Point').default; //eslint-disable-line
|
||||
|
||||
global.web2d = {
|
||||
const web2d = {
|
||||
ElementPeer: elementPeer,
|
||||
Element: element,
|
||||
Workspace: workspace,
|
||||
@ -68,7 +68,7 @@ function web2D() {
|
||||
Point: point,
|
||||
};
|
||||
|
||||
return global.web2d; //eslint-disable-line
|
||||
return web2d; //eslint-disable-line
|
||||
}
|
||||
|
||||
module.exports = web2D; //eslint-disable-line
|
||||
|
Loading…
Reference in New Issue
Block a user