Mindplot module migration

This commit is contained in:
Ezequiel-Vega 2021-09-02 13:32:23 -03:00
parent d515e0bb57
commit 0567dedb88
37 changed files with 11320 additions and 3725 deletions

View File

@ -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
}

View File

@ -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;

View File

@ -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({

View File

@ -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

View File

@ -31,7 +31,7 @@ const Messages = new Class({
},
});
global.$msg = function (key) {
const $msg = function (key) {
if (!Messages.__bundle) {
Messages.init('en');
}

View File

@ -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();

View File

@ -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;

View File

@ -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({

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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}

View File

@ -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;

View File

@ -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;

View 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);}};})();

File diff suppressed because it is too large Load Diff

View File

@ -421,5 +421,5 @@ INodeModel._nextUUID = function () {
};
INodeModel._uuid = 0;
export default INodeModel;
export { TopicShape };
export default INodeModel;

View File

@ -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,
};

View File

@ -0,0 +1,7 @@
const fadeEffect = require('./FadeEffect').default;
const shape = require('./Shape').default;
export const Utils = {
FadeEffect: fadeEffect,
Shape: shape,
};

View File

@ -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;

View File

@ -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;

View File

@ -46,4 +46,5 @@ const $notify = function (msg) {
toolbarNotifier.logMessage(msg);
};
export { $notify };
export default ToolbarNotifier;

View File

@ -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,

View File

@ -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,
};
}

View File

@ -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",

View File

@ -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>

View File

@ -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>

View File

@ -17,6 +17,9 @@
*/
const TestSuite = require('./TestSuite').default;
const Mindplot = require('../../../../lib/mindplot');
const mindplot = Mindplot();
const BalancedTestSuite = new Class({
Extends: TestSuite,

View File

@ -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,

View File

@ -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();

View File

@ -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');

View 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>

View File

@ -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: [
{

View File

@ -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

4859
yarn.lock

File diff suppressed because it is too large Load Diff