mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-25 23:54:55 +01:00
Add more tests on mindplot/playground and fix.
This commit is contained in:
parent
e102b61c7d
commit
a10b41ee4d
@ -10,8 +10,6 @@
|
|||||||
"globals":{
|
"globals":{
|
||||||
"Class": "readonly",
|
"Class": "readonly",
|
||||||
"$": "readonly",
|
"$": "readonly",
|
||||||
"$assert": "readonly",
|
|
||||||
"$defined": "readonly",
|
|
||||||
"$msg": "readonly",
|
"$msg": "readonly",
|
||||||
"_": "readonly"
|
"_": "readonly"
|
||||||
},
|
},
|
||||||
@ -19,6 +17,7 @@
|
|||||||
"rules": {
|
"rules": {
|
||||||
"no-underscore-dangle": "off",
|
"no-underscore-dangle": "off",
|
||||||
"no-plusplus": "off",
|
"no-plusplus": "off",
|
||||||
|
"class-methods-use-this": "off",
|
||||||
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["!cypress/**/*.js"]}]
|
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["!cypress/**/*.js"]}]
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
|
@ -33,7 +33,8 @@
|
|||||||
"@wisemapping/core-js": "^0.0.1",
|
"@wisemapping/core-js": "^0.0.1",
|
||||||
"@wisemapping/web2d": "^0.0.1",
|
"@wisemapping/web2d": "^0.0.1",
|
||||||
"jquery": "^3.6.0",
|
"jquery": "^3.6.0",
|
||||||
"mootools": "1.4.5"
|
"mootools": "1.4.5",
|
||||||
|
"underscore": "^1.13.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.14.6",
|
"@babel/core": "^7.14.6",
|
||||||
@ -53,6 +54,8 @@
|
|||||||
"eslint-plugin-import": "^2.24.2",
|
"eslint-plugin-import": "^2.24.2",
|
||||||
"eslint-plugin-only-warn": "^1.0.3",
|
"eslint-plugin-only-warn": "^1.0.3",
|
||||||
"html-webpack-plugin": "^5.3.2",
|
"html-webpack-plugin": "^5.3.2",
|
||||||
|
"less": "^4.1.2",
|
||||||
|
"less-loader": "^10.2.0",
|
||||||
"nodemon": "^2.0.12",
|
"nodemon": "^2.0.12",
|
||||||
"start-server-and-test": "^1.14.0",
|
"start-server-and-test": "^1.14.0",
|
||||||
"webpack": "^5.44.0",
|
"webpack": "^5.44.0",
|
||||||
|
@ -17,161 +17,162 @@
|
|||||||
*/
|
*/
|
||||||
import { $assert, $defined } from '@wisemapping/core-js';
|
import { $assert, $defined } from '@wisemapping/core-js';
|
||||||
import * as web2d from '@wisemapping/web2d';
|
import * as web2d from '@wisemapping/web2d';
|
||||||
|
import IconGroupRemoveTip from './IconGroupRemoveTip';
|
||||||
|
|
||||||
import Icon from './Icon';
|
import Icon from './Icon';
|
||||||
|
|
||||||
const IconGroup = new Class(
|
class IconGroup {
|
||||||
/** @lends IconGroup */ {
|
/** @lends IconGroup */
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param topicId
|
* @param topicId
|
||||||
* @param iconSize
|
* @param iconSize
|
||||||
* @throws will throw an error if topicId is null or undefined
|
* @throws will throw an error if topicId is null or undefined
|
||||||
* @throws will throw an error if iconSize is null or undefined
|
* @throws will throw an error if iconSize is null or undefined
|
||||||
*/
|
*/
|
||||||
initialize(topicId, iconSize) {
|
constructor(topicId, iconSize) {
|
||||||
$assert($defined(topicId), 'topicId can not be null');
|
$assert($defined(topicId), 'topicId can not be null');
|
||||||
$assert($defined(iconSize), 'iconSize can not be null');
|
$assert($defined(iconSize), 'iconSize can not be null');
|
||||||
|
|
||||||
this._icons = [];
|
this._icons = [];
|
||||||
this._group = new web2d.Group({
|
this._group = new web2d.Group({
|
||||||
width: 0,
|
width: 0,
|
||||||
height: iconSize,
|
height: iconSize,
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
coordSizeWidth: 0,
|
coordSizeWidth: 0,
|
||||||
coordSizeHeight: 100,
|
coordSizeHeight: 100,
|
||||||
});
|
});
|
||||||
this._removeTip = new IconGroup.RemoveTip(this._group, topicId);
|
this._removeTip = new IconGroup.RemoveTip(this._group, topicId);
|
||||||
this.seIconSize(iconSize, iconSize);
|
this.seIconSize(iconSize, iconSize);
|
||||||
|
|
||||||
this._registerListeners();
|
this._registerListeners();
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setPosition(x, y) {
|
setPosition(x, y) {
|
||||||
this._group.setPosition(x, y);
|
this._group.setPosition(x, y);
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getPosition() {
|
getPosition() {
|
||||||
return this._group.getPosition();
|
return this._group.getPosition();
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getNativeElement() {
|
getNativeElement() {
|
||||||
return this._group;
|
return this._group;
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getSize() {
|
getSize() {
|
||||||
return this._group.getSize();
|
return this._group.getSize();
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
seIconSize(width, height) {
|
seIconSize(width, height) {
|
||||||
this._iconSize = { width, height };
|
this._iconSize = { width, height };
|
||||||
this._resize(this._icons.length);
|
this._resize(this._icons.length);
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param icon the icon to be added to the icon group
|
* @param icon the icon to be added to the icon group
|
||||||
* @param {Boolean} remove
|
* @param {Boolean} remove
|
||||||
* @throws will throw an error if icon is not defined
|
* @throws will throw an error if icon is not defined
|
||||||
*/
|
*/
|
||||||
addIcon(icon, remove) {
|
addIcon(icon, remove) {
|
||||||
$defined(icon, 'icon is not defined');
|
$defined(icon, 'icon is not defined');
|
||||||
|
|
||||||
icon.setGroup(this);
|
icon.setGroup(this);
|
||||||
this._icons.push(icon);
|
this._icons.push(icon);
|
||||||
|
|
||||||
// Adjust group and position ...
|
// Adjust group and position ...
|
||||||
this._resize(this._icons.length);
|
this._resize(this._icons.length);
|
||||||
this._positionIcon(icon, this._icons.length - 1);
|
this._positionIcon(icon, this._icons.length - 1);
|
||||||
|
|
||||||
const imageShape = icon.getImage();
|
const imageShape = icon.getImage();
|
||||||
this._group.append(imageShape);
|
this._group.append(imageShape);
|
||||||
|
|
||||||
// Register event for the group ..
|
// Register event for the group ..
|
||||||
if (remove) {
|
if (remove) {
|
||||||
this._removeTip.decorate(this._topicId, icon);
|
this._removeTip.decorate(this._topicId, icon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_findIconFromModel(iconModel) {
|
||||||
|
let result = null;
|
||||||
|
|
||||||
|
this._icons.forEach((icon) => {
|
||||||
|
const elModel = icon.getModel();
|
||||||
|
|
||||||
|
if (elModel.getId() === iconModel.getId()) {
|
||||||
|
result = icon;
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
_findIconFromModel(iconModel) {
|
if (result == null) {
|
||||||
let result = null;
|
throw new Error(`Icon can no be found:${iconModel.getId()}, Icons:${this._icons}`);
|
||||||
|
}
|
||||||
|
|
||||||
this._icons.forEach((icon) => {
|
return result;
|
||||||
const elModel = icon.getModel();
|
}
|
||||||
|
|
||||||
if (elModel.getId() === iconModel.getId()) {
|
/** */
|
||||||
result = icon;
|
removeIconByModel(featureModel) {
|
||||||
}
|
$assert(featureModel, 'featureModel can not be null');
|
||||||
});
|
|
||||||
|
|
||||||
if (result == null) {
|
const icon = this._findIconFromModel(featureModel);
|
||||||
throw new Error(`Icon can no be found:${iconModel.getId()}, Icons:${this._icons}`);
|
this._removeIcon(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
_removeIcon(icon) {
|
||||||
},
|
$assert(icon, 'icon can not be null');
|
||||||
|
|
||||||
/** */
|
this._removeTip.close(0);
|
||||||
removeIconByModel(featureModel) {
|
this._group.removeChild(icon.getImage());
|
||||||
$assert(featureModel, 'featureModel can not be null');
|
|
||||||
|
|
||||||
const icon = this._findIconFromModel(featureModel);
|
this._icons.erase(icon);
|
||||||
this._removeIcon(icon);
|
this._resize(this._icons.length);
|
||||||
},
|
const me = this;
|
||||||
|
|
||||||
_removeIcon(icon) {
|
// Add all again ...
|
||||||
$assert(icon, 'icon can not be null');
|
this._icons.forEach((elem, i) => {
|
||||||
|
me._positionIcon(elem, i);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this._removeTip.close(0);
|
/** */
|
||||||
this._group.removeChild(icon.getImage());
|
moveToFront() {
|
||||||
|
this._group.moveToFront();
|
||||||
|
}
|
||||||
|
|
||||||
this._icons.erase(icon);
|
_registerListeners() {
|
||||||
this._resize(this._icons.length);
|
this._group.addEvent('click', (event) => {
|
||||||
const me = this;
|
// Avoid node creation ...
|
||||||
|
event.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
// Add all again ...
|
this._group.addEvent('dblclick', (event) => {
|
||||||
this._icons.forEach((elem, i) => {
|
event.stopPropagation();
|
||||||
me._positionIcon(elem, i);
|
});
|
||||||
});
|
}
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
_resize(iconsLength) {
|
||||||
moveToFront() {
|
this._group.setSize(iconsLength * this._iconSize.width, this._iconSize.height);
|
||||||
this._group.moveToFront();
|
|
||||||
},
|
|
||||||
|
|
||||||
_registerListeners() {
|
const iconSize = Icon.SIZE + IconGroup.ICON_PADDING * 2;
|
||||||
this._group.addEvent('click', (event) => {
|
this._group.setCoordSize(iconsLength * iconSize, iconSize);
|
||||||
// Avoid node creation ...
|
}
|
||||||
event.stopPropagation();
|
|
||||||
});
|
|
||||||
|
|
||||||
this._group.addEvent('dblclick', (event) => {
|
// eslint-disable-next-line class-methods-use-this
|
||||||
event.stopPropagation();
|
_positionIcon(icon, order) {
|
||||||
});
|
const iconSize = Icon.SIZE + IconGroup.ICON_PADDING * 2;
|
||||||
},
|
icon.getImage().setPosition(
|
||||||
|
iconSize * order + IconGroup.ICON_PADDING,
|
||||||
_resize(iconsLength) {
|
IconGroup.ICON_PADDING,
|
||||||
this._group.setSize(iconsLength * this._iconSize.width, this._iconSize.height);
|
);
|
||||||
|
}
|
||||||
const iconSize = Icon.SIZE + IconGroup.ICON_PADDING * 2;
|
}
|
||||||
this._group.setCoordSize(iconsLength * iconSize, iconSize);
|
|
||||||
},
|
|
||||||
|
|
||||||
_positionIcon(icon, order) {
|
|
||||||
const iconSize = Icon.SIZE + IconGroup.ICON_PADDING * 2;
|
|
||||||
icon.getImage().setPosition(
|
|
||||||
iconSize * order + IconGroup.ICON_PADDING,
|
|
||||||
IconGroup.ICON_PADDING,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
@ -180,167 +181,6 @@ const IconGroup = new Class(
|
|||||||
*/
|
*/
|
||||||
IconGroup.ICON_PADDING = 5;
|
IconGroup.ICON_PADDING = 5;
|
||||||
|
|
||||||
IconGroup.RemoveTip = new Class(
|
IconGroup.RemoveTip = IconGroupRemoveTip;
|
||||||
/** @lends IconGroup.RemoveTip */ {
|
|
||||||
/**
|
|
||||||
* @classdesc inner class of IconGroup
|
|
||||||
* @constructs
|
|
||||||
* @param container
|
|
||||||
*/
|
|
||||||
initialize(container) {
|
|
||||||
$assert(container, 'group can not be null');
|
|
||||||
this._fadeElem = container;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param topicId
|
|
||||||
* @param icon
|
|
||||||
* @throws will throw an error if icon is null or undefined
|
|
||||||
*/
|
|
||||||
show(topicId, icon) {
|
|
||||||
$assert(icon, 'icon can not be null');
|
|
||||||
|
|
||||||
// Nothing to do ...
|
|
||||||
if (this._activeIcon != icon) {
|
|
||||||
// If there is an active icon, close it first ...
|
|
||||||
if (this._activeIcon) {
|
|
||||||
this.close(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now, let move the position the icon...
|
|
||||||
const pos = icon.getPosition();
|
|
||||||
|
|
||||||
// Register events ...
|
|
||||||
const widget = this._buildWeb2d();
|
|
||||||
widget.addEvent('click', () => {
|
|
||||||
icon.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
const me = this;
|
|
||||||
|
|
||||||
widget.addEvent('mouseover', () => {
|
|
||||||
me.show(topicId, icon);
|
|
||||||
});
|
|
||||||
|
|
||||||
widget.addEvent('mouseout', () => {
|
|
||||||
me.hide();
|
|
||||||
});
|
|
||||||
|
|
||||||
widget.setPosition(pos.x + 80, pos.y - 50);
|
|
||||||
this._fadeElem.append(widget);
|
|
||||||
|
|
||||||
// Setup current element ...
|
|
||||||
this._activeIcon = icon;
|
|
||||||
this._widget = widget;
|
|
||||||
} else {
|
|
||||||
clearTimeout(this._closeTimeoutId);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** */
|
|
||||||
hide() {
|
|
||||||
this.close(200);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param delay
|
|
||||||
*/
|
|
||||||
close(delay) {
|
|
||||||
// This is not ok, trying to close the same dialog twice ?
|
|
||||||
if (this._closeTimeoutId) {
|
|
||||||
clearTimeout(this._closeTimeoutId);
|
|
||||||
}
|
|
||||||
|
|
||||||
const me = this;
|
|
||||||
if (this._activeIcon) {
|
|
||||||
const widget = this._widget;
|
|
||||||
const close = function () {
|
|
||||||
me._activeIcon = null;
|
|
||||||
me._fadeElem.removeChild(widget);
|
|
||||||
me._widget = null;
|
|
||||||
me._closeTimeoutId = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!$defined(delay) || delay == 0) {
|
|
||||||
close();
|
|
||||||
} else {
|
|
||||||
this._closeTimeoutId = close.delay(delay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_buildWeb2d() {
|
|
||||||
const result = new web2d.Group({
|
|
||||||
width: 10,
|
|
||||||
height: 10,
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
coordSizeWidth: 10,
|
|
||||||
coordSizeHeight: 10,
|
|
||||||
});
|
|
||||||
|
|
||||||
const outerRect = new web2d.Rect(0, {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
width: 10,
|
|
||||||
height: 10,
|
|
||||||
stroke: '0',
|
|
||||||
fillColor: 'black',
|
|
||||||
});
|
|
||||||
result.append(outerRect);
|
|
||||||
outerRect.setCursor('pointer');
|
|
||||||
|
|
||||||
const innerRect = new web2d.Rect(0, {
|
|
||||||
x: 1,
|
|
||||||
y: 1,
|
|
||||||
width: 8,
|
|
||||||
height: 8,
|
|
||||||
stroke: '1 solid white',
|
|
||||||
fillColor: 'gray',
|
|
||||||
});
|
|
||||||
result.append(innerRect);
|
|
||||||
|
|
||||||
const line = new web2d.Line({ stroke: '1 solid white' });
|
|
||||||
line.setFrom(1, 1);
|
|
||||||
line.setTo(9, 9);
|
|
||||||
result.append(line);
|
|
||||||
|
|
||||||
const line2 = new web2d.Line({ stroke: '1 solid white' });
|
|
||||||
line2.setFrom(1, 9);
|
|
||||||
line2.setTo(9, 1);
|
|
||||||
result.append(line2);
|
|
||||||
|
|
||||||
// Some events ...
|
|
||||||
result.addEvent('mouseover', () => {
|
|
||||||
innerRect.setFill('#CC0033');
|
|
||||||
});
|
|
||||||
result.addEvent('mouseout', () => {
|
|
||||||
innerRect.setFill('gray');
|
|
||||||
});
|
|
||||||
|
|
||||||
result.setSize(50, 50);
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param topicId
|
|
||||||
* @param icon
|
|
||||||
*/
|
|
||||||
decorate(topicId, icon) {
|
|
||||||
const me = this;
|
|
||||||
|
|
||||||
if (!icon.__remove) {
|
|
||||||
icon.addEvent('mouseover', () => {
|
|
||||||
me.show(topicId, icon);
|
|
||||||
});
|
|
||||||
|
|
||||||
icon.addEvent('mouseout', () => {
|
|
||||||
me.hide();
|
|
||||||
});
|
|
||||||
icon.__remove = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
export default IconGroup;
|
export default IconGroup;
|
||||||
|
165
packages/mindplot/src/components/IconGroupRemoveTip.js
Normal file
165
packages/mindplot/src/components/IconGroupRemoveTip.js
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import * as web2d from '@wisemapping/web2d';
|
||||||
|
import { $assert, $defined } from '@wisemapping/core-js';
|
||||||
|
|
||||||
|
export default class RemoveTip {
|
||||||
|
/** @lends IconGroup.RemoveTip */
|
||||||
|
/**
|
||||||
|
* @classdesc inner class of IconGroup
|
||||||
|
* @constructs
|
||||||
|
* @param container
|
||||||
|
*/
|
||||||
|
constructor(container) {
|
||||||
|
$assert(container, 'group can not be null');
|
||||||
|
this._fadeElem = container;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param topicId
|
||||||
|
* @param icon
|
||||||
|
* @throws will throw an error if icon is null or undefined
|
||||||
|
*/
|
||||||
|
show(topicId, icon) {
|
||||||
|
$assert(icon, 'icon can not be null');
|
||||||
|
|
||||||
|
// Nothing to do ...
|
||||||
|
if (this._activeIcon != icon) {
|
||||||
|
// If there is an active icon, close it first ...
|
||||||
|
if (this._activeIcon) {
|
||||||
|
this.close(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, let move the position the icon...
|
||||||
|
const pos = icon.getPosition();
|
||||||
|
|
||||||
|
// Register events ...
|
||||||
|
const widget = this._buildWeb2d();
|
||||||
|
widget.addEvent('click', () => {
|
||||||
|
icon.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
const me = this;
|
||||||
|
|
||||||
|
widget.addEvent('mouseover', () => {
|
||||||
|
me.show(topicId, icon);
|
||||||
|
});
|
||||||
|
|
||||||
|
widget.addEvent('mouseout', () => {
|
||||||
|
me.hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
widget.setPosition(pos.x + 80, pos.y - 50);
|
||||||
|
this._fadeElem.append(widget);
|
||||||
|
|
||||||
|
// Setup current element ...
|
||||||
|
this._activeIcon = icon;
|
||||||
|
this._widget = widget;
|
||||||
|
} else {
|
||||||
|
clearTimeout(this._closeTimeoutId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** */
|
||||||
|
hide() {
|
||||||
|
this.close(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param delay
|
||||||
|
*/
|
||||||
|
close(delay) {
|
||||||
|
// This is not ok, trying to close the same dialog twice ?
|
||||||
|
if (this._closeTimeoutId) {
|
||||||
|
clearTimeout(this._closeTimeoutId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const me = this;
|
||||||
|
if (this._activeIcon) {
|
||||||
|
const widget = this._widget;
|
||||||
|
const close = function close() {
|
||||||
|
me._activeIcon = null;
|
||||||
|
me._fadeElem.removeChild(widget);
|
||||||
|
me._widget = null;
|
||||||
|
me._closeTimeoutId = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!$defined(delay) || delay == 0) {
|
||||||
|
close();
|
||||||
|
} else {
|
||||||
|
this._closeTimeoutId = close.delay(delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line class-methods-use-this
|
||||||
|
_buildWeb2d() {
|
||||||
|
const result = new web2d.Group({
|
||||||
|
width: 10,
|
||||||
|
height: 10,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
coordSizeWidth: 10,
|
||||||
|
coordSizeHeight: 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
const outerRect = new web2d.Rect(0, {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: 10,
|
||||||
|
height: 10,
|
||||||
|
stroke: '0',
|
||||||
|
fillColor: 'black',
|
||||||
|
});
|
||||||
|
result.append(outerRect);
|
||||||
|
outerRect.setCursor('pointer');
|
||||||
|
|
||||||
|
const innerRect = new web2d.Rect(0, {
|
||||||
|
x: 1,
|
||||||
|
y: 1,
|
||||||
|
width: 8,
|
||||||
|
height: 8,
|
||||||
|
stroke: '1 solid white',
|
||||||
|
fillColor: 'gray',
|
||||||
|
});
|
||||||
|
result.append(innerRect);
|
||||||
|
|
||||||
|
const line = new web2d.Line({ stroke: '1 solid white' });
|
||||||
|
line.setFrom(1, 1);
|
||||||
|
line.setTo(9, 9);
|
||||||
|
result.append(line);
|
||||||
|
|
||||||
|
const line2 = new web2d.Line({ stroke: '1 solid white' });
|
||||||
|
line2.setFrom(1, 9);
|
||||||
|
line2.setTo(9, 1);
|
||||||
|
result.append(line2);
|
||||||
|
|
||||||
|
// Some events ...
|
||||||
|
result.addEvent('mouseover', () => {
|
||||||
|
innerRect.setFill('#CC0033');
|
||||||
|
});
|
||||||
|
result.addEvent('mouseout', () => {
|
||||||
|
innerRect.setFill('gray');
|
||||||
|
});
|
||||||
|
|
||||||
|
result.setSize(50, 50);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param topicId
|
||||||
|
* @param icon
|
||||||
|
*/
|
||||||
|
decorate(topicId, icon) {
|
||||||
|
const me = this;
|
||||||
|
|
||||||
|
if (!icon.__remove) {
|
||||||
|
icon.addEvent('mouseover', () => {
|
||||||
|
me.show(topicId, icon);
|
||||||
|
});
|
||||||
|
|
||||||
|
icon.addEvent('mouseout', () => {
|
||||||
|
me.hide();
|
||||||
|
});
|
||||||
|
icon.__remove = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,10 +16,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import { $defined } from '@wisemapping/core-js';
|
import { $defined } from '@wisemapping/core-js';
|
||||||
import Events from './Events';
|
|
||||||
import ActionDispatcher from './ActionDispatcher';
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import initHotKeyPluggin from '@libraries/jquery.hotkeys';
|
import initHotKeyPluggin from '@libraries/jquery.hotkeys';
|
||||||
|
import Events from './Events';
|
||||||
|
import ActionDispatcher from './ActionDispatcher';
|
||||||
|
|
||||||
initHotKeyPluggin($);
|
initHotKeyPluggin($);
|
||||||
|
|
||||||
@ -56,7 +56,7 @@ class MultilineTextEditor extends Events {
|
|||||||
_registerEvents(containerElem) {
|
_registerEvents(containerElem) {
|
||||||
const textareaElem = this._getTextareaElem();
|
const textareaElem = this._getTextareaElem();
|
||||||
const me = this;
|
const me = this;
|
||||||
textareaElem.on('keydown', function keydown (event) {
|
textareaElem.on('keydown', function keydown(event) {
|
||||||
switch (jQuery.hotkeys.specialKeys[event.keyCode]) {
|
switch (jQuery.hotkeys.specialKeys[event.keyCode]) {
|
||||||
case 'esc':
|
case 'esc':
|
||||||
me.close(false);
|
me.close(false);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable class-methods-use-this */
|
||||||
/*
|
/*
|
||||||
* Copyright [2015] [wisemapping]
|
* Copyright [2015] [wisemapping]
|
||||||
*
|
*
|
||||||
@ -21,61 +22,59 @@ import ChildrenSorterStrategy from './ChildrenSorterStrategy';
|
|||||||
* @class
|
* @class
|
||||||
* @extends mindplot.layout.ChildrenSorterStrategy
|
* @extends mindplot.layout.ChildrenSorterStrategy
|
||||||
*/
|
*/
|
||||||
const AbstractBasicSorter = new Class(
|
class AbstractBasicSorter extends ChildrenSorterStrategy {
|
||||||
/** @lends AbstractBasicSorter */ {
|
/** @lends AbstractBasicSorter */
|
||||||
Extends: ChildrenSorterStrategy,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} node
|
* @param {} node
|
||||||
* @return the height of a node and its children if existing and not shrunken
|
* @return the height of a node and its children if existing and not shrunken
|
||||||
*/
|
*/
|
||||||
computeChildrenIdByHeights(treeSet, node) {
|
computeChildrenIdByHeights(treeSet, node) {
|
||||||
const result = {};
|
const result = {};
|
||||||
this._computeChildrenHeight(treeSet, node, result);
|
this._computeChildrenHeight(treeSet, node, result);
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
_getVerticalPadding() {
|
_getVerticalPadding() {
|
||||||
return AbstractBasicSorter.INTERNODE_VERTICAL_PADDING;
|
return AbstractBasicSorter.INTERNODE_VERTICAL_PADDING;
|
||||||
},
|
}
|
||||||
|
|
||||||
_computeChildrenHeight(treeSet, node, heightCache) {
|
_computeChildrenHeight(treeSet, node, heightCache) {
|
||||||
const height = node.getSize().height + this._getVerticalPadding() * 2; // 2* Top and down padding;
|
const height = node.getSize().height + this._getVerticalPadding() * 2; // 2* Top and down padding;
|
||||||
|
|
||||||
let result;
|
let result;
|
||||||
const children = treeSet.getChildren(node);
|
const children = treeSet.getChildren(node);
|
||||||
if (children.length === 0 || node.areChildrenShrunken()) {
|
if (children.length === 0 || node.areChildrenShrunken()) {
|
||||||
result = height;
|
result = height;
|
||||||
} else {
|
} else {
|
||||||
let childrenHeight = 0;
|
let childrenHeight = 0;
|
||||||
|
|
||||||
children.forEach(((child) => {
|
children.forEach(((child) => {
|
||||||
childrenHeight += this._computeChildrenHeight(treeSet, child, heightCache);
|
childrenHeight += this._computeChildrenHeight(treeSet, child, heightCache);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
result = Math.max(height, childrenHeight);
|
result = Math.max(height, childrenHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (heightCache) {
|
if (heightCache) {
|
||||||
heightCache[node.getId()] = result;
|
heightCache[node.getId()] = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
_getSortedChildren(treeSet, node) {
|
_getSortedChildren(treeSet, node) {
|
||||||
const result = treeSet.getChildren(node);
|
const result = treeSet.getChildren(node);
|
||||||
result.sort((a, b) => a.getOrder() - b.getOrder());
|
result.sort((a, b) => a.getOrder() - b.getOrder());
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
_getRelativeDirection(reference, position) {
|
_getRelativeDirection(reference, position) {
|
||||||
const offset = position.x - reference.x;
|
const offset = position.x - reference.x;
|
||||||
return offset >= 0 ? 1 : -1;
|
return offset >= 0 ? 1 : -1;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable class-methods-use-this */
|
||||||
/*
|
/*
|
||||||
* Copyright [2015] [wisemapping]
|
* Copyright [2015] [wisemapping]
|
||||||
*
|
*
|
||||||
@ -18,16 +19,13 @@
|
|||||||
import { $assert, $defined } from '@wisemapping/core-js';
|
import { $assert, $defined } from '@wisemapping/core-js';
|
||||||
import AbstractBasicSorter from './AbstractBasicSorter';
|
import AbstractBasicSorter from './AbstractBasicSorter';
|
||||||
|
|
||||||
const BalancedSorter = new Class(
|
class BalancedSorter extends AbstractBasicSorter {
|
||||||
/** @lends BalancedSorter */ {
|
/** @lends BalancedSorter */
|
||||||
Extends: AbstractBasicSorter,
|
/**
|
||||||
/**
|
|
||||||
* @constructs
|
* @constructs
|
||||||
* @extends mindplot.layout.AbstractBasicSorter
|
* @extends mindplot.layout.AbstractBasicSorter
|
||||||
*/
|
*/
|
||||||
initialize() { },
|
/**
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {} graph
|
* @param {} graph
|
||||||
* @param {} parent
|
* @param {} parent
|
||||||
* @param {} node
|
* @param {} node
|
||||||
@ -35,284 +33,283 @@ const BalancedSorter = new Class(
|
|||||||
* @param {Boolean} free
|
* @param {Boolean} free
|
||||||
* @return an array with order and position
|
* @return an array with order and position
|
||||||
*/
|
*/
|
||||||
predict(graph, parent, node, position, free) {
|
predict(graph, parent, node, position, free) {
|
||||||
// If its a free node...
|
// If its a free node...
|
||||||
if (free) {
|
if (free) {
|
||||||
$assert(
|
$assert(
|
||||||
$defined(position),
|
$defined(position),
|
||||||
'position cannot be null for predict in free positioning',
|
'position cannot be null for predict in free positioning',
|
||||||
);
|
);
|
||||||
$assert($defined(node), 'node 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 rootNode = graph.getRootNode(parent);
|
||||||
var direction = this._getRelativeDirection(
|
var direction = this._getRelativeDirection(
|
||||||
rootNode.getPosition(),
|
rootNode.getPosition(),
|
||||||
node.getPosition(),
|
node.getPosition(),
|
||||||
);
|
);
|
||||||
|
|
||||||
const limitXPos = parent.getPosition().x
|
const limitXPos = parent.getPosition().x
|
||||||
+ direction
|
+ direction
|
||||||
* (parent.getSize().width / 2
|
* (parent.getSize().width / 2
|
||||||
+ node.getSize().width / 2
|
+ node.getSize().width / 2
|
||||||
+ BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
+ BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||||
|
|
||||||
const xPos = direction > 0
|
const xPos = direction > 0
|
||||||
? position.x >= limitXPos
|
? position.x >= limitXPos
|
||||||
? position.x
|
? position.x
|
||||||
: limitXPos
|
: limitXPos
|
||||||
: position.x <= limitXPos
|
: position.x <= limitXPos
|
||||||
? position.x
|
? position.x
|
||||||
: limitXPos;
|
: limitXPos;
|
||||||
|
|
||||||
return [0, { x: xPos, y: position.y }];
|
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');
|
||||||
|
const nodeDirection = this._getRelativeDirection(
|
||||||
|
rootNode.getPosition(),
|
||||||
|
node.getPosition(),
|
||||||
|
);
|
||||||
|
const positionDirection = this._getRelativeDirection(
|
||||||
|
rootNode.getPosition(),
|
||||||
|
position,
|
||||||
|
);
|
||||||
|
const siblings = graph.getSiblings(node);
|
||||||
|
|
||||||
|
const sameParent = parent == graph.getParent(node);
|
||||||
|
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
||||||
|
return [node.getOrder(), node.getPosition()];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var rootNode = graph.getRootNode(parent);
|
if (!position) {
|
||||||
|
var right = this._getChildrenForOrder(parent, graph, 0);
|
||||||
|
var left = this._getChildrenForOrder(parent, graph, 1);
|
||||||
|
}
|
||||||
|
// Filter nodes on one side..
|
||||||
|
const order = position
|
||||||
|
? position.x > rootNode.getPosition().x
|
||||||
|
? 0
|
||||||
|
: 1
|
||||||
|
: right.length - left.length > 0
|
||||||
|
? 1
|
||||||
|
: 0;
|
||||||
|
var direction = order % 2 == 0 ? 1 : -1;
|
||||||
|
|
||||||
// If it is a dragged node...
|
// Exclude the dragged node (if set)
|
||||||
if (node) {
|
const children = this._getChildrenForOrder(parent, graph, order).filter((child) => child != node);
|
||||||
$assert($defined(position), 'position cannot be null for predict in dragging');
|
|
||||||
const nodeDirection = this._getRelativeDirection(
|
|
||||||
rootNode.getPosition(),
|
|
||||||
node.getPosition(),
|
|
||||||
);
|
|
||||||
const positionDirection = this._getRelativeDirection(
|
|
||||||
rootNode.getPosition(),
|
|
||||||
position,
|
|
||||||
);
|
|
||||||
const siblings = graph.getSiblings(node);
|
|
||||||
|
|
||||||
const sameParent = parent == graph.getParent(node);
|
// No children?
|
||||||
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
if (children.length == 0) {
|
||||||
return [node.getOrder(), node.getPosition()];
|
return [
|
||||||
}
|
order,
|
||||||
}
|
{
|
||||||
|
x:
|
||||||
if (!position) {
|
|
||||||
var right = this._getChildrenForOrder(parent, graph, 0);
|
|
||||||
var left = this._getChildrenForOrder(parent, graph, 1);
|
|
||||||
}
|
|
||||||
// Filter nodes on one side..
|
|
||||||
const 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)
|
|
||||||
const children = this._getChildrenForOrder(parent, graph, order).filter((child) => child != node);
|
|
||||||
|
|
||||||
// No children?
|
|
||||||
if (children.length == 0) {
|
|
||||||
return [
|
|
||||||
order,
|
|
||||||
{
|
|
||||||
x:
|
|
||||||
parent.getPosition().x
|
parent.getPosition().x
|
||||||
+ direction
|
+ direction
|
||||||
* (parent.getSize().width / 2
|
* (parent.getSize().width / 2
|
||||||
+ BalancedSorter.INTERNODE_HORIZONTAL_PADDING * 2),
|
+ BalancedSorter.INTERNODE_HORIZONTAL_PADDING * 2),
|
||||||
y: parent.getPosition().y,
|
y: parent.getPosition().y,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to fit within ...
|
||||||
|
let result = null;
|
||||||
|
const last = children.getLast();
|
||||||
|
position = position || { x: last.getPosition().x, y: last.getPosition().y + 1 };
|
||||||
|
children.forEach((child, index) => {
|
||||||
|
const cpos = child.getPosition();
|
||||||
|
if (position.y > cpos.y) {
|
||||||
|
const 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 }];
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Try to fit within ...
|
// Position wasn't below any node, so it must be inserted above
|
||||||
let result = null;
|
if (!result) {
|
||||||
const last = children.getLast();
|
const first = children[0];
|
||||||
position = position || { x: last.getPosition().x, y: last.getPosition().y + 1 };
|
result = [
|
||||||
children.forEach((child, index) => {
|
position.x > 0 ? 0 : 1,
|
||||||
const cpos = child.getPosition();
|
{
|
||||||
if (position.y > cpos.y) {
|
x: first.getPosition().x,
|
||||||
const yOffset = child == last
|
y:
|
||||||
? 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) {
|
|
||||||
const first = children[0];
|
|
||||||
result = [
|
|
||||||
position.x > 0 ? 0 : 1,
|
|
||||||
{
|
|
||||||
x: first.getPosition().x,
|
|
||||||
y:
|
|
||||||
first.getPosition().y
|
first.getPosition().y
|
||||||
- first.getSize().height
|
- first.getSize().height
|
||||||
- BalancedSorter.INTERNODE_VERTICAL_PADDING * 2,
|
- BalancedSorter.INTERNODE_VERTICAL_PADDING * 2,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} parent
|
* @param {} parent
|
||||||
* @param {} child
|
* @param {} child
|
||||||
* @param {} order
|
* @param {} order
|
||||||
*/
|
*/
|
||||||
insert(treeSet, parent, child, order) {
|
insert(treeSet, parent, child, order) {
|
||||||
const children = this._getChildrenForOrder(parent, treeSet, order);
|
const children = this._getChildrenForOrder(parent, treeSet, order);
|
||||||
|
|
||||||
// If no children, return 0 or 1 depending on the side
|
// If no children, return 0 or 1 depending on the side
|
||||||
if (children.length == 0) {
|
if (children.length == 0) {
|
||||||
child.setOrder(order % 2);
|
child.setOrder(order % 2);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift all the elements by two, so side is the same.
|
||||||
|
// In case of balanced sorter, order don't need to be continuous...
|
||||||
|
let max = 0;
|
||||||
|
for (let i = 0; i < children.length; i++) {
|
||||||
|
const 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);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Shift all the elements by two, so side is the same.
|
const newOrder = order > max + 1 ? max + 2 : order;
|
||||||
// In case of balanced sorter, order don't need to be continuous...
|
child.setOrder(newOrder);
|
||||||
let max = 0;
|
}
|
||||||
for (let i = 0; i < children.length; i++) {
|
|
||||||
const 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const newOrder = order > max + 1 ? max + 2 : order;
|
/**
|
||||||
child.setOrder(newOrder);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} node
|
* @param {} node
|
||||||
*/
|
*/
|
||||||
detach(treeSet, node) {
|
detach(treeSet, node) {
|
||||||
const parent = treeSet.getParent(node);
|
const parent = treeSet.getParent(node);
|
||||||
// Filter nodes on one side..
|
// Filter nodes on one side..
|
||||||
const children = this._getChildrenForOrder(parent, treeSet, node.getOrder());
|
const children = this._getChildrenForOrder(parent, treeSet, node.getOrder());
|
||||||
|
|
||||||
children.forEach((child) => {
|
children.forEach((child) => {
|
||||||
if (child.getOrder() > node.getOrder()) {
|
if (child.getOrder() > node.getOrder()) {
|
||||||
child.setOrder(child.getOrder() - 2);
|
child.setOrder(child.getOrder() - 2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
node.setOrder(node.getOrder() % 2 == 0 ? 0 : 1);
|
node.setOrder(node.getOrder() % 2 == 0 ? 0 : 1);
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} node
|
* @param {} node
|
||||||
* @return offsets
|
* @return offsets
|
||||||
*/
|
*/
|
||||||
computeOffsets(treeSet, node) {
|
computeOffsets(treeSet, node) {
|
||||||
$assert(treeSet, 'treeSet can no be null.');
|
$assert(treeSet, 'treeSet can no be null.');
|
||||||
$assert(node, 'node can no be null.');
|
$assert(node, 'node can no be null.');
|
||||||
|
|
||||||
const children = this._getSortedChildren(treeSet, node);
|
const children = this._getSortedChildren(treeSet, node);
|
||||||
|
|
||||||
// Compute heights ...
|
// Compute heights ...
|
||||||
const heights = children
|
const heights = children
|
||||||
.map(function (child) {
|
.map(function (child) {
|
||||||
return {
|
return {
|
||||||
id: child.getId(),
|
id: child.getId(),
|
||||||
order: child.getOrder(),
|
order: child.getOrder(),
|
||||||
width: child.getSize().width,
|
width: child.getSize().width,
|
||||||
height: this._computeChildrenHeight(treeSet, child),
|
height: this._computeChildrenHeight(treeSet, child),
|
||||||
};
|
};
|
||||||
}, this)
|
}, this)
|
||||||
.reverse();
|
.reverse();
|
||||||
|
|
||||||
// Compute the center of the branch ...
|
// Compute the center of the branch ...
|
||||||
let totalPHeight = 0;
|
let totalPHeight = 0;
|
||||||
let totalNHeight = 0;
|
let totalNHeight = 0;
|
||||||
|
|
||||||
heights.forEach((elem) => {
|
heights.forEach((elem) => {
|
||||||
if (elem.order % 2 === 0) {
|
if (elem.order % 2 === 0) {
|
||||||
totalPHeight += elem.height;
|
totalPHeight += elem.height;
|
||||||
} else {
|
} else {
|
||||||
totalNHeight += elem.height;
|
totalNHeight += elem.height;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let psum = totalPHeight / 2;
|
let psum = totalPHeight / 2;
|
||||||
let nsum = totalNHeight / 2;
|
let nsum = totalNHeight / 2;
|
||||||
let ysum = 0;
|
let ysum = 0;
|
||||||
|
|
||||||
// Calculate the offsets ...
|
// Calculate the offsets ...
|
||||||
const result = {};
|
const result = {};
|
||||||
for (let i = 0; i < heights.length; i++) {
|
for (let i = 0; i < heights.length; i++) {
|
||||||
const direction = heights[i].order % 2 ? -1 : 1;
|
const direction = heights[i].order % 2 ? -1 : 1;
|
||||||
|
|
||||||
if (direction > 0) {
|
if (direction > 0) {
|
||||||
psum -= heights[i].height;
|
psum -= heights[i].height;
|
||||||
ysum = psum;
|
ysum = psum;
|
||||||
} else {
|
} else {
|
||||||
nsum -= heights[i].height;
|
nsum -= heights[i].height;
|
||||||
ysum = nsum;
|
ysum = nsum;
|
||||||
}
|
}
|
||||||
|
|
||||||
const yOffset = ysum + heights[i].height / 2;
|
const yOffset = ysum + heights[i].height / 2;
|
||||||
const xOffset = direction
|
const xOffset = direction
|
||||||
* (node.getSize().width / 2
|
* (node.getSize().width / 2
|
||||||
+ heights[i].width / 2
|
+ heights[i].width / 2
|
||||||
+ +BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
+ +BalancedSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||||
|
|
||||||
$assert(!isNaN(xOffset), 'xOffset can not be null');
|
$assert(!isNaN(xOffset), 'xOffset can not be null');
|
||||||
$assert(!isNaN(yOffset), 'yOffset can not be null');
|
$assert(!isNaN(yOffset), 'yOffset can not be null');
|
||||||
|
|
||||||
result[heights[i].id] = { x: xOffset, y: yOffset };
|
result[heights[i].id] = { x: xOffset, y: yOffset };
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} node
|
* @param {} node
|
||||||
* @throw will throw an error if order elements are missing
|
* @throw will throw an error if order elements are missing
|
||||||
*/
|
*/
|
||||||
verify(treeSet, node) {
|
verify(treeSet, node) {
|
||||||
// Check that all is consistent ...
|
// Check that all is consistent ...
|
||||||
const children = this._getChildrenForOrder(node, treeSet, node.getOrder());
|
const children = this._getChildrenForOrder(node, treeSet, node.getOrder());
|
||||||
|
|
||||||
// All odd ordered nodes should be "continuous" by themselves
|
// All odd ordered nodes should be "continuous" by themselves
|
||||||
// All even numbered nodes should be "continuous" by themselves
|
// All even numbered nodes should be "continuous" by themselves
|
||||||
const factor = node.getOrder() % 2 == 0 ? 2 : 1;
|
const factor = node.getOrder() % 2 == 0 ? 2 : 1;
|
||||||
for (let i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
const order = i == 0 && factor == 1 ? 1 : factor * i;
|
const order = i == 0 && factor == 1 ? 1 : factor * i;
|
||||||
$assert(
|
$assert(
|
||||||
children[i].getOrder() == order,
|
children[i].getOrder() == order,
|
||||||
`Missing order elements. Missing order: ${i * factor
|
`Missing order elements. Missing order: ${i * factor
|
||||||
}. Parent:${node.getId()
|
}. Parent:${node.getId()
|
||||||
},Node:${children[i].getId()}`,
|
},Node:${children[i].getId()}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} child
|
* @param {} child
|
||||||
* @return the direction of the child within the treeSet
|
* @return the direction of the child within the treeSet
|
||||||
*/
|
*/
|
||||||
getChildDirection(treeSet, child) {
|
getChildDirection(treeSet, child) {
|
||||||
return child.getOrder() % 2 == 0 ? 1 : -1;
|
return child.getOrder() % 2 == 0 ? 1 : -1;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {String} the print name of this class
|
* @return {String} the print name of this class
|
||||||
*/
|
*/
|
||||||
toString() {
|
toString() {
|
||||||
return 'Balanced Sorter';
|
return 'Balanced Sorter';
|
||||||
},
|
}
|
||||||
|
|
||||||
_getChildrenForOrder(parent, graph, order) {
|
_getChildrenForOrder(parent, graph, order) {
|
||||||
return this._getSortedChildren(graph, parent).filter((child) => child.getOrder() % 2 == order % 2);
|
return this._getSortedChildren(graph, parent).filter((child) => child.getOrder() % 2 == order % 2);
|
||||||
},
|
}
|
||||||
|
|
||||||
_getVerticalPadding() {
|
_getVerticalPadding() {
|
||||||
return BalancedSorter.INTERNODE_VERTICAL_PADDING;
|
return BalancedSorter.INTERNODE_VERTICAL_PADDING;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable class-methods-use-this */
|
||||||
/*
|
/*
|
||||||
* Copyright [2015] [wisemapping]
|
* Copyright [2015] [wisemapping]
|
||||||
*
|
*
|
||||||
@ -16,54 +17,49 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const ChildrenSorterStrategy = new Class(/** @lends ChildrenSorterStrategy */{
|
class ChildrenSorterStrategy {/** @lends ChildrenSorterStrategy */
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
*/
|
*/
|
||||||
initialize() {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
computeChildrenIdByHeights(treeSet, node) {
|
computeChildrenIdByHeights(treeSet, node) {
|
||||||
throw 'Method must be implemented';
|
throw new Error('Method must be implemented');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
computeOffsets(treeSet, node) {
|
computeOffsets(treeSet, node) {
|
||||||
throw 'Method must be implemented';
|
throw new Error('Method must be implemented');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
insert(treeSet, parent, child, order) {
|
insert(treeSet, parent, child, order) {
|
||||||
throw 'Method must be implemented';
|
throw new Error('Method must be implemented');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
detach(treeSet, node) {
|
detach(treeSet, node) {
|
||||||
throw 'Method must be implemented';
|
throw new Error('Method must be implemented');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
predict(treeSet, parent, node, position, free) {
|
predict(treeSet, parent, node, position, free) {
|
||||||
throw 'Method must be implemented';
|
throw new Error('Method must be implemented');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
verify(treeSet, node) {
|
verify(treeSet, node) {
|
||||||
throw 'Method must be implemented';
|
throw new Error('Method must be implemented');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
getChildDirection(treeSet, node) {
|
getChildDirection(treeSet, node) {
|
||||||
throw 'Method must be implemented';
|
throw new Error('Method must be implemented');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** @abstract */
|
/** @abstract */
|
||||||
toString() {
|
toString() {
|
||||||
throw 'Method must be implemented: print name';
|
throw new Error('Method must be implemented: print name');
|
||||||
},
|
}
|
||||||
|
}
|
||||||
});
|
|
||||||
|
|
||||||
export default ChildrenSorterStrategy;
|
export default ChildrenSorterStrategy;
|
||||||
|
@ -17,20 +17,20 @@
|
|||||||
*/
|
*/
|
||||||
import EventBus from './EventBus';
|
import EventBus from './EventBus';
|
||||||
|
|
||||||
const EventBusDispatcher = new Class(/** @lends EventBusDispatcher */{
|
class EventBusDispatcher {/** @lends EventBusDispatcher */
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
*/
|
*/
|
||||||
initialize() {
|
constructor() {
|
||||||
this.registerBusEvents();
|
this.registerBusEvents();
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {mindplot.layout.LayoutManager} layoutManager
|
* @param {mindplot.layout.LayoutManager} layoutManager
|
||||||
*/
|
*/
|
||||||
setLayoutManager(layoutManager) {
|
setLayoutManager(layoutManager) {
|
||||||
this._layoutManager = layoutManager;
|
this._layoutManager = layoutManager;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* register bus events
|
* register bus events
|
||||||
@ -44,27 +44,27 @@ const EventBusDispatcher = new Class(/** @lends EventBusDispatcher */{
|
|||||||
EventBus.instance.addEvent(EventBus.events.NodeConnectEvent, this._nodeConnectEvent.bind(this));
|
EventBus.instance.addEvent(EventBus.events.NodeConnectEvent, this._nodeConnectEvent.bind(this));
|
||||||
EventBus.instance.addEvent(EventBus.events.NodeShrinkEvent, this._nodeShrinkEvent.bind(this));
|
EventBus.instance.addEvent(EventBus.events.NodeShrinkEvent, this._nodeShrinkEvent.bind(this));
|
||||||
EventBus.instance.addEvent(EventBus.events.DoLayout, this._doLayout.bind(this));
|
EventBus.instance.addEvent(EventBus.events.DoLayout, this._doLayout.bind(this));
|
||||||
},
|
}
|
||||||
|
|
||||||
_nodeResizeEvent(args) {
|
_nodeResizeEvent(args) {
|
||||||
this._layoutManager.updateNodeSize(args.node.getId(), args.size);
|
this._layoutManager.updateNodeSize(args.node.getId(), args.size);
|
||||||
},
|
}
|
||||||
|
|
||||||
_nodeMoveEvent(args) {
|
_nodeMoveEvent(args) {
|
||||||
this._layoutManager.moveNode(args.node.getId(), args.position);
|
this._layoutManager.moveNode(args.node.getId(), args.position);
|
||||||
},
|
}
|
||||||
|
|
||||||
_nodeDisconnectEvent(node) {
|
_nodeDisconnectEvent(node) {
|
||||||
this._layoutManager.disconnectNode(node.getId());
|
this._layoutManager.disconnectNode(node.getId());
|
||||||
},
|
}
|
||||||
|
|
||||||
_nodeConnectEvent(args) {
|
_nodeConnectEvent(args) {
|
||||||
this._layoutManager.connectNode(args.parentNode.getId(), args.childNode.getId(), args.childNode.getOrder());
|
this._layoutManager.connectNode(args.parentNode.getId(), args.childNode.getId(), args.childNode.getOrder());
|
||||||
},
|
}
|
||||||
|
|
||||||
_nodeShrinkEvent(node) {
|
_nodeShrinkEvent(node) {
|
||||||
this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken());
|
this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken());
|
||||||
},
|
}
|
||||||
|
|
||||||
_nodeAdded(node) {
|
_nodeAdded(node) {
|
||||||
// Central topic must not be added twice ...
|
// Central topic must not be added twice ...
|
||||||
@ -72,11 +72,11 @@ const EventBusDispatcher = new Class(/** @lends EventBusDispatcher */{
|
|||||||
this._layoutManager.addNode(node.getId(), { width: 10, height: 10 }, node.getPosition());
|
this._layoutManager.addNode(node.getId(), { width: 10, height: 10 }, node.getPosition());
|
||||||
this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken());
|
this._layoutManager.updateShrinkState(node.getId(), node.areChildrenShrunken());
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
_nodeRemoved(node) {
|
_nodeRemoved(node) {
|
||||||
this._layoutManager.removeNode(node.getId());
|
this._layoutManager.removeNode(node.getId());
|
||||||
},
|
}
|
||||||
|
|
||||||
_doLayout() {
|
_doLayout() {
|
||||||
// (function() {
|
// (function() {
|
||||||
@ -86,13 +86,12 @@ const EventBusDispatcher = new Class(/** @lends EventBusDispatcher */{
|
|||||||
// console.log("---------");
|
// console.log("---------");
|
||||||
// console.log("---------");
|
// console.log("---------");
|
||||||
// }).delay(0, this);
|
// }).delay(0, this);
|
||||||
},
|
}
|
||||||
|
|
||||||
/** @return layout manager */
|
/** @return layout manager */
|
||||||
getLayoutManager() {
|
getLayoutManager() {
|
||||||
return this._layoutManager;
|
return this._layoutManager;
|
||||||
},
|
}
|
||||||
|
}
|
||||||
});
|
|
||||||
|
|
||||||
export default EventBusDispatcher;
|
export default EventBusDispatcher;
|
||||||
|
@ -22,9 +22,7 @@ import AbstractBasicSorter from './AbstractBasicSorter';
|
|||||||
* @class
|
* @class
|
||||||
* @extends mindplot.layout.AbstractBasicSorter
|
* @extends mindplot.layout.AbstractBasicSorter
|
||||||
*/
|
*/
|
||||||
const GridSorter = new Class(/** @lends GridSorter */{
|
class GridSorter extends AbstractBasicSorter {/** @lends GridSorter */
|
||||||
Extends: AbstractBasicSorter,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {} treeSet
|
* @param {} treeSet
|
||||||
* @param {} node
|
* @param {} node
|
||||||
@ -59,22 +57,21 @@ const GridSorter = new Class(/** @lends GridSorter */{
|
|||||||
const yOffset = zeroHeight + middleHeight + finalHeight;
|
const yOffset = zeroHeight + middleHeight + finalHeight;
|
||||||
const xOffset = node.getSize().width + GridSorter.GRID_HORIZONTAR_SIZE;
|
const xOffset = node.getSize().width + GridSorter.GRID_HORIZONTAR_SIZE;
|
||||||
|
|
||||||
$assert(!isNaN(xOffset), 'xOffset can not be null');
|
$assert(!Number.isNaN(xOffset), 'xOffset can not be null');
|
||||||
$assert(!isNaN(yOffset), 'yOffset can not be null');
|
$assert(!Number.isNaN(yOffset), 'yOffset can not be null');
|
||||||
|
|
||||||
result[heights[i].id] = { x: xOffset, y: yOffset };
|
result[heights[i].id] = { x: xOffset, y: yOffset };
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return {String} the print name of this class
|
* @return {String} the print name of this class
|
||||||
*/
|
*/
|
||||||
toString() {
|
toString() {
|
||||||
return 'Grid Sorter';
|
return 'Grid Sorter';
|
||||||
},
|
}
|
||||||
|
}
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
|
@ -17,9 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
import { $assert, $defined } from '@wisemapping/core-js';
|
import { $assert, $defined } from '@wisemapping/core-js';
|
||||||
|
|
||||||
const Node = new Class(
|
class Node {
|
||||||
/** @lends Node */ {
|
/** @lends Node */
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param id
|
* @param id
|
||||||
* @param size
|
* @param size
|
||||||
@ -30,220 +30,220 @@ const Node = new Class(
|
|||||||
* @throws will throw an error if position 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
|
* @throws will throw an error if sorter is null or undefined
|
||||||
*/
|
*/
|
||||||
initialize(id, size, position, sorter) {
|
constructor(id, size, position, sorter) {
|
||||||
$assert(typeof id === 'number' && Number.isFinite(id), 'id can not be null');
|
$assert(typeof id === 'number' && Number.isFinite(id), 'id can not be null');
|
||||||
$assert(size, 'size can not be null');
|
$assert(size, 'size can not be null');
|
||||||
$assert(position, 'position can not be null');
|
$assert(position, 'position can not be null');
|
||||||
$assert(sorter, 'sorter can not be null');
|
$assert(sorter, 'sorter can not be null');
|
||||||
|
|
||||||
this._id = id;
|
this._id = id;
|
||||||
this._sorter = sorter;
|
this._sorter = sorter;
|
||||||
this._properties = {};
|
this._properties = {};
|
||||||
|
|
||||||
this.setSize(size);
|
this.setSize(size);
|
||||||
this.setPosition(position);
|
this.setPosition(position);
|
||||||
this.setShrunken(false);
|
this.setShrunken(false);
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getId() {
|
getId() {
|
||||||
return this._id;
|
return this._id;
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setFree(value) {
|
setFree(value) {
|
||||||
this._setProperty('free', value);
|
this._setProperty('free', value);
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
isFree() {
|
isFree() {
|
||||||
return this._getProperty('free');
|
return this._getProperty('free');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
hasFreeChanged() {
|
hasFreeChanged() {
|
||||||
return this._isPropertyChanged('free');
|
return this._isPropertyChanged('free');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
hasFreeDisplacementChanged() {
|
hasFreeDisplacementChanged() {
|
||||||
return this._isPropertyChanged('freeDisplacement');
|
return this._isPropertyChanged('freeDisplacement');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setShrunken(value) {
|
setShrunken(value) {
|
||||||
this._setProperty('shrink', value);
|
this._setProperty('shrink', value);
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
areChildrenShrunken() {
|
areChildrenShrunken() {
|
||||||
return this._getProperty('shrink');
|
return this._getProperty('shrink');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setOrder(order) {
|
setOrder(order) {
|
||||||
$assert(
|
$assert(
|
||||||
typeof order === 'number' && Number.isFinite(order),
|
typeof order === 'number' && Number.isFinite(order),
|
||||||
`Order can not be null. Value:${order}`,
|
`Order can not be null. Value:${order}`,
|
||||||
);
|
);
|
||||||
this._setProperty('order', order);
|
this._setProperty('order', order);
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
resetPositionState() {
|
resetPositionState() {
|
||||||
const prop = this._properties.position;
|
const prop = this._properties.position;
|
||||||
if (prop) {
|
if (prop) {
|
||||||
prop.hasChanged = false;
|
prop.hasChanged = false;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
resetOrderState() {
|
resetOrderState() {
|
||||||
const prop = this._properties.order;
|
const prop = this._properties.order;
|
||||||
if (prop) {
|
if (prop) {
|
||||||
prop.hasChanged = false;
|
prop.hasChanged = false;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
resetFreeState() {
|
resetFreeState() {
|
||||||
const prop = this._properties.freeDisplacement;
|
const prop = this._properties.freeDisplacement;
|
||||||
if (prop) {
|
if (prop) {
|
||||||
prop.hasChanged = false;
|
prop.hasChanged = false;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getOrder() {
|
getOrder() {
|
||||||
return this._getProperty('order');
|
return this._getProperty('order');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
hasOrderChanged() {
|
hasOrderChanged() {
|
||||||
return this._isPropertyChanged('order');
|
return this._isPropertyChanged('order');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
hasPositionChanged() {
|
hasPositionChanged() {
|
||||||
return this._isPropertyChanged('position');
|
return this._isPropertyChanged('position');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
hasSizeChanged() {
|
hasSizeChanged() {
|
||||||
return this._isPropertyChanged('size');
|
return this._isPropertyChanged('size');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getPosition() {
|
getPosition() {
|
||||||
return this._getProperty('position');
|
return this._getProperty('position');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setSize(size) {
|
setSize(size) {
|
||||||
$assert($defined(size), 'Size can not be null');
|
$assert($defined(size), 'Size can not be null');
|
||||||
this._setProperty('size', Object.clone(size));
|
this._setProperty('size', Object.clone(size));
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getSize() {
|
getSize() {
|
||||||
return this._getProperty('size');
|
return this._getProperty('size');
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setFreeDisplacement(displacement) {
|
setFreeDisplacement(displacement) {
|
||||||
$assert($defined(displacement), 'Position can not be null');
|
$assert($defined(displacement), 'Position can not be null');
|
||||||
$assert($defined(displacement.x), 'x can not be null');
|
$assert($defined(displacement.x), 'x can not be null');
|
||||||
$assert($defined(displacement.y), 'y can not be null');
|
$assert($defined(displacement.y), 'y can not be null');
|
||||||
const oldDisplacement = this.getFreeDisplacement();
|
const oldDisplacement = this.getFreeDisplacement();
|
||||||
const newDisplacement = {
|
const newDisplacement = {
|
||||||
x: oldDisplacement.x + displacement.x,
|
x: oldDisplacement.x + displacement.x,
|
||||||
y: oldDisplacement.y + displacement.y,
|
y: oldDisplacement.y + displacement.y,
|
||||||
};
|
};
|
||||||
|
|
||||||
this._setProperty('freeDisplacement', Object.clone(newDisplacement));
|
this._setProperty('freeDisplacement', Object.clone(newDisplacement));
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
resetFreeDisplacement() {
|
resetFreeDisplacement() {
|
||||||
this._setProperty('freeDisplacement', { x: 0, y: 0 });
|
this._setProperty('freeDisplacement', { x: 0, y: 0 });
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getFreeDisplacement() {
|
getFreeDisplacement() {
|
||||||
const freeDisplacement = this._getProperty('freeDisplacement');
|
const freeDisplacement = this._getProperty('freeDisplacement');
|
||||||
return freeDisplacement || { x: 0, y: 0 };
|
return freeDisplacement || { x: 0, y: 0 };
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
setPosition(position) {
|
setPosition(position) {
|
||||||
$assert($defined(position), 'Position can not be null');
|
$assert($defined(position), 'Position can not be null');
|
||||||
$assert($defined(position.x), 'x can not be null');
|
$assert($defined(position.x), 'x can not be null');
|
||||||
$assert($defined(position.y), 'y 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.
|
// This is a performance improvement to avoid movements that really could be avoided.
|
||||||
const currentPos = this.getPosition();
|
const currentPos = this.getPosition();
|
||||||
if (
|
if (
|
||||||
currentPos == null
|
currentPos == null
|
||||||
|| Math.abs(currentPos.x - position.x) > 2
|
|| Math.abs(currentPos.x - position.x) > 2
|
||||||
|| Math.abs(currentPos.y - position.y) > 2
|
|| Math.abs(currentPos.y - position.y) > 2
|
||||||
) this._setProperty('position', position);
|
) this._setProperty('position', position);
|
||||||
},
|
}
|
||||||
|
|
||||||
_setProperty(key, value) {
|
_setProperty(key, value) {
|
||||||
let prop = this._properties[key];
|
let prop = this._properties[key];
|
||||||
if (!prop) {
|
if (!prop) {
|
||||||
prop = {
|
prop = {
|
||||||
hasChanged: false,
|
hasChanged: false,
|
||||||
value: null,
|
value: null,
|
||||||
oldValue: null,
|
oldValue: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only update if the property has changed ...
|
// Only update if the property has changed ...
|
||||||
if (JSON.stringify(prop.value) !== JSON.stringify(value)) {
|
if (JSON.stringify(prop.value) !== JSON.stringify(value)) {
|
||||||
prop.oldValue = prop.value;
|
prop.oldValue = prop.value;
|
||||||
prop.value = value;
|
prop.value = value;
|
||||||
prop.hasChanged = true;
|
prop.hasChanged = true;
|
||||||
}
|
}
|
||||||
this._properties[key] = prop;
|
this._properties[key] = prop;
|
||||||
},
|
}
|
||||||
|
|
||||||
_getProperty(key) {
|
_getProperty(key) {
|
||||||
const prop = this._properties[key];
|
const prop = this._properties[key];
|
||||||
return $defined(prop) ? prop.value : null;
|
return $defined(prop) ? prop.value : null;
|
||||||
},
|
}
|
||||||
|
|
||||||
_isPropertyChanged(key) {
|
_isPropertyChanged(key) {
|
||||||
const prop = this._properties[key];
|
const prop = this._properties[key];
|
||||||
return prop ? prop.hasChanged : false;
|
return prop ? prop.hasChanged : false;
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
getSorter() {
|
getSorter() {
|
||||||
return this._sorter;
|
return this._sorter;
|
||||||
},
|
}
|
||||||
|
|
||||||
|
/** @return {String} returns id, order, position, size and shrink information */
|
||||||
|
toString() {
|
||||||
|
return (
|
||||||
|
`[id:${
|
||||||
|
this.getId()
|
||||||
|
}, order:${
|
||||||
|
this.getOrder()
|
||||||
|
}, position: {${
|
||||||
|
this.getPosition().x
|
||||||
|
},${
|
||||||
|
this.getPosition().y
|
||||||
|
}}, size: {${
|
||||||
|
this.getSize().width
|
||||||
|
},${
|
||||||
|
this.getSize().height
|
||||||
|
}}, shrink:${
|
||||||
|
this.areChildrenShrunken()
|
||||||
|
}]`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {String} returns id, order, position, size and shrink information */
|
|
||||||
toString() {
|
|
||||||
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;
|
export default Node;
|
||||||
|
@ -17,438 +17,437 @@
|
|||||||
*/
|
*/
|
||||||
import { $assert, $defined } from '@wisemapping/core-js';
|
import { $assert, $defined } from '@wisemapping/core-js';
|
||||||
|
|
||||||
const RootedTreeSet = new Class(
|
class RootedTreeSet {
|
||||||
/** @lends RootedTreeSet */ {
|
/** @lends RootedTreeSet */
|
||||||
/** @constructs */
|
/** @constructs */
|
||||||
initialize() {
|
constructor() {
|
||||||
this._rootNodes = [];
|
this._rootNodes = [];
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param root
|
* @param root
|
||||||
* @throws will throw an error if root is null or undefined
|
* @throws will throw an error if root is null or undefined
|
||||||
*/
|
*/
|
||||||
setRoot(root) {
|
setRoot(root) {
|
||||||
$assert(root, 'root can not be null');
|
$assert(root, 'root can not be null');
|
||||||
this._rootNodes.push(this._decodate(root));
|
this._rootNodes.push(this._decodate(root));
|
||||||
},
|
}
|
||||||
|
|
||||||
/** getter */
|
/** getter */
|
||||||
getTreeRoots() {
|
getTreeRoots() {
|
||||||
return this._rootNodes;
|
return this._rootNodes;
|
||||||
},
|
}
|
||||||
|
|
||||||
_decodate(node) {
|
_decodate(node) {
|
||||||
node._children = [];
|
node._children = [];
|
||||||
return node;
|
return node;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {mindplot.model.NodeModel} node
|
* @param {mindplot.model.NodeModel} node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @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 with id already exists
|
||||||
* @throws will throw an error if node has been added already
|
* @throws will throw an error if node has been added already
|
||||||
*/
|
*/
|
||||||
add(node) {
|
add(node) {
|
||||||
$assert(node, 'node can not be null');
|
$assert(node, 'node can not be null');
|
||||||
$assert(
|
$assert(
|
||||||
!this.find(node.getId(), false),
|
!this.find(node.getId(), false),
|
||||||
`node already exits with this id. Id:${node.getId()}`,
|
`node already exits with this id. Id:${node.getId()}`,
|
||||||
);
|
);
|
||||||
$assert(!node._children, 'node already added');
|
$assert(!node._children, 'node already added');
|
||||||
this._rootNodes.push(this._decodate(node));
|
this._rootNodes.push(this._decodate(node));
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param nodeId
|
* @param nodeId
|
||||||
* @throws will throw an error if nodeId is null or undefined
|
* @throws will throw an error if nodeId is null or undefined
|
||||||
*/
|
*/
|
||||||
remove(nodeId) {
|
remove(nodeId) {
|
||||||
$assert($defined(nodeId), 'nodeId can not be null');
|
$assert($defined(nodeId), 'nodeId can not be null');
|
||||||
const node = this.find(nodeId);
|
const node = this.find(nodeId);
|
||||||
this._rootNodes.erase(node);
|
this._rootNodes.erase(node);
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param parentId
|
* @param parentId
|
||||||
* @param childId
|
* @param childId
|
||||||
* @throws will throw an error if parentId is null or undefined
|
* @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 childId is null or undefined
|
||||||
* @throws will throw an error if node with id childId is already a child of parent
|
* @throws will throw an error if node with id childId is already a child of parent
|
||||||
*/
|
*/
|
||||||
connect(parentId, childId) {
|
connect(parentId, childId) {
|
||||||
$assert($defined(parentId), 'parent can not be null');
|
$assert($defined(parentId), 'parent can not be null');
|
||||||
$assert($defined(childId), 'child can not be null');
|
$assert($defined(childId), 'child can not be null');
|
||||||
|
|
||||||
const parent = this.find(parentId);
|
const parent = this.find(parentId);
|
||||||
const child = this.find(childId, true);
|
const child = this.find(childId, true);
|
||||||
$assert(
|
$assert(
|
||||||
!child._parent,
|
!child._parent,
|
||||||
`node already connected. Id:${child.getId()},previous:${child._parent}`,
|
`node already connected. Id:${child.getId()},previous:${child._parent}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
parent._children.push(child);
|
parent._children.push(child);
|
||||||
child._parent = parent;
|
child._parent = parent;
|
||||||
this._rootNodes.erase(child);
|
this._rootNodes.erase(child);
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param nodeId
|
* @param nodeId
|
||||||
* @throws will throw an error if nodeId is null or undefined
|
* @throws will throw an error if nodeId is null or undefined
|
||||||
* @throws will throw an error if node is not connected
|
* @throws will throw an error if node is not connected
|
||||||
*/
|
*/
|
||||||
disconnect(nodeId) {
|
disconnect(nodeId) {
|
||||||
$assert($defined(nodeId), 'nodeId can not be null');
|
$assert($defined(nodeId), 'nodeId can not be null');
|
||||||
const node = this.find(nodeId);
|
const node = this.find(nodeId);
|
||||||
$assert(node._parent, 'Node is not connected');
|
$assert(node._parent, 'Node is not connected');
|
||||||
|
|
||||||
node._parent._children.erase(node);
|
node._parent._children.erase(node);
|
||||||
this._rootNodes.push(node);
|
this._rootNodes.push(node);
|
||||||
node._parent = null;
|
node._parent = null;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param id
|
* @param id
|
||||||
* @param validate
|
* @param validate
|
||||||
* @throws will throw an error if id is null or undefined
|
* @throws will throw an error if id is null or undefined
|
||||||
* @throws will throw an error if node cannot be found
|
* @throws will throw an error if node cannot be found
|
||||||
* @return node
|
* @return node
|
||||||
*/
|
*/
|
||||||
find(id, validate) {
|
find(id, validate) {
|
||||||
$assert($defined(id), 'id can not be null');
|
$assert($defined(id), 'id can not be null');
|
||||||
|
|
||||||
const graphs = this._rootNodes;
|
const graphs = this._rootNodes;
|
||||||
let result = null;
|
let result = null;
|
||||||
for (let i = 0; i < graphs.length; i++) {
|
for (let i = 0; i < graphs.length; i++) {
|
||||||
const node = graphs[i];
|
const node = graphs[i];
|
||||||
result = this._find(id, node);
|
result = this._find(id, node);
|
||||||
if (result) {
|
if (result) {
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
validate = !$defined(validate) ? true : validate;
|
}
|
||||||
$assert(
|
validate = !$defined(validate) ? true : validate;
|
||||||
validate ? result : true,
|
$assert(
|
||||||
`node could not be found id:${id}\n,RootedTreeSet${this.dump()}`,
|
validate ? result : true,
|
||||||
);
|
`node could not be found id:${id}\n,RootedTreeSet${this.dump()}`,
|
||||||
return result;
|
);
|
||||||
},
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
_find(id, parent) {
|
_find(id, parent) {
|
||||||
if (parent.getId() === id) {
|
if (parent.getId() === id) {
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = null;
|
let result = null;
|
||||||
const children = parent._children;
|
const children = parent._children;
|
||||||
for (let i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
const child = children[i];
|
const child = children[i];
|
||||||
result = this._find(id, child);
|
result = this._find(id, child);
|
||||||
if (result) break;
|
if (result) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if nodeId is null or undefined
|
* @throws will throw an error if nodeId is null or undefined
|
||||||
* @return children
|
* @return children
|
||||||
*/
|
*/
|
||||||
getChildren(node) {
|
getChildren(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
return node._children;
|
return node._children;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @throws will throw an error if node is null or undefined
|
||||||
* @return root node or the provided node, if it has no parent
|
* @return root node or the provided node, if it has no parent
|
||||||
*/
|
*/
|
||||||
getRootNode(node) {
|
getRootNode(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
const parent = this.getParent(node);
|
const parent = this.getParent(node);
|
||||||
if ($defined(parent)) {
|
if ($defined(parent)) {
|
||||||
return this.getRootNode(parent);
|
return this.getRootNode(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @throws will throw an error if node is null or undefined
|
||||||
* @return {Array} ancestors */
|
* @return {Array} ancestors */
|
||||||
getAncestors(node) {
|
getAncestors(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
return this._getAncestors(this.getParent(node), []);
|
return this._getAncestors(this.getParent(node), []);
|
||||||
},
|
}
|
||||||
|
|
||||||
_getAncestors(node, ancestors) {
|
_getAncestors(node, ancestors) {
|
||||||
const result = ancestors;
|
const result = ancestors;
|
||||||
if (node) {
|
if (node) {
|
||||||
result.push(node);
|
result.push(node);
|
||||||
this._getAncestors(this.getParent(node), result);
|
this._getAncestors(this.getParent(node), result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @throws will throw an error if node is null or undefined
|
||||||
* @return {Array} siblings
|
* @return {Array} siblings
|
||||||
*/
|
*/
|
||||||
getSiblings(node) {
|
getSiblings(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
if (!$defined(node._parent)) {
|
if (!$defined(node._parent)) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const siblings = node._parent._children.filter((child) => child !== node);
|
const siblings = node._parent._children.filter((child) => child !== node);
|
||||||
return siblings;
|
return siblings;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @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)
|
* @return {Boolean} whether the node has a single path to a single leaf (no branching)
|
||||||
*/
|
*/
|
||||||
hasSinglePathToSingleLeaf(node) {
|
hasSinglePathToSingleLeaf(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
return this._hasSinglePathToSingleLeaf(node);
|
return this._hasSinglePathToSingleLeaf(node);
|
||||||
},
|
}
|
||||||
|
|
||||||
_hasSinglePathToSingleLeaf(node) {
|
_hasSinglePathToSingleLeaf(node) {
|
||||||
const children = this.getChildren(node);
|
const children = this.getChildren(node);
|
||||||
|
|
||||||
if (children.length === 1) {
|
if (children.length === 1) {
|
||||||
return this._hasSinglePathToSingleLeaf(children[0]);
|
return this._hasSinglePathToSingleLeaf(children[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return children.length === 0;
|
return children.length === 0;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @return {Boolean} whether the node is the start of a subbranch */
|
* @return {Boolean} whether the node is the start of a subbranch */
|
||||||
isStartOfSubBranch(node) {
|
isStartOfSubBranch(node) {
|
||||||
return this.getSiblings(node).length > 0 && this.getChildren(node).length === 1;
|
return this.getSiblings(node).length > 0 && this.getChildren(node).length === 1;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @throws will throw an error if node is null or undefined
|
||||||
* @return {Boolean} whether the node is a leaf
|
* @return {Boolean} whether the node is a leaf
|
||||||
*/
|
*/
|
||||||
isLeaf(node) {
|
isLeaf(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
return this.getChildren(node).length === 0;
|
return this.getChildren(node).length === 0;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if node is null or undefined
|
* @throws will throw an error if node is null or undefined
|
||||||
* @return parent
|
* @return parent
|
||||||
*/
|
*/
|
||||||
getParent(node) {
|
getParent(node) {
|
||||||
$assert(node, 'node cannot be null');
|
$assert(node, 'node cannot be null');
|
||||||
return node._parent;
|
return node._parent;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return result
|
* @return result
|
||||||
*/
|
*/
|
||||||
dump() {
|
dump() {
|
||||||
const branches = this._rootNodes;
|
const branches = this._rootNodes;
|
||||||
let result = '';
|
let result = '';
|
||||||
for (let i = 0; i < branches.length; i++) {
|
for (let i = 0; i < branches.length; i++) {
|
||||||
const branch = branches[i];
|
const branch = branches[i];
|
||||||
result += this._dump(branch, '');
|
result += this._dump(branch, '');
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
_dump(node, indent) {
|
_dump(node, indent) {
|
||||||
let result = `${indent + node}\n`;
|
let result = `${indent + node}\n`;
|
||||||
const children = this.getChildren(node);
|
const children = this.getChildren(node);
|
||||||
for (let i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
const child = children[i];
|
const child = children[i];
|
||||||
result += this._dump(child, `${indent} `);
|
result += this._dump(child, `${indent} `);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param canvas
|
* @param canvas
|
||||||
*/
|
*/
|
||||||
plot(canvas) {
|
plot(canvas) {
|
||||||
const branches = this._rootNodes;
|
const branches = this._rootNodes;
|
||||||
for (let i = 0; i < branches.length; i++) {
|
for (let i = 0; i < branches.length; i++) {
|
||||||
const branch = branches[i];
|
const branch = branches[i];
|
||||||
this._plot(canvas, branch);
|
this._plot(canvas, branch);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
_plot(canvas, node, root) {
|
_plot(canvas, node, root) {
|
||||||
const children = this.getChildren(node);
|
const children = this.getChildren(node);
|
||||||
const cx = node.getPosition().x + canvas.width / 2 - node.getSize().width / 2;
|
const cx = node.getPosition().x + canvas.width / 2 - node.getSize().width / 2;
|
||||||
const cy = node.getPosition().y + canvas.height / 2 - node.getSize().height / 2;
|
const cy = node.getPosition().y + canvas.height / 2 - node.getSize().height / 2;
|
||||||
const rect = canvas.rect(cx, cy, node.getSize().width, node.getSize().height);
|
const rect = canvas.rect(cx, cy, node.getSize().width, node.getSize().height);
|
||||||
const order = node.getOrder() == null ? 'r' : node.getOrder();
|
const order = node.getOrder() == null ? 'r' : node.getOrder();
|
||||||
const text = canvas.text(
|
const text = canvas.text(
|
||||||
node.getPosition().x + canvas.width / 2,
|
node.getPosition().x + canvas.width / 2,
|
||||||
node.getPosition().y + canvas.height / 2,
|
node.getPosition().y + canvas.height / 2,
|
||||||
`${node.getId()}[${order}]`,
|
`${node.getId()}[${order}]`,
|
||||||
|
);
|
||||||
|
text.attr('fill', '#FFF');
|
||||||
|
const fillColor = this._rootNodes.contains(node)
|
||||||
|
? '#000'
|
||||||
|
: node.isFree()
|
||||||
|
? '#abc'
|
||||||
|
: '#c00';
|
||||||
|
rect.attr('fill', fillColor);
|
||||||
|
|
||||||
|
const rectPosition = {
|
||||||
|
x: rect.attr('x') - canvas.width / 2 + rect.attr('width') / 2,
|
||||||
|
y: rect.attr('y') - canvas.height / 2 + rect.attr('height') / 2,
|
||||||
|
};
|
||||||
|
const rectSize = { width: rect.attr('width'), height: rect.attr('height') };
|
||||||
|
rect.click(() => {
|
||||||
|
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.attr('fill', '#FFF');
|
});
|
||||||
const fillColor = this._rootNodes.contains(node)
|
text.click(() => {
|
||||||
? '#000'
|
console.log(
|
||||||
: node.isFree()
|
`[id:${
|
||||||
? '#abc'
|
node.getId()
|
||||||
: '#c00';
|
}, order:${
|
||||||
rect.attr('fill', fillColor);
|
node.getOrder()
|
||||||
|
}, position:(${
|
||||||
|
rectPosition.x
|
||||||
|
},${
|
||||||
|
rectPosition.y
|
||||||
|
}), size:${
|
||||||
|
rectSize.width
|
||||||
|
}x${
|
||||||
|
rectSize.height
|
||||||
|
}, freeDisplacement:(${
|
||||||
|
node.getFreeDisplacement().x
|
||||||
|
},${
|
||||||
|
node.getFreeDisplacement().y
|
||||||
|
})]`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
const rectPosition = {
|
for (let i = 0; i < children.length; i++) {
|
||||||
x: rect.attr('x') - canvas.width / 2 + rect.attr('width') / 2,
|
const child = children[i];
|
||||||
y: rect.attr('y') - canvas.height / 2 + rect.attr('height') / 2,
|
this._plot(canvas, child);
|
||||||
};
|
}
|
||||||
const rectSize = { width: rect.attr('width'), height: rect.attr('height') };
|
}
|
||||||
rect.click(() => {
|
|
||||||
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(() => {
|
|
||||||
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
|
|
||||||
})]`,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
for (let i = 0; i < children.length; i++) {
|
/**
|
||||||
const child = children[i];
|
|
||||||
this._plot(canvas, child);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param node
|
* @param node
|
||||||
* @param position
|
* @param position
|
||||||
*/
|
*/
|
||||||
updateBranchPosition(node, position) {
|
updateBranchPosition(node, position) {
|
||||||
const oldPos = node.getPosition();
|
const oldPos = node.getPosition();
|
||||||
node.setPosition(position);
|
node.setPosition(position);
|
||||||
|
|
||||||
const xOffset = oldPos.x - position.x;
|
const xOffset = oldPos.x - position.x;
|
||||||
const yOffset = oldPos.y - position.y;
|
const yOffset = oldPos.y - position.y;
|
||||||
|
|
||||||
const children = this.getChildren(node);
|
const children = this.getChildren(node);
|
||||||
const me = this;
|
const me = this;
|
||||||
children.forEach((child) => {
|
children.forEach((child) => {
|
||||||
me.shiftBranchPosition(child, xOffset, yOffset);
|
me.shiftBranchPosition(child, xOffset, yOffset);
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @param xOffset
|
* @param xOffset
|
||||||
* @param yOffset
|
* @param yOffset
|
||||||
*/
|
*/
|
||||||
shiftBranchPosition(node, xOffset, yOffset) {
|
shiftBranchPosition(node, xOffset, yOffset) {
|
||||||
const position = node.getPosition();
|
const position = node.getPosition();
|
||||||
node.setPosition({ x: position.x + xOffset, y: position.y + yOffset });
|
node.setPosition({ x: position.x + xOffset, y: position.y + yOffset });
|
||||||
|
|
||||||
const children = this.getChildren(node);
|
const children = this.getChildren(node);
|
||||||
const me = this;
|
const me = this;
|
||||||
children.forEach((child) => {
|
children.forEach((child) => {
|
||||||
me.shiftBranchPosition(child, xOffset, yOffset);
|
me.shiftBranchPosition(child, xOffset, yOffset);
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @param yOffset
|
* @param yOffset
|
||||||
* @return siblings in the offset (vertical) direction, i.e. with lower or higher order, respectively
|
* @return siblings in the offset (vertical) direction, i.e. with lower or higher order, respectively
|
||||||
*/
|
*/
|
||||||
getSiblingsInVerticalDirection(node, yOffset) {
|
getSiblingsInVerticalDirection(node, yOffset) {
|
||||||
// siblings with lower or higher order, depending on the direction of the offset and on the same side as their parent
|
// siblings with lower or higher order, depending on the direction of the offset and on the same side as their parent
|
||||||
const parent = this.getParent(node);
|
const parent = this.getParent(node);
|
||||||
const siblings = this.getSiblings(node).filter((sibling) => {
|
const siblings = this.getSiblings(node).filter((sibling) => {
|
||||||
const sameSide = node.getPosition().x > parent.getPosition().x
|
const sameSide = node.getPosition().x > parent.getPosition().x
|
||||||
? sibling.getPosition().x > parent.getPosition().x
|
? sibling.getPosition().x > parent.getPosition().x
|
||||||
: sibling.getPosition().x < parent.getPosition().x;
|
: sibling.getPosition().x < parent.getPosition().x;
|
||||||
const orderOK = yOffset < 0
|
const orderOK = yOffset < 0
|
||||||
? sibling.getOrder() < node.getOrder()
|
? sibling.getOrder() < node.getOrder()
|
||||||
: sibling.getOrder() > node.getOrder();
|
: sibling.getOrder() > node.getOrder();
|
||||||
return orderOK && sameSide;
|
return orderOK && sameSide;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (yOffset < 0) {
|
if (yOffset < 0) {
|
||||||
siblings.reverse();
|
siblings.reverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
return siblings;
|
return siblings;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param node
|
* @param node
|
||||||
* @param yOffset
|
* @param yOffset
|
||||||
* @return branches of the root node on the same side as the given node's, in the given
|
* @return branches of the root node on the same side as the given node's, in the given
|
||||||
* vertical direction
|
* vertical direction
|
||||||
*/
|
*/
|
||||||
getBranchesInVerticalDirection(node, yOffset) {
|
getBranchesInVerticalDirection(node, yOffset) {
|
||||||
// direct descendants of the root that do not contain the node and are on the same side
|
// direct descendants of the root that do not contain the node and are on the same side
|
||||||
// and on the direction of the offset
|
// and on the direction of the offset
|
||||||
const rootNode = this.getRootNode(node);
|
const rootNode = this.getRootNode(node);
|
||||||
const branches = this.getChildren(rootNode).filter(((child) => {
|
const branches = this.getChildren(rootNode).filter(((child) => {
|
||||||
return this._find(node.getId(), child);
|
return this._find(node.getId(), child);
|
||||||
}).bind(this));
|
}).bind(this));
|
||||||
|
|
||||||
const branch = branches[0];
|
const branch = branches[0];
|
||||||
const rootDescendants = this.getSiblings(branch).filter((sibling) => {
|
const rootDescendants = this.getSiblings(branch).filter((sibling) => {
|
||||||
const sameSide = node.getPosition().x > rootNode.getPosition().x
|
const sameSide = node.getPosition().x > rootNode.getPosition().x
|
||||||
? sibling.getPosition().x > rootNode.getPosition().x
|
? sibling.getPosition().x > rootNode.getPosition().x
|
||||||
: sibling.getPosition().x < rootNode.getPosition().x;
|
: sibling.getPosition().x < rootNode.getPosition().x;
|
||||||
const sameDirection = yOffset < 0
|
const sameDirection = yOffset < 0
|
||||||
? sibling.getOrder() < branch.getOrder()
|
? sibling.getOrder() < branch.getOrder()
|
||||||
: sibling.getOrder() > branch.getOrder();
|
: sibling.getOrder() > branch.getOrder();
|
||||||
return sameSide && sameDirection;
|
return sameSide && sameDirection;
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
return rootDescendants;
|
return rootDescendants;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
);
|
|
||||||
|
|
||||||
export default RootedTreeSet;
|
export default RootedTreeSet;
|
||||||
|
@ -18,17 +18,10 @@
|
|||||||
import { $assert, $defined } from '@wisemapping/core-js';
|
import { $assert, $defined } from '@wisemapping/core-js';
|
||||||
import AbstractBasicSorter from './AbstractBasicSorter';
|
import AbstractBasicSorter from './AbstractBasicSorter';
|
||||||
|
|
||||||
|
class SymmetricSorter extends AbstractBasicSorter {
|
||||||
|
/** @lends SymmetricSorter */
|
||||||
|
|
||||||
const SymmetricSorter = new Class(
|
/**
|
||||||
/** @lends SymmetricSorter */ {
|
|
||||||
Extends: AbstractBasicSorter,
|
|
||||||
/**
|
|
||||||
* @constructs
|
|
||||||
* @extends mindplot.layout.AbstractBasicSorter
|
|
||||||
*/
|
|
||||||
initialize() {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Predict the order and position of a dragged node.
|
* Predict the order and position of a dragged node.
|
||||||
*
|
*
|
||||||
* @param graph The tree set
|
* @param graph The tree set
|
||||||
@ -38,184 +31,184 @@ const SymmetricSorter = new Class(
|
|||||||
* @param free Free drag or not
|
* @param free Free drag or not
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
predict(graph, parent, node, position, free) {
|
predict(graph, parent, node, position, free) {
|
||||||
const self = this;
|
const self = this;
|
||||||
const rootNode = graph.getRootNode(parent);
|
const rootNode = graph.getRootNode(parent);
|
||||||
|
|
||||||
// If its a free node...
|
// If its a free node...
|
||||||
if (free) {
|
if (free) {
|
||||||
$assert(
|
$assert(
|
||||||
$defined(position),
|
$defined(position),
|
||||||
'position cannot be null for predict in free positioning',
|
'position cannot be null for predict in free positioning',
|
||||||
);
|
);
|
||||||
$assert($defined(node), 'node cannot be null for predict in free positioning');
|
$assert($defined(node), 'node cannot be null for predict in free positioning');
|
||||||
|
|
||||||
const direction = this._getRelativeDirection(
|
const direction = this._getRelativeDirection(
|
||||||
rootNode.getPosition(),
|
rootNode.getPosition(),
|
||||||
parent.getPosition(),
|
parent.getPosition(),
|
||||||
);
|
);
|
||||||
const limitXPos = parent.getPosition().x
|
const limitXPos = parent.getPosition().x
|
||||||
+ direction
|
+ direction
|
||||||
* (parent.getSize().width / 2
|
* (parent.getSize().width / 2
|
||||||
+ node.getSize().width / 2
|
+ node.getSize().width / 2
|
||||||
+ SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
+ SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||||
|
|
||||||
const xPos = direction > 0
|
const xPos = direction > 0
|
||||||
? position.x >= limitXPos
|
? position.x >= limitXPos
|
||||||
? position.x
|
? position.x
|
||||||
: limitXPos
|
: limitXPos
|
||||||
: position.x <= limitXPos
|
: position.x <= limitXPos
|
||||||
? position.x
|
? position.x
|
||||||
: limitXPos;
|
: limitXPos;
|
||||||
|
|
||||||
return [0, { x: xPos, y: position.y }];
|
return [0, { x: xPos, y: position.y }];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Its not a dragged node (it is being added)
|
// Its not a dragged node (it is being added)
|
||||||
if (!node) {
|
if (!node) {
|
||||||
const parentDirection = self._getRelativeDirection(
|
const parentDirection = self._getRelativeDirection(
|
||||||
rootNode.getPosition(),
|
rootNode.getPosition(),
|
||||||
parent.getPosition(),
|
parent.getPosition(),
|
||||||
);
|
);
|
||||||
|
|
||||||
var position = {
|
var position = {
|
||||||
x:
|
x:
|
||||||
parent.getPosition().x
|
parent.getPosition().x
|
||||||
+ parentDirection
|
+ parentDirection
|
||||||
* (parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
* (parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
||||||
y: parent.getPosition().y,
|
y: parent.getPosition().y,
|
||||||
};
|
};
|
||||||
return [graph.getChildren(parent).length, position];
|
return [graph.getChildren(parent).length, position];
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it is a dragged node...
|
// If it is a dragged node...
|
||||||
$assert($defined(position), 'position cannot be null for predict in dragging');
|
$assert($defined(position), 'position cannot be null for predict in dragging');
|
||||||
const nodeDirection = this._getRelativeDirection(
|
const nodeDirection = this._getRelativeDirection(
|
||||||
rootNode.getPosition(),
|
rootNode.getPosition(),
|
||||||
node.getPosition(),
|
node.getPosition(),
|
||||||
);
|
);
|
||||||
const positionDirection = this._getRelativeDirection(rootNode.getPosition(), position);
|
const positionDirection = this._getRelativeDirection(rootNode.getPosition(), position);
|
||||||
const siblings = graph.getSiblings(node);
|
const siblings = graph.getSiblings(node);
|
||||||
|
|
||||||
// node has no siblings and its trying to reconnect to its own parent
|
// node has no siblings and its trying to reconnect to its own parent
|
||||||
const sameParent = parent == graph.getParent(node);
|
const sameParent = parent == graph.getParent(node);
|
||||||
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
if (siblings.length == 0 && nodeDirection == positionDirection && sameParent) {
|
||||||
return [node.getOrder(), node.getPosition()];
|
return [node.getOrder(), node.getPosition()];
|
||||||
}
|
}
|
||||||
|
|
||||||
const parentChildren = graph.getChildren(parent);
|
const parentChildren = graph.getChildren(parent);
|
||||||
|
|
||||||
if (parentChildren.length == 0) {
|
if (parentChildren.length == 0) {
|
||||||
// Fit as a child of the parent node...
|
// Fit as a child of the parent node...
|
||||||
var position = {
|
var position = {
|
||||||
x:
|
x:
|
||||||
parent.getPosition().x
|
parent.getPosition().x
|
||||||
+ positionDirection
|
+ positionDirection
|
||||||
* (parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
* (parent.getSize().width + SymmetricSorter.INTERNODE_HORIZONTAL_PADDING),
|
||||||
y: parent.getPosition().y,
|
y: parent.getPosition().y,
|
||||||
};
|
};
|
||||||
return [0, position];
|
return [0, position];
|
||||||
}
|
}
|
||||||
// Try to fit within ...
|
// Try to fit within ...
|
||||||
const result = null;
|
const result = null;
|
||||||
const last = parentChildren.getLast();
|
const last = parentChildren.getLast();
|
||||||
for (let i = 0; i < parentChildren.length; i++) {
|
for (let i = 0; i < parentChildren.length; i++) {
|
||||||
const parentChild = parentChildren[i];
|
const parentChild = parentChildren[i];
|
||||||
const nodeAfter = i + 1 == parentChild.length ? null : parentChildren[i + 1];
|
const nodeAfter = i + 1 == parentChild.length ? null : parentChildren[i + 1];
|
||||||
|
|
||||||
// Fit at the bottom
|
// Fit at the bottom
|
||||||
if (!nodeAfter && position.y > parentChild.getPosition().y) {
|
if (!nodeAfter && position.y > parentChild.getPosition().y) {
|
||||||
var order = graph.getParent(node) && graph.getParent(node).getId() == parent.getId()
|
var order = graph.getParent(node) && graph.getParent(node).getId() == parent.getId()
|
||||||
? last.getOrder()
|
? last.getOrder()
|
||||||
: last.getOrder() + 1;
|
: last.getOrder() + 1;
|
||||||
var position = {
|
var position = {
|
||||||
x: parentChild.getPosition().x,
|
x: parentChild.getPosition().x,
|
||||||
y:
|
y:
|
||||||
parentChild.getPosition().y
|
parentChild.getPosition().y
|
||||||
+ parentChild.getSize().height
|
+ parentChild.getSize().height
|
||||||
+ SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2,
|
+ SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2,
|
||||||
};
|
};
|
||||||
return [order, position];
|
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()];
|
|
||||||
}
|
|
||||||
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
|
// Fit after this node
|
||||||
const first = parentChildren[0];
|
if (
|
||||||
var position = {
|
nodeAfter
|
||||||
x: first.getPosition().x,
|
&& position.y > parentChild.getPosition().y
|
||||||
y:
|
&& position.y < nodeAfter.getPosition().y
|
||||||
|
) {
|
||||||
|
if (
|
||||||
|
nodeAfter.getId() == node.getId()
|
||||||
|
|| parentChild.getId() == node.getId()
|
||||||
|
) {
|
||||||
|
return [node.getOrder(), node.getPosition()];
|
||||||
|
}
|
||||||
|
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
|
||||||
|
const first = parentChildren[0];
|
||||||
|
var position = {
|
||||||
|
x: first.getPosition().x,
|
||||||
|
y:
|
||||||
first.getPosition().y
|
first.getPosition().y
|
||||||
- first.getSize().height
|
- first.getSize().height
|
||||||
- SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2,
|
- SymmetricSorter.INTERNODE_VERTICAL_PADDING * 2,
|
||||||
};
|
};
|
||||||
return [0, position];
|
return [0, position];
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param treeSet
|
* @param treeSet
|
||||||
* @param parent
|
* @param parent
|
||||||
* @param child
|
* @param child
|
||||||
* @param order
|
* @param order
|
||||||
* @throws will throw an error if the order is not strictly continuous
|
* @throws will throw an error if the order is not strictly continuous
|
||||||
*/
|
*/
|
||||||
insert(treeSet, parent, child, order) {
|
insert(treeSet, parent, child, order) {
|
||||||
const children = this._getSortedChildren(treeSet, parent);
|
const children = this._getSortedChildren(treeSet, parent);
|
||||||
$assert(
|
$assert(
|
||||||
order <= children.length,
|
order <= children.length,
|
||||||
`Order must be continues and can not have holes. Order:${order}`,
|
`Order must be continues and can not have holes. Order:${order}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Shift all the elements in one .
|
// Shift all the elements in one .
|
||||||
for (let i = order; i < children.length; i++) {
|
for (let i = order; i < children.length; i++) {
|
||||||
const node = children[i];
|
const node = children[i];
|
||||||
node.setOrder(i + 1);
|
node.setOrder(i + 1);
|
||||||
}
|
}
|
||||||
child.setOrder(order);
|
child.setOrder(order);
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param treeSet
|
* @param treeSet
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if the node is in the wrong position */
|
* @throws will throw an error if the node is in the wrong position */
|
||||||
detach(treeSet, node) {
|
detach(treeSet, node) {
|
||||||
const parent = treeSet.getParent(node);
|
const parent = treeSet.getParent(node);
|
||||||
const children = this._getSortedChildren(treeSet, parent);
|
const children = this._getSortedChildren(treeSet, parent);
|
||||||
const order = node.getOrder();
|
const order = node.getOrder();
|
||||||
$assert(children[order] === node, 'Node seems not to be in the right position');
|
$assert(children[order] === node, 'Node seems not to be in the right position');
|
||||||
|
|
||||||
// Shift all the nodes ...
|
// Shift all the nodes ...
|
||||||
for (let i = node.getOrder() + 1; i < children.length; i++) {
|
for (let i = node.getOrder() + 1; i < children.length; i++) {
|
||||||
const child = children[i];
|
const child = children[i];
|
||||||
child.setOrder(child.getOrder() - 1);
|
child.setOrder(child.getOrder() - 1);
|
||||||
}
|
}
|
||||||
node.setOrder(0);
|
node.setOrder(0);
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param treeSet
|
* @param treeSet
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if treeSet is null or undefined
|
* @throws will throw an error if treeSet is null or undefined
|
||||||
@ -226,100 +219,99 @@ const SymmetricSorter = new Class(
|
|||||||
* value, is null or undefined
|
* value, is null or undefined
|
||||||
* @return offsets
|
* @return offsets
|
||||||
*/
|
*/
|
||||||
computeOffsets(treeSet, node) {
|
computeOffsets(treeSet, node) {
|
||||||
$assert(treeSet, 'treeSet can no be null.');
|
$assert(treeSet, 'treeSet can no be null.');
|
||||||
$assert(node, 'node can no be null.');
|
$assert(node, 'node can no be null.');
|
||||||
|
|
||||||
const children = this._getSortedChildren(treeSet, node);
|
const children = this._getSortedChildren(treeSet, node);
|
||||||
|
|
||||||
// Compute heights ...
|
// Compute heights ...
|
||||||
const heights = children
|
const heights = children
|
||||||
.map(function (child) {
|
.map(function (child) {
|
||||||
return {
|
return {
|
||||||
id: child.getId(),
|
id: child.getId(),
|
||||||
order: child.getOrder(),
|
order: child.getOrder(),
|
||||||
position: child.getPosition(),
|
position: child.getPosition(),
|
||||||
width: child.getSize().width,
|
width: child.getSize().width,
|
||||||
height: this._computeChildrenHeight(treeSet, child),
|
height: this._computeChildrenHeight(treeSet, child),
|
||||||
};
|
};
|
||||||
}, this)
|
}, this)
|
||||||
.reverse();
|
.reverse();
|
||||||
|
|
||||||
// Compute the center of the branch ...
|
// Compute the center of the branch ...
|
||||||
let totalHeight = 0;
|
let totalHeight = 0;
|
||||||
heights.forEach((elem) => {
|
heights.forEach((elem) => {
|
||||||
totalHeight += elem.height;
|
totalHeight += elem.height;
|
||||||
});
|
});
|
||||||
let ysum = totalHeight / 2;
|
let ysum = totalHeight / 2;
|
||||||
|
|
||||||
// Calculate the offsets ...
|
// Calculate the offsets ...
|
||||||
const result = {};
|
const result = {};
|
||||||
for (let i = 0; i < heights.length; i++) {
|
for (let i = 0; i < heights.length; i++) {
|
||||||
ysum -= heights[i].height;
|
ysum -= heights[i].height;
|
||||||
const childNode = treeSet.find(heights[i].id);
|
const childNode = treeSet.find(heights[i].id);
|
||||||
const direction = this.getChildDirection(treeSet, childNode);
|
const direction = this.getChildDirection(treeSet, childNode);
|
||||||
|
|
||||||
const yOffset = ysum + heights[i].height / 2;
|
const yOffset = ysum + heights[i].height / 2;
|
||||||
const xOffset = direction
|
const xOffset = direction
|
||||||
* (heights[i].width / 2
|
* (heights[i].width / 2
|
||||||
+ node.getSize().width / 2
|
+ node.getSize().width / 2
|
||||||
+ SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
+ SymmetricSorter.INTERNODE_HORIZONTAL_PADDING);
|
||||||
|
|
||||||
$assert(!isNaN(xOffset), 'xOffset can not be null');
|
$assert(!Number.isNaN(xOffset), 'xOffset can not be null');
|
||||||
$assert(!isNaN(yOffset), 'yOffset can not be null');
|
$assert(!Number.isNaN(yOffset), 'yOffset can not be null');
|
||||||
|
|
||||||
result[heights[i].id] = { x: xOffset, y: yOffset };
|
result[heights[i].id] = { x: xOffset, y: yOffset };
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param treeSet
|
* @param treeSet
|
||||||
* @param node
|
* @param node
|
||||||
* @throws will throw an error if order elements are missing
|
* @throws will throw an error if order elements are missing
|
||||||
*/
|
*/
|
||||||
verify(treeSet, node) {
|
verify(treeSet, node) {
|
||||||
// Check that all is consistent ...
|
// Check that all is consistent ...
|
||||||
const children = this._getSortedChildren(treeSet, node);
|
const children = this._getSortedChildren(treeSet, node);
|
||||||
|
|
||||||
for (let i = 0; i < children.length; i++) {
|
for (let i = 0; i < children.length; i++) {
|
||||||
$assert(children[i].getOrder() == i, 'missing order elements');
|
$assert(children[i].getOrder() == i, 'missing order elements');
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param treeSet
|
* @param treeSet
|
||||||
* @param child
|
* @param child
|
||||||
* @return direction of the given child from its parent or from the root node, if isolated */
|
* @return direction of the given child from its parent or from the root node, if isolated */
|
||||||
getChildDirection(treeSet, child) {
|
getChildDirection(treeSet, child) {
|
||||||
$assert(treeSet, 'treeSet can no be null.');
|
$assert(treeSet, 'treeSet can no be null.');
|
||||||
$assert(treeSet.getParent(child), 'This should not happen');
|
$assert(treeSet.getParent(child), 'This should not happen');
|
||||||
|
|
||||||
let result;
|
let result;
|
||||||
const rootNode = treeSet.getRootNode(child);
|
const rootNode = treeSet.getRootNode(child);
|
||||||
if (treeSet.getParent(child) == rootNode) {
|
if (treeSet.getParent(child) == rootNode) {
|
||||||
// This is the case of a isolated child ... In this case, the directions is based on the root.
|
// This is the case of a isolated child ... In this case, the directions is based on the root.
|
||||||
result = Math.sign(rootNode.getPosition().x);
|
result = Math.sign(rootNode.getPosition().x);
|
||||||
} else {
|
} else {
|
||||||
// if this is not the case, honor the direction of the parent ...
|
// if this is not the case, honor the direction of the parent ...
|
||||||
const parent = treeSet.getParent(child);
|
const parent = treeSet.getParent(child);
|
||||||
const grandParent = treeSet.getParent(parent);
|
const grandParent = treeSet.getParent(parent);
|
||||||
const sorter = grandParent.getSorter();
|
const sorter = grandParent.getSorter();
|
||||||
result = sorter.getChildDirection(treeSet, parent);
|
result = sorter.getChildDirection(treeSet, parent);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
/** @return {String} the print name of this class */
|
/** @return {String} the print name of this class */
|
||||||
toString() {
|
toString() {
|
||||||
return 'Symmetric Sorter';
|
return 'Symmetric Sorter';
|
||||||
},
|
}
|
||||||
|
|
||||||
_getVerticalPadding() {
|
_getVerticalPadding() {
|
||||||
return SymmetricSorter.INTERNODE_VERTICAL_PADDING;
|
return SymmetricSorter.INTERNODE_VERTICAL_PADDING;
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constant
|
* @constant
|
||||||
|
@ -19,8 +19,7 @@
|
|||||||
// FIXME: this Class should be reimplemented
|
// FIXME: this Class should be reimplemented
|
||||||
import Events from '../Events';
|
import Events from '../Events';
|
||||||
|
|
||||||
const FadeEffect = new Class(/** @lends FadeEffect */{
|
class FadeEffect extends Events {/** @lends FadeEffect */
|
||||||
Extends: Events,
|
|
||||||
/**
|
/**
|
||||||
* @extends mindplot.Events
|
* @extends mindplot.Events
|
||||||
* @constructs
|
* @constructs
|
||||||
@ -30,7 +29,7 @@ const FadeEffect = new Class(/** @lends FadeEffect */{
|
|||||||
initialize(elements, isVisible) {
|
initialize(elements, isVisible) {
|
||||||
this._isVisible = isVisible;
|
this._isVisible = isVisible;
|
||||||
this._element = elements;
|
this._element = elements;
|
||||||
},
|
}
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
start() {
|
start() {
|
||||||
@ -42,7 +41,7 @@ const FadeEffect = new Class(/** @lends FadeEffect */{
|
|||||||
});
|
});
|
||||||
this._isVisible = !visible;
|
this._isVisible = !visible;
|
||||||
this.fireEvent('complete');
|
this.fireEvent('complete');
|
||||||
},
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
export default FadeEffect;
|
export default FadeEffect;
|
||||||
|
@ -65,7 +65,7 @@ class ColorPalettePanel extends ToolbarPaneItem {
|
|||||||
const colorCells = content.find('div[class=palette-colorswatch]');
|
const colorCells = content.find('div[class=palette-colorswatch]');
|
||||||
const model = this.getModel();
|
const model = this.getModel();
|
||||||
const me = this;
|
const me = this;
|
||||||
colorCells.each((elem) => {
|
colorCells.each((index, elem) => {
|
||||||
$(elem).on('click', () => {
|
$(elem).on('click', () => {
|
||||||
const color = $(elem).css('background-color');
|
const color = $(elem).css('background-color');
|
||||||
model.setValue(color);
|
model.setValue(color);
|
||||||
|
@ -17,30 +17,28 @@
|
|||||||
*/
|
*/
|
||||||
import BootstrapDialog from '../libraries/bootstrap/BootstrapDialog';
|
import BootstrapDialog from '../libraries/bootstrap/BootstrapDialog';
|
||||||
|
|
||||||
const LinkEditor = new Class(/** @lends LinkEditor */{
|
class LinkEditor extends BootstrapDialog {/** @lends LinkEditor */
|
||||||
Extends: BootstrapDialog,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructs
|
* @constructs
|
||||||
* @param model
|
* @param model
|
||||||
* @throws will throw an error if model is null or undefined
|
* @throws will throw an error if model is null or undefined
|
||||||
* @extends BootstrapDialog
|
* @extends BootstrapDialog
|
||||||
*/
|
*/
|
||||||
initialize(model) {
|
constructor(model) {
|
||||||
$assert(model, 'model can not be null');
|
$assert(model, 'model can not be null');
|
||||||
this._model = model;
|
super($msg('LINK'), {
|
||||||
this.parent($msg('LINK'), {
|
|
||||||
cancelButton: true,
|
cancelButton: true,
|
||||||
closeButton: true,
|
closeButton: true,
|
||||||
acceptButton: true,
|
acceptButton: true,
|
||||||
removeButton: typeof model.getValue() !== 'undefined',
|
removeButton: typeof model.getValue() !== 'undefined',
|
||||||
errorMessage: true,
|
errorMessage: true,
|
||||||
onEventData: { model: this._model },
|
onEventData: { model },
|
||||||
});
|
});
|
||||||
|
this._model = model;
|
||||||
this.css({ margin: '150px auto' });
|
this.css({ margin: '150px auto' });
|
||||||
const panel = this._buildPanel(model);
|
const panel = this._buildPanel(model);
|
||||||
this.setContent(panel);
|
this.setContent(panel);
|
||||||
},
|
}
|
||||||
|
|
||||||
_buildPanel(model) {
|
_buildPanel(model) {
|
||||||
const result = $('<div></div>').css('padding-top', '5px');
|
const result = $('<div></div>').css('padding-top', '5px');
|
||||||
@ -109,7 +107,7 @@ const LinkEditor = new Class(/** @lends LinkEditor */{
|
|||||||
|
|
||||||
result.append(this.form);
|
result.append(this.form);
|
||||||
return result;
|
return result;
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* checks whether the input is a valid url
|
* checks whether the input is a valid url
|
||||||
@ -118,7 +116,7 @@ const LinkEditor = new Class(/** @lends LinkEditor */{
|
|||||||
checkURL(url) {
|
checkURL(url) {
|
||||||
const regex = /^(http|https|ftp):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i;
|
const regex = /^(http|https|ftp):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/i;
|
||||||
return (regex.test(url));
|
return (regex.test(url));
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* overrides abstract parent method
|
* overrides abstract parent method
|
||||||
@ -131,7 +129,7 @@ const LinkEditor = new Class(/** @lends LinkEditor */{
|
|||||||
if (!this.formSubmitted) {
|
if (!this.formSubmitted) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* overrides parent method
|
* overrides parent method
|
||||||
@ -139,7 +137,7 @@ const LinkEditor = new Class(/** @lends LinkEditor */{
|
|||||||
*/
|
*/
|
||||||
onDialogShown() {
|
onDialogShown() {
|
||||||
$(this).find('#inputUrl').focus();
|
$(this).find('#inputUrl').focus();
|
||||||
},
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* overrides abstract parent method
|
* overrides abstract parent method
|
||||||
@ -148,8 +146,8 @@ const LinkEditor = new Class(/** @lends LinkEditor */{
|
|||||||
onRemoveClick(event) {
|
onRemoveClick(event) {
|
||||||
event.data.model.setValue(null);
|
event.data.model.setValue(null);
|
||||||
event.data.dialog.close();
|
event.data.dialog.close();
|
||||||
},
|
}
|
||||||
|
|
||||||
});
|
}
|
||||||
|
|
||||||
export default LinkEditor;
|
export default LinkEditor;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable no-console */
|
||||||
/*
|
/*
|
||||||
* Copyright [2015] [wisemapping]
|
* Copyright [2015] [wisemapping]
|
||||||
*
|
*
|
||||||
@ -15,19 +16,18 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
import $ from 'jquery';
|
||||||
|
import { $assert } from '@wisemapping/core-js';
|
||||||
import TestSuite from './TestSuite';
|
import TestSuite from './TestSuite';
|
||||||
import LayoutManager from '../../../src/components/layout/LayoutManager';
|
import LayoutManager from '../../../src/components/layout/LayoutManager';
|
||||||
|
class BalancedTestSuite extends TestSuite {
|
||||||
const BalancedTestSuite = new Class({
|
constructor() {
|
||||||
Extends: TestSuite,
|
|
||||||
|
|
||||||
initialize() {
|
|
||||||
$('#balancedTest').css('display', 'block');
|
$('#balancedTest').css('display', 'block');
|
||||||
|
super();
|
||||||
this.testBalanced();
|
this.testBalanced();
|
||||||
this.testBalancedPredict();
|
this.testBalancedPredict();
|
||||||
this.testBalancedNodeDragPredict();
|
this.testBalancedNodeDragPredict();
|
||||||
},
|
}
|
||||||
|
|
||||||
testBalanced() {
|
testBalanced() {
|
||||||
console.log('testBalanced:');
|
console.log('testBalanced:');
|
||||||
@ -176,7 +176,7 @@ const BalancedTestSuite = new Class({
|
|||||||
);
|
);
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testBalancedPredict() {
|
testBalancedPredict() {
|
||||||
console.log('testBalancedPredict:');
|
console.log('testBalancedPredict:');
|
||||||
@ -335,7 +335,7 @@ const BalancedTestSuite = new Class({
|
|||||||
$assert(prediction5a.order == prediction5b.order, 'Both predictions should be the same');
|
$assert(prediction5a.order == prediction5b.order, 'Both predictions should be the same');
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testBalancedNodeDragPredict() {
|
testBalancedNodeDragPredict() {
|
||||||
console.log('testBalancedNodeDragPredict:');
|
console.log('testBalancedNodeDragPredict:');
|
||||||
@ -493,7 +493,7 @@ const BalancedTestSuite = new Class({
|
|||||||
);
|
);
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
export default BalancedTestSuite;
|
export default BalancedTestSuite;
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
import $ from 'jquery';
|
||||||
|
import { $assert } from '@wisemapping/core-js';
|
||||||
import TestSuite from './TestSuite';
|
import TestSuite from './TestSuite';
|
||||||
import LayoutManager from '../../../src/components/layout/LayoutManager';
|
import LayoutManager from '../../../src/components/layout/LayoutManager';
|
||||||
import OriginalLayout from '../../../src/components/layout/OriginalLayout';
|
import OriginalLayout from '../../../src/components/layout/OriginalLayout';
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable no-console */
|
||||||
/*
|
/*
|
||||||
* Copyright [2015] [wisemapping]
|
* Copyright [2015] [wisemapping]
|
||||||
*
|
*
|
||||||
@ -15,19 +16,20 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
import $ from 'jquery';
|
||||||
|
import { $assert } from '@wisemapping/core-js';
|
||||||
import TestSuite from './TestSuite';
|
import TestSuite from './TestSuite';
|
||||||
import LayoutManager from '../../../src/components/layout/LayoutManager';
|
import LayoutManager from '../../../src/components/layout/LayoutManager';
|
||||||
|
|
||||||
const SymmetricTestSuite = new Class({
|
class SymmetricTestSuite extends TestSuite {
|
||||||
Extends: TestSuite,
|
constructor() {
|
||||||
|
|
||||||
initialize() {
|
|
||||||
$('#symmetricTest').css('display', 'block');
|
$('#symmetricTest').css('display', 'block');
|
||||||
|
super();
|
||||||
|
|
||||||
this.testSymmetry();
|
this.testSymmetry();
|
||||||
this.testSymmetricPredict();
|
this.testSymmetricPredict();
|
||||||
this.testSymmetricDragPredict();
|
this.testSymmetricDragPredict();
|
||||||
},
|
}
|
||||||
|
|
||||||
testSymmetry() {
|
testSymmetry() {
|
||||||
console.log('testSymmetry:');
|
console.log('testSymmetry:');
|
||||||
@ -92,7 +94,7 @@ const SymmetricTestSuite = new Class({
|
|||||||
);
|
);
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testSymmetricPredict() {
|
testSymmetricPredict() {
|
||||||
console.log('testSymmetricPredict:');
|
console.log('testSymmetricPredict:');
|
||||||
@ -276,7 +278,7 @@ const SymmetricTestSuite = new Class({
|
|||||||
$assert(prediction5d.order == 0, 'Prediction order should be 0');
|
$assert(prediction5d.order == 0, 'Prediction order should be 0');
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testSymmetricDragPredict() {
|
testSymmetricDragPredict() {
|
||||||
console.log('testSymmetricDragPredict:');
|
console.log('testSymmetricDragPredict:');
|
||||||
@ -345,7 +347,7 @@ const SymmetricTestSuite = new Class({
|
|||||||
);
|
);
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
export default SymmetricTestSuite;
|
export default SymmetricTestSuite;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable no-console */
|
||||||
/*
|
/*
|
||||||
* Copyright [2015] [wisemapping]
|
* Copyright [2015] [wisemapping]
|
||||||
*
|
*
|
||||||
@ -15,12 +16,13 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
import $ from 'jquery';
|
||||||
|
import { $assert } from '@wisemapping/core-js';
|
||||||
import LayoutManager from '../../../src/components/layout/LayoutManager';
|
import LayoutManager from '../../../src/components/layout/LayoutManager';
|
||||||
|
import ChildrenSorterStrategy from '../../../src/components/layout/ChildrenSorterStrategy';
|
||||||
const TestSuite = new Class({
|
class TestSuite extends ChildrenSorterStrategy {
|
||||||
Extends: ChildrenSorterStrategy,
|
constructor() {
|
||||||
|
super();
|
||||||
initialize() {
|
|
||||||
$('#basicTest').css('display', 'block');
|
$('#basicTest').css('display', 'block');
|
||||||
// this.testAligned();
|
// this.testAligned();
|
||||||
this.testBaselineAligned1();
|
this.testBaselineAligned1();
|
||||||
@ -32,7 +34,7 @@ const TestSuite = new Class({
|
|||||||
this.testRemoveNode();
|
this.testRemoveNode();
|
||||||
this.testSize();
|
this.testSize();
|
||||||
this.testReconnectSingleNode();
|
this.testReconnectSingleNode();
|
||||||
},
|
}
|
||||||
|
|
||||||
testAligned() {
|
testAligned() {
|
||||||
console.log('testAligned:');
|
console.log('testAligned:');
|
||||||
@ -79,7 +81,7 @@ const TestSuite = new Class({
|
|||||||
);
|
);
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testBaselineAligned1() {
|
testBaselineAligned1() {
|
||||||
console.log('testBaselineAligned1:');
|
console.log('testBaselineAligned1:');
|
||||||
@ -125,7 +127,7 @@ const TestSuite = new Class({
|
|||||||
// manager.plot("testBaselineAligned1", {width:1600,height:800});
|
// manager.plot("testBaselineAligned1", {width:1600,height:800});
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testBaselineAligned2() {
|
testBaselineAligned2() {
|
||||||
console.log('testBaselineAligned2:');
|
console.log('testBaselineAligned2:');
|
||||||
@ -143,7 +145,7 @@ const TestSuite = new Class({
|
|||||||
manager.plot('testBaselineAligned2', { width: 1600, height: 800 });
|
manager.plot('testBaselineAligned2', { width: 1600, height: 800 });
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testEvents() {
|
testEvents() {
|
||||||
console.log('testEvents:');
|
console.log('testEvents:');
|
||||||
@ -181,7 +183,7 @@ const TestSuite = new Class({
|
|||||||
$assert(events.length == 0, 'Unnecessary tree updated.');
|
$assert(events.length == 0, 'Unnecessary tree updated.');
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testEventsComplex() {
|
testEventsComplex() {
|
||||||
console.log('testEventsComplex:');
|
console.log('testEventsComplex:');
|
||||||
@ -229,7 +231,7 @@ const TestSuite = new Class({
|
|||||||
$assert(events.length == 4, 'Only 4 nodes should be repositioned.');
|
$assert(events.length == 4, 'Only 4 nodes should be repositioned.');
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testDisconnect() {
|
testDisconnect() {
|
||||||
console.log('testDisconnect:');
|
console.log('testDisconnect:');
|
||||||
@ -290,7 +292,7 @@ const TestSuite = new Class({
|
|||||||
);
|
);
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testReconnect() {
|
testReconnect() {
|
||||||
console.log('testReconnect:');
|
console.log('testReconnect:');
|
||||||
@ -352,7 +354,7 @@ const TestSuite = new Class({
|
|||||||
);
|
);
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testRemoveNode() {
|
testRemoveNode() {
|
||||||
console.log('testRemoveNode:');
|
console.log('testRemoveNode:');
|
||||||
@ -422,7 +424,7 @@ const TestSuite = new Class({
|
|||||||
$assert(manager.find(9).getOrder() == 3, 'Node 9 should have order 3');
|
$assert(manager.find(9).getOrder() == 3, 'Node 9 should have order 3');
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testSize() {
|
testSize() {
|
||||||
console.log('testSize:');
|
console.log('testSize:');
|
||||||
@ -519,7 +521,7 @@ const TestSuite = new Class({
|
|||||||
);
|
);
|
||||||
|
|
||||||
console.log('OK!\n\n');
|
console.log('OK!\n\n');
|
||||||
},
|
}
|
||||||
|
|
||||||
testReconnectSingleNode() {
|
testReconnectSingleNode() {
|
||||||
console.log('testReconnectSingleNode:');
|
console.log('testReconnectSingleNode:');
|
||||||
@ -552,7 +554,7 @@ const TestSuite = new Class({
|
|||||||
'Node 1 should now be to the left of the root node',
|
'Node 1 should now be to the left of the root node',
|
||||||
);
|
);
|
||||||
$assert(manager.find(1).getOrder() == 1, 'Node 1 should now have order 0');
|
$assert(manager.find(1).getOrder() == 1, 'Node 1 should now have order 0');
|
||||||
},
|
}
|
||||||
|
|
||||||
_plotPrediction(canvas, prediction) {
|
_plotPrediction(canvas, prediction) {
|
||||||
if (!canvas) {
|
if (!canvas) {
|
||||||
@ -570,10 +572,10 @@ const TestSuite = new Class({
|
|||||||
const cx = position.x + canvas.width / 2 - TestSuite.NODE_SIZE.width / 2;
|
const cx = position.x + canvas.width / 2 - TestSuite.NODE_SIZE.width / 2;
|
||||||
const cy = position.y + canvas.height / 2 - TestSuite.NODE_SIZE.height / 2;
|
const cy = position.y + canvas.height / 2 - TestSuite.NODE_SIZE.height / 2;
|
||||||
canvas.rect(cx, cy, TestSuite.NODE_SIZE.width, TestSuite.NODE_SIZE.height);
|
canvas.rect(cx, cy, TestSuite.NODE_SIZE.width, TestSuite.NODE_SIZE.height);
|
||||||
},
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
(TestSuite.NODE_SIZE = { width: 80, height: 30 }),
|
TestSuite.NODE_SIZE = { width: 80, height: 30 };
|
||||||
(TestSuite.ROOT_NODE_SIZE = { width: 120, height: 40 });
|
TestSuite.ROOT_NODE_SIZE = { width: 120, height: 40 };
|
||||||
|
|
||||||
export default TestSuite;
|
export default TestSuite;
|
||||||
|
@ -4,6 +4,7 @@ import SymmetricTestSuite from './SymmetricTestSuite';
|
|||||||
import FreeTestSuite from './FreeTestSuite';
|
import FreeTestSuite from './FreeTestSuite';
|
||||||
import Raphael from './lib/raphael-min';
|
import Raphael from './lib/raphael-min';
|
||||||
import { drawGrid } from './lib/raphael-plugins';
|
import { drawGrid } from './lib/raphael-plugins';
|
||||||
|
import '../../../src'; // TODO: remove this when removing mootools (hack used to load it as a side effect)
|
||||||
|
|
||||||
global.Raphael = Raphael;
|
global.Raphael = Raphael;
|
||||||
global.Raphael.fn.drawGrid = drawGrid;
|
global.Raphael.fn.drawGrid = drawGrid;
|
||||||
|
@ -12,5 +12,6 @@
|
|||||||
},
|
},
|
||||||
"persistenceManager": "mindplot.LocalStorageManager",
|
"persistenceManager": "mindplot.LocalStorageManager",
|
||||||
"mapId": "welcome",
|
"mapId": "welcome",
|
||||||
"container":"mindplot"
|
"container":"mindplot",
|
||||||
|
"locale": "en"
|
||||||
}
|
}
|
@ -1,122 +1,115 @@
|
|||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>WiseMapping - Editor </title>
|
<title>WiseMapping - Editor </title>
|
||||||
<meta http-equiv="Content-type" content="text/html; charset=UTF-8"/>
|
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
|
||||||
|
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
|
||||||
<![endif]-->
|
|
||||||
<link rel="stylesheet/less" type="text/css" href="css/editor.less"/>
|
|
||||||
|
|
||||||
<script type='text/javascript' src='js/jquery.js'></script>
|
|
||||||
<script type="text/javascript" language="javascript" src="bootstrap/js/bootstrap.js"></script>
|
|
||||||
<script src="js/less.js" type="text/javascript"></script>
|
|
||||||
|
|
||||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||||
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
|
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id='load' class="modal fade">
|
<div id='load' class="modal fade">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div style="height: 120px; text-align: center; border: 2px solid orange" class="modal-content">
|
<div style="height: 120px; text-align: center; border: 2px solid orange" class="modal-content">
|
||||||
<img style='margin-top:25px; text-align: center' src="images/ajax-loader.gif">
|
<img style='margin-top:25px; text-align: center' src="images/ajax-loader.gif">
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="header">
|
|
||||||
|
|
||||||
<div id="headerInfo">
|
|
||||||
<div id="headerActions"></div>
|
|
||||||
<div id="headerLogo"></div>
|
|
||||||
<div id="headerMapTitle">Title: <span>Welcome</span></div>
|
|
||||||
</div>
|
|
||||||
<div id="toolbar">
|
|
||||||
<div id="editTab" class="tabContent">
|
|
||||||
<div id="persist" class="buttonContainer">
|
|
||||||
<div id="save" class="buttonOn">
|
|
||||||
<img src="images/save.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="discard" class="buttonOn">
|
|
||||||
<img src="images/discard.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="export" class="buttonOn">
|
|
||||||
<img src="images/export.png"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="edit" class="buttonContainer">
|
|
||||||
<div id="undoEdition" class="buttonOn">
|
|
||||||
<img src="images/undo.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="redoEdition" class="buttonOn">
|
|
||||||
<img src="images/redo.png"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="zoom" class="buttonContainer">
|
|
||||||
<div id="zoomOut" class="buttonOn">
|
|
||||||
<img src="images/zoom-out.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="zoomIn" class="buttonOn">
|
|
||||||
<img src="images/zoom-in.png"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="node" class="buttonContainer">
|
|
||||||
<div id="topicShape" class="buttonExtOn">
|
|
||||||
<img src="images/topic-shape.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="addTopic" class="buttonOn">
|
|
||||||
<img src="images/topic-add.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="deleteTopic" class="buttonOn">
|
|
||||||
<img src="images/topic-delete.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="topicBorder" class="buttonExtOn">
|
|
||||||
<img src="images/topic-border.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="topicColor" class="buttonExtOn">
|
|
||||||
<img src="images/topic-color.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="topicIcon" class="buttonExtOn">
|
|
||||||
<img src="images/topic-icon.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="topicNote" class="buttonOn">
|
|
||||||
<img src="images/topic-note.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="topicLink" class="buttonOn">
|
|
||||||
<img src="images/topic-link.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="topicRelation" class="buttonOn">
|
|
||||||
<img src="images/topic-relation.png"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="font" class="buttonContainer">
|
|
||||||
<div id="fontFamily" class="buttonExtOn">
|
|
||||||
<img src="images/font-type.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="fontSize" class="buttonExtOn">
|
|
||||||
<img src="images/font-size.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="fontBold" class="buttonOn">
|
|
||||||
<img src="images/font-bold.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="fontItalic" class="buttonOn">
|
|
||||||
<img src="images/font-italic.png"/>
|
|
||||||
</div>
|
|
||||||
<div id="fontColor" class="buttonExtOn" style="padding-top:4px">
|
|
||||||
<img src="images/font-color.png"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="headerNotifier"></div>
|
|
||||||
<div id="footer">
|
|
||||||
<div id="footerLogo"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="mindplot" onselectstart="return false;"></div>
|
<div id="header">
|
||||||
|
|
||||||
|
<div id="headerInfo">
|
||||||
|
<div id="headerActions"></div>
|
||||||
|
<div id="headerLogo"></div>
|
||||||
|
<div id="headerMapTitle">Title: <span>Welcome</span></div>
|
||||||
|
</div>
|
||||||
|
<div id="toolbar">
|
||||||
|
<div id="editTab" class="tabContent">
|
||||||
|
<div id="persist" class="buttonContainer">
|
||||||
|
<div id="save" class="buttonOn">
|
||||||
|
<img src="images/save.png" />
|
||||||
|
</div>
|
||||||
|
<div id="discard" class="buttonOn">
|
||||||
|
<img src="images/discard.png" />
|
||||||
|
</div>
|
||||||
|
<div id="export" class="buttonOn">
|
||||||
|
<img src="images/export.png" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="edit" class="buttonContainer">
|
||||||
|
<div id="undoEdition" class="buttonOn">
|
||||||
|
<img src="images/undo.png" />
|
||||||
|
</div>
|
||||||
|
<div id="redoEdition" class="buttonOn">
|
||||||
|
<img src="images/redo.png" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="zoom" class="buttonContainer">
|
||||||
|
<div id="zoomOut" class="buttonOn">
|
||||||
|
<img src="images/zoom-out.png" />
|
||||||
|
</div>
|
||||||
|
<div id="zoomIn" class="buttonOn">
|
||||||
|
<img src="images/zoom-in.png" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="node" class="buttonContainer">
|
||||||
|
<div id="topicShape" class="buttonExtOn">
|
||||||
|
<img src="images/topic-shape.png" />
|
||||||
|
</div>
|
||||||
|
<div id="addTopic" class="buttonOn">
|
||||||
|
<img src="images/topic-add.png" />
|
||||||
|
</div>
|
||||||
|
<div id="deleteTopic" class="buttonOn">
|
||||||
|
<img src="images/topic-delete.png" />
|
||||||
|
</div>
|
||||||
|
<div id="topicBorder" class="buttonExtOn">
|
||||||
|
<img src="images/topic-border.png" />
|
||||||
|
</div>
|
||||||
|
<div id="topicColor" class="buttonExtOn">
|
||||||
|
<img src="images/topic-color.png" />
|
||||||
|
</div>
|
||||||
|
<div id="topicIcon" class="buttonExtOn">
|
||||||
|
<img src="images/topic-icon.png" />
|
||||||
|
</div>
|
||||||
|
<div id="topicNote" class="buttonOn">
|
||||||
|
<img src="images/topic-note.png" />
|
||||||
|
</div>
|
||||||
|
<div id="topicLink" class="buttonOn">
|
||||||
|
<img src="images/topic-link.png" />
|
||||||
|
</div>
|
||||||
|
<div id="topicRelation" class="buttonOn">
|
||||||
|
<img src="images/topic-relation.png" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="font" class="buttonContainer">
|
||||||
|
<div id="fontFamily" class="buttonExtOn">
|
||||||
|
<img src="images/font-type.png" />
|
||||||
|
</div>
|
||||||
|
<div id="fontSize" class="buttonExtOn">
|
||||||
|
<img src="images/font-size.png" />
|
||||||
|
</div>
|
||||||
|
<div id="fontBold" class="buttonOn">
|
||||||
|
<img src="images/font-bold.png" />
|
||||||
|
</div>
|
||||||
|
<div id="fontItalic" class="buttonOn">
|
||||||
|
<img src="images/font-italic.png" />
|
||||||
|
</div>
|
||||||
|
<div id="fontColor" class="buttonExtOn" style="padding-top:4px">
|
||||||
|
<img src="images/font-color.png" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="headerNotifier"></div>
|
||||||
|
<div id="footer">
|
||||||
|
<div id="footerLogo"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="mindplot" onselectstart="return false;"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
@ -1,135 +1,101 @@
|
|||||||
<!DOCTYPE HTML>
|
<!DOCTYPE HTML>
|
||||||
|
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<title>WiseMapping - Editor </title>
|
<title>WiseMapping - Editor </title>
|
||||||
<meta http-equiv="Content-type" content="text/html; charset=UTF-8"/>
|
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
|
||||||
<!--[if lt IE 9]>
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="chrome=1">
|
|
||||||
<![endif]-->
|
|
||||||
<link rel="stylesheet/less" type="text/css" href="css/embedded.less"/>
|
|
||||||
|
|
||||||
<script type='text/javascript' src='js/jquery.js'></script>
|
|
||||||
<script type='text/javascript' src='js/bootstrap.js'></script>
|
|
||||||
<script type='text/javascript' src='js/mootools-core.js'></script>
|
|
||||||
<script type='text/javascript' src='js/core.js'></script>
|
|
||||||
<script type='text/javascript' src='js/less.js'></script>
|
|
||||||
|
|
||||||
<link rel="icon" href="images/favicon.ico" type="image/x-icon">
|
<link rel="icon" href="images/favicon.ico" type="image/x-icon">
|
||||||
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon">
|
<link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon">
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
|
|
||||||
var mapId = 'welcome';
|
|
||||||
$(document).on('loadcomplete', function(resource) {
|
|
||||||
|
|
||||||
// Options has been defined in by a external ile ?
|
|
||||||
var queryString = window.location.search;
|
|
||||||
var confUrl = queryString.replace("?confUrl=", "");
|
|
||||||
var options = loadDesignerOptions(confUrl);
|
|
||||||
var designer = buildDesigner(options);
|
|
||||||
|
|
||||||
// Load map from XML file persisted on disk...
|
|
||||||
var persistence = mindplot.PersistenceManager.getInstance();
|
|
||||||
var mindmap;
|
|
||||||
try {
|
|
||||||
mindmap = persistence.load(mapId);
|
|
||||||
} catch(e) {
|
|
||||||
// If the map could not be loaded, create a new empty map...
|
|
||||||
mindmap = mindplot.model.Mindmap.buildEmpty(mapId);
|
|
||||||
}
|
|
||||||
designer.loadMap(mindmap);
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
<div id="header">
|
||||||
|
|
||||||
<div id="header">
|
<div id="headerInfo">
|
||||||
|
<div id="headerActions"></div>
|
||||||
<div id="headerInfo">
|
<div id="headerLogo"></div>
|
||||||
<div id="headerActions"></div>
|
<div id="headerMapTitle">Title: <span>Welcome</span></div>
|
||||||
<div id="headerLogo"></div>
|
</div>
|
||||||
<div id="headerMapTitle">Title: <span>Welcome</span></div>
|
<div id="toolbar">
|
||||||
</div>
|
<div id="editTab" class="tabContent">
|
||||||
<div id="toolbar">
|
<div id="persist" class="buttonContainer">
|
||||||
<div id="editTab" class="tabContent">
|
<div id="save" class="buttonOn">
|
||||||
<div id="persist" class="buttonContainer">
|
<img src="images/save.png" />
|
||||||
<div id="save" class="buttonOn">
|
</div>
|
||||||
<img src="images/save.png"/>
|
<div id="discard" class="buttonOn">
|
||||||
</div>
|
<img src="images/discard.png" />
|
||||||
<div id="discard" class="buttonOn">
|
</div>
|
||||||
<img src="images/discard.png"/>
|
</div>
|
||||||
</div>
|
<div id="edit" class="buttonContainer">
|
||||||
</div>
|
<div id="undoEdition" class="buttonOn">
|
||||||
<div id="edit" class="buttonContainer">
|
<img src="images/undo.png" />
|
||||||
<div id="undoEdition" class="buttonOn">
|
</div>
|
||||||
<img src="images/undo.png"/>
|
<div id="redoEdition" class="buttonOn">
|
||||||
</div>
|
<img src="images/redo.png" />
|
||||||
<div id="redoEdition" class="buttonOn">
|
</div>
|
||||||
<img src="images/redo.png"/>
|
</div>
|
||||||
</div>
|
<div id="zoom" class="buttonContainer">
|
||||||
</div>
|
<div id="zoomIn" class="buttonOn">
|
||||||
<div id="zoom" class="buttonContainer">
|
<img src="images/zoom-in.png" />
|
||||||
<div id="zoomIn" class="buttonOn">
|
</div>
|
||||||
<img src="images/zoom-in.png"/>
|
<div id="zoomOut" class="buttonOn">
|
||||||
</div>
|
<img src="images/zoom-out.png" />
|
||||||
<div id="zoomOut" class="buttonOn">
|
</div>
|
||||||
<img src="images/zoom-out.png"/>
|
</div>
|
||||||
</div>
|
<div id="node" class="buttonContainer">
|
||||||
</div>
|
<div id="topicShape" class="buttonExtOn">
|
||||||
<div id="node" class="buttonContainer">
|
<img src="images/topic-shape.png" />
|
||||||
<div id="topicShape" class="buttonExtOn">
|
</div>
|
||||||
<img src="images/topic-shape.png"/>
|
<div id="addTopic" class="buttonOn">
|
||||||
</div>
|
<img src="images/topic-add.png" />
|
||||||
<div id="addTopic" class="buttonOn">
|
</div>
|
||||||
<img src="images/topic-add.png"/>
|
<div id="deleteTopic" class="buttonOn">
|
||||||
</div>
|
<img src="images/topic-delete.png" />
|
||||||
<div id="deleteTopic" class="buttonOn">
|
</div>
|
||||||
<img src="images/topic-delete.png"/>
|
<div id="topicBorder" class="buttonOn">
|
||||||
</div>
|
<img src="images/topic-border.png" />
|
||||||
<div id="topicBorder" class="buttonOn">
|
</div>
|
||||||
<img src="images/topic-border.png"/>
|
<div id="topicColor" class="buttonExtOn">
|
||||||
</div>
|
<img src="images/topic-color.png" />
|
||||||
<div id="topicColor" class="buttonExtOn">
|
</div>
|
||||||
<img src="images/topic-color.png"/>
|
<div id="topicIcon" class="buttonExtOn">
|
||||||
</div>
|
<img src="images/topic-icon.png" />
|
||||||
<div id="topicIcon" class="buttonExtOn">
|
</div>
|
||||||
<img src="images/topic-icon.png"/>
|
<div id="topicNote" class="buttonOn">
|
||||||
</div>
|
<img src="images/topic-note.png" />
|
||||||
<div id="topicNote" class="buttonOn">
|
</div>
|
||||||
<img src="images/topic-note.png"/>
|
<div id="topicLink" class="buttonOn">
|
||||||
</div>
|
<img src="images/topic-link.png" />
|
||||||
<div id="topicLink" class="buttonOn">
|
</div>
|
||||||
<img src="images/topic-link.png"/>
|
<div id="topicRelation" class="buttonOn">
|
||||||
</div>
|
<img src="images/topic-relation.png" />
|
||||||
<div id="topicRelation" class="buttonOn">
|
</div>
|
||||||
<img src="images/topic-relation.png"/>
|
</div>
|
||||||
</div>
|
<div id="font" class="buttonContainer">
|
||||||
</div>
|
<div id="fontFamily" class="buttonOn">
|
||||||
<div id="font" class="buttonContainer">
|
<img src="images/font-type.png" />
|
||||||
<div id="fontFamily" class="buttonOn">
|
</div>
|
||||||
<img src="images/font-type.png"/>
|
<div id="fontSize" class="buttonExtOn">
|
||||||
</div>
|
<img src="images/font-size.png" />
|
||||||
<div id="fontSize" class="buttonExtOn">
|
</div>
|
||||||
<img src="images/font-size.png"/>
|
<div id="fontBold" class="buttonOn">
|
||||||
</div>
|
<img src="images/font-bold.png" />
|
||||||
<div id="fontBold" class="buttonOn">
|
</div>
|
||||||
<img src="images/font-bold.png"/>
|
<div id="fontItalic" class="buttonOn">
|
||||||
</div>
|
<img src="images/font-italic.png" />
|
||||||
<div id="fontItalic" class="buttonOn">
|
</div>
|
||||||
<img src="images/font-italic.png"/>
|
<div id="fontColor" class="buttonExtOn" style="padding-top:4px">
|
||||||
</div>
|
<img src="images/font-color.png" />
|
||||||
<div id="fontColor" class="buttonExtOn" style="padding-top:4px">
|
|
||||||
<img src="images/font-color.png"/>
|
|
||||||
|
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="headerNotifier"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="headerNotifier"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="mindplot" onselectstart="return false;"></div>
|
<div id="mindplot" onselectstart="return false;"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
@ -1,187 +1,16 @@
|
|||||||
/*
|
import '../css/editor.less';
|
||||||
* Copyright [2015] [wisemapping]
|
import { buildDesigner, loadDesignerOptions, loadExample } from './loader';
|
||||||
*
|
import { PersistenceManager } from '../../../../src';
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "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
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
import { $assert } from '@wisemapping/core-js';
|
|
||||||
import { Mindmap, PersistenceManager, Designer, LocalStorageManager, Menu } from '../../../../src/';
|
|
||||||
|
|
||||||
import $ from 'jquery';
|
const example = async () => {
|
||||||
global.jQuery = $;
|
const mapId = 'welcome';
|
||||||
|
const options = await loadDesignerOptions();
|
||||||
|
const designer = buildDesigner(options);
|
||||||
|
|
||||||
let designer = null;
|
// Load map from XML file persisted on disk...
|
||||||
|
const persistence = PersistenceManager.getInstance();
|
||||||
/*
|
const mindmap = persistence.load(mapId);
|
||||||
* Disclaimer: this global variable is a temporary workaround to Mootools' Browser class
|
designer.loadMap(mindmap);
|
||||||
* We need to avoid browser detection and replace it with feature detection,
|
|
||||||
* jquery recommends: http://www.modernizr.com/
|
|
||||||
*/
|
|
||||||
|
|
||||||
global.Browser = {
|
|
||||||
firefox: window.globalStorage,
|
|
||||||
ie: document.all && !window.opera,
|
|
||||||
ie6: !window.XMLHttpRequest,
|
|
||||||
ie7: document.all && window.XMLHttpRequest && !XDomainRequest && !window.opera,
|
|
||||||
ie8: document.documentMode == 8,
|
|
||||||
ie11: document.documentMode == 11,
|
|
||||||
opera: Boolean(window.opera),
|
|
||||||
chrome: Boolean(window.chrome),
|
|
||||||
safari: window.getComputedStyle && !window.globalStorage && !window.opera,
|
|
||||||
Platform: {
|
|
||||||
mac: navigator.platform.indexOf('Mac') != -1,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function buildDesigner(options) {
|
loadExample(example);
|
||||||
const container = $(`#${options.container}`);
|
|
||||||
$assert(container, 'container could not be null');
|
|
||||||
|
|
||||||
// Register load events ...
|
|
||||||
designer = new Designer(options, container);
|
|
||||||
designer.addEvent('loadSuccess', () => {
|
|
||||||
window.mindmapLoadReady = true;
|
|
||||||
console.log("Map loadded successfully");
|
|
||||||
});
|
|
||||||
|
|
||||||
const onerrorFn = function onerror(message, url, lineNo) {
|
|
||||||
// Ignore errors ...
|
|
||||||
if (message === 'Script error.' && lineNo == 0) {
|
|
||||||
// http://stackoverflow.com/questions/5913978/cryptic-script-error-reported-in-javascript-in-chrome-and-firefox
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transform error ...
|
|
||||||
let errorMsg = message;
|
|
||||||
if (typeof (message) === 'object' && message.srcElement && message.target) {
|
|
||||||
if (message.srcElement == '[object HTMLScriptElement]' && message.target == '[object HTMLScriptElement]') {
|
|
||||||
errorMsg = 'Error loading script';
|
|
||||||
} else {
|
|
||||||
errorMsg = `Event Error - target:${message.target} srcElement:${message.srcElement}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
errorMsg = errorMsg.toString();
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
method: 'post',
|
|
||||||
url: '/c/restful/logger/editor',
|
|
||||||
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
|
|
||||||
data: JSON.stringify({
|
|
||||||
jsErrorMsg: `Message: '${errorMsg}', line:'${lineNo}', url: :${url}`,
|
|
||||||
jsStack: window.event.error.stack || window.errorStack,
|
|
||||||
userAgent: navigator.userAgent,
|
|
||||||
mapId: options.mapId,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
// Close loading dialog ...
|
|
||||||
if (window.waitDialog) {
|
|
||||||
window.waitDialog.close();
|
|
||||||
window.waitDialog = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open error dialog only in case of mindmap loading errors. The rest of the error are reported but not display the dialog.
|
|
||||||
// Remove this in the near future.
|
|
||||||
if (!window.mindmapLoadReady) {
|
|
||||||
$notifyModal($msg('UNEXPECTED_ERROR_LOADING'));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
window.onerror = onerrorFn;
|
|
||||||
|
|
||||||
// Configure default persistence manager ...
|
|
||||||
let persistence;
|
|
||||||
if (options.persistenceManager) {
|
|
||||||
if (typeof options.persistenceManager === 'string') {
|
|
||||||
const managerClass = /^mindplot\.(\w+)/.exec(options.persistenceManager);
|
|
||||||
if (managerClass){
|
|
||||||
persistence = new mindplot[managerClass[1]]('samples/{id}.xml');
|
|
||||||
} else {
|
|
||||||
persistence = eval(`new ${options.persistenceManager}()`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
persistence = options.persistenceManager;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
persistence = new LocalStorageManager('samples/{id}.xml');
|
|
||||||
}
|
|
||||||
PersistenceManager.init(persistence);
|
|
||||||
|
|
||||||
// Register toolbar event ...
|
|
||||||
if ($('#toolbar')) {
|
|
||||||
const menu = new Menu(designer, 'toolbar', options.mapId, '');
|
|
||||||
|
|
||||||
// If a node has focus, focus can be move to another node using the keys.
|
|
||||||
designer._cleanScreen = function () {
|
|
||||||
menu.clear();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return designer;
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadDesignerOptions(jsonConf) {
|
|
||||||
// Load map options ...
|
|
||||||
let result;
|
|
||||||
if (jsonConf) {
|
|
||||||
$.ajax({
|
|
||||||
url: jsonConf,
|
|
||||||
dataType: 'json',
|
|
||||||
async: false,
|
|
||||||
method: 'get',
|
|
||||||
success(options) {
|
|
||||||
result = options;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Set workspace screen size as default. In this way, resize issues are solved.
|
|
||||||
const containerSize = {
|
|
||||||
height: parseInt(screen.height),
|
|
||||||
width: parseInt(screen.width),
|
|
||||||
};
|
|
||||||
|
|
||||||
const viewPort = {
|
|
||||||
height: parseInt(window.innerHeight - 70), // Footer and Header
|
|
||||||
width: parseInt(window.innerWidth),
|
|
||||||
};
|
|
||||||
result = {
|
|
||||||
readOnly: false,
|
|
||||||
zoom: 0.85,
|
|
||||||
saveOnLoad: true,
|
|
||||||
size: containerSize,
|
|
||||||
viewPort,
|
|
||||||
container: 'mindplot',
|
|
||||||
locale: 'en',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show loading dialog ...
|
|
||||||
$(() => {
|
|
||||||
import('../../../../../../libraries/bootstrap').then(() => {
|
|
||||||
// from viewmode.html ---------
|
|
||||||
var mapId = 'welcome';
|
|
||||||
// Set readonly option ...
|
|
||||||
var options = loadDesignerOptions();
|
|
||||||
// options.readOnly = true;
|
|
||||||
var designer = buildDesigner(options);
|
|
||||||
|
|
||||||
// Load map from XML file persisted on disk...
|
|
||||||
const persistence = PersistenceManager.getInstance();
|
|
||||||
var mindmap = persistence.load(mapId);
|
|
||||||
designer.loadMap(mindmap);
|
|
||||||
// from viewmode.html ---------
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
25
packages/mindplot/test/playground/map-render/js/embedded.js
Normal file
25
packages/mindplot/test/playground/map-render/js/embedded.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import '../css/embedded.less';
|
||||||
|
import { buildDesigner, loadDesignerOptions, loadExample } from './loader';
|
||||||
|
import { Mindmap, PersistenceManager } from '../../../../src';
|
||||||
|
|
||||||
|
const example = async () => {
|
||||||
|
const mapId = 'welcome';
|
||||||
|
// Options has been defined in by a external ile ?
|
||||||
|
const queryString = window.location.search;
|
||||||
|
const confUrl = queryString.replace('?confUrl=', '');
|
||||||
|
const options = await loadDesignerOptions(confUrl);
|
||||||
|
const designer = buildDesigner(options);
|
||||||
|
|
||||||
|
// Load map from XML file persisted on disk...
|
||||||
|
const persistence = PersistenceManager.getInstance();
|
||||||
|
let mindmap;
|
||||||
|
try {
|
||||||
|
mindmap = persistence.load(mapId);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('The map could not be loaded, loading an empty map instead.', e);
|
||||||
|
mindmap = Mindmap.buildEmpty(mapId);
|
||||||
|
}
|
||||||
|
designer.loadMap(mindmap);
|
||||||
|
};
|
||||||
|
|
||||||
|
loadExample(example);
|
File diff suppressed because one or more lines are too long
167
packages/mindplot/test/playground/map-render/js/loader.js
Normal file
167
packages/mindplot/test/playground/map-render/js/loader.js
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2015] [wisemapping]
|
||||||
|
*
|
||||||
|
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||||
|
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||||
|
* "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
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { $assert } from '@wisemapping/core-js';
|
||||||
|
import { PersistenceManager, Designer, LocalStorageManager, Menu } from '../../../../src/';
|
||||||
|
import * as mindplot from '../../../../src/';
|
||||||
|
|
||||||
|
import $ from 'jquery';
|
||||||
|
global.jQuery = $;
|
||||||
|
global.$ = $;
|
||||||
|
|
||||||
|
let designer = null;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Disclaimer: this global variable is a temporary workaround to Mootools' Browser class
|
||||||
|
* We need to avoid browser detection and replace it with feature detection,
|
||||||
|
* jquery recommends: http://www.modernizr.com/
|
||||||
|
*/
|
||||||
|
|
||||||
|
global.Browser = {
|
||||||
|
firefox: window.globalStorage,
|
||||||
|
ie: document.all && !window.opera,
|
||||||
|
ie6: !window.XMLHttpRequest,
|
||||||
|
ie7: document.all && window.XMLHttpRequest && !XDomainRequest && !window.opera,
|
||||||
|
ie8: document.documentMode == 8,
|
||||||
|
ie11: document.documentMode == 11,
|
||||||
|
opera: Boolean(window.opera),
|
||||||
|
chrome: Boolean(window.chrome),
|
||||||
|
safari: window.getComputedStyle && !window.globalStorage && !window.opera,
|
||||||
|
Platform: {
|
||||||
|
mac: navigator.platform.indexOf('Mac') != -1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export function buildDesigner(options) {
|
||||||
|
const container = $(`#${options.container}`);
|
||||||
|
$assert(container, 'container could not be null');
|
||||||
|
|
||||||
|
// Register load events ...
|
||||||
|
designer = new Designer(options, container);
|
||||||
|
designer.addEvent('loadSuccess', () => {
|
||||||
|
window.mindmapLoadReady = true;
|
||||||
|
console.log('Map loadded successfully');
|
||||||
|
});
|
||||||
|
|
||||||
|
const onerrorFn = function onerror(message, url, lineNo) {
|
||||||
|
// Ignore errors ...
|
||||||
|
if (message === 'Script error.' && lineNo == 0) {
|
||||||
|
// http://stackoverflow.com/questions/5913978/cryptic-script-error-reported-in-javascript-in-chrome-and-firefox
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transform error ...
|
||||||
|
let errorMsg = message;
|
||||||
|
if (typeof message === 'object' && message.srcElement && message.target) {
|
||||||
|
if (
|
||||||
|
message.srcElement == '[object HTMLScriptElement]' &&
|
||||||
|
message.target == '[object HTMLScriptElement]'
|
||||||
|
) {
|
||||||
|
errorMsg = 'Error loading script';
|
||||||
|
} else {
|
||||||
|
errorMsg = `Event Error - target:${message.target} srcElement:${message.srcElement}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errorMsg = errorMsg.toString();
|
||||||
|
|
||||||
|
// Close loading dialog ...
|
||||||
|
if (window.waitDialog) {
|
||||||
|
window.waitDialog.close();
|
||||||
|
window.waitDialog = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open error dialog only in case of mindmap loading errors. The rest of the error are reported but not display the dialog.
|
||||||
|
// Remove this in the near future.
|
||||||
|
if (!window.mindmapLoadReady) {
|
||||||
|
$notifyModal($msg('UNEXPECTED_ERROR_LOADING'));
|
||||||
|
}
|
||||||
|
|
||||||
|
console.error(errorMsg, 'line:', lineNo, 'url:', url);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onerror = onerrorFn;
|
||||||
|
|
||||||
|
// Configure default persistence manager ...
|
||||||
|
let persistence;
|
||||||
|
if (options.persistenceManager) {
|
||||||
|
if (typeof options.persistenceManager === 'string') {
|
||||||
|
const managerClass = /^mindplot\.(\w+)/.exec(options.persistenceManager);
|
||||||
|
if (managerClass) {
|
||||||
|
persistence = new mindplot[managerClass[1]]('samples/{id}.xml');
|
||||||
|
} else {
|
||||||
|
persistence = eval(`new ${options.persistenceManager}()`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
persistence = options.persistenceManager;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
persistence = new LocalStorageManager('samples/{id}.xml');
|
||||||
|
}
|
||||||
|
PersistenceManager.init(persistence);
|
||||||
|
|
||||||
|
// Register toolbar event ...
|
||||||
|
if ($('#toolbar').length) {
|
||||||
|
const menu = new Menu(designer, 'toolbar', options.mapId, '');
|
||||||
|
|
||||||
|
// If a node has focus, focus can be move to another node using the keys.
|
||||||
|
designer._cleanScreen = function () {
|
||||||
|
menu.clear();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return designer;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadDesignerOptions(jsonConf) {
|
||||||
|
// Load map options ...
|
||||||
|
let result;
|
||||||
|
if (jsonConf) {
|
||||||
|
result = await $.ajax({
|
||||||
|
url: jsonConf,
|
||||||
|
dataType: 'json',
|
||||||
|
method: 'get',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Set workspace screen size as default. In this way, resize issues are solved.
|
||||||
|
const containerSize = {
|
||||||
|
height: parseInt(screen.height),
|
||||||
|
width: parseInt(screen.width),
|
||||||
|
};
|
||||||
|
|
||||||
|
const viewPort = {
|
||||||
|
height: parseInt(window.innerHeight - 70), // Footer and Header
|
||||||
|
width: parseInt(window.innerWidth),
|
||||||
|
};
|
||||||
|
result = {
|
||||||
|
readOnly: false,
|
||||||
|
zoom: 0.85,
|
||||||
|
saveOnLoad: true,
|
||||||
|
size: containerSize,
|
||||||
|
viewPort,
|
||||||
|
container: 'mindplot',
|
||||||
|
locale: 'en',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function loadExample(exampleFn) {
|
||||||
|
$(() => {
|
||||||
|
// Hack: load bootstrap first
|
||||||
|
import('@libraries/bootstrap').then(exampleFn);
|
||||||
|
});
|
||||||
|
}
|
24
packages/mindplot/test/playground/map-render/js/viewmode.js
Normal file
24
packages/mindplot/test/playground/map-render/js/viewmode.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import '../css/embedded.less';
|
||||||
|
import { buildDesigner, loadDesignerOptions, loadExample } from './loader';
|
||||||
|
import { Mindmap, PersistenceManager } from '../../../../src';
|
||||||
|
|
||||||
|
const example = async () => {
|
||||||
|
const mapId = 'welcome';
|
||||||
|
// Set readonly option ...
|
||||||
|
const options = await loadDesignerOptions();
|
||||||
|
options.readOnly = true;
|
||||||
|
const designer = buildDesigner(options);
|
||||||
|
|
||||||
|
// Load map from XML file persisted on disk...
|
||||||
|
const persistence = PersistenceManager.getInstance();
|
||||||
|
let mindmap;
|
||||||
|
try {
|
||||||
|
mindmap = persistence.load(mapId);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('The map could not be loaded, loading an empty map instead.', e);
|
||||||
|
mindmap = Mindmap.buildEmpty(mapId);
|
||||||
|
}
|
||||||
|
designer.loadMap(mindmap);
|
||||||
|
};
|
||||||
|
|
||||||
|
loadExample(example);
|
@ -7,6 +7,8 @@ const CopyPlugin = require('copy-webpack-plugin');
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
layout: path.resolve(__dirname, './test/playground/layout/context-loader'),
|
layout: path.resolve(__dirname, './test/playground/layout/context-loader'),
|
||||||
|
viewmode: path.resolve(__dirname, './test/playground/map-render/js/viewmode'),
|
||||||
|
embedded: path.resolve(__dirname, './test/playground/map-render/js/embedded'),
|
||||||
editor: path.resolve(__dirname, './test/playground/map-render/js/editor'),
|
editor: path.resolve(__dirname, './test/playground/map-render/js/editor'),
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
@ -35,9 +37,19 @@ module.exports = {
|
|||||||
exclude: [
|
exclude: [
|
||||||
/node_modules/,
|
/node_modules/,
|
||||||
path.resolve(__dirname, '../../libraries/mootools-core-1.4.5'),
|
path.resolve(__dirname, '../../libraries/mootools-core-1.4.5'),
|
||||||
|
path.resolve(__dirname, '../../libraries/underscore-min'),
|
||||||
/lib\/raphael/ig,
|
/lib\/raphael/ig,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
test: /\.less$/i,
|
||||||
|
use: [
|
||||||
|
// compiles Less to CSS
|
||||||
|
'style-loader',
|
||||||
|
'css-loader?url=false',
|
||||||
|
'less-loader',
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
resolve: {
|
resolve: {
|
||||||
@ -54,13 +66,13 @@ module.exports = {
|
|||||||
{ from: 'test/playground/map-render/images/favicon.ico', to: 'favicon.ico' },
|
{ from: 'test/playground/map-render/images/favicon.ico', to: 'favicon.ico' },
|
||||||
{ from: 'test/playground/map-render/images', to: 'images' },
|
{ from: 'test/playground/map-render/images', to: 'images' },
|
||||||
{ from: 'test/playground/map-render/icons', to: 'icons' },
|
{ from: 'test/playground/map-render/icons', to: 'icons' },
|
||||||
{ from: 'test/playground/map-render/css', to: 'css' },
|
|
||||||
{ from: 'test/playground/map-render/js', to: 'js' },
|
{ from: 'test/playground/map-render/js', to: 'js' },
|
||||||
{ from: 'test/playground/map-render/samples', to: 'samples' },
|
{ from: 'test/playground/map-render/samples', to: 'samples' },
|
||||||
{ from: 'test/playground/map-render/bootstrap', to: 'bootstrap' },
|
{ from: 'test/playground/map-render/bootstrap', to: 'bootstrap' },
|
||||||
{ from: 'test/playground/index.html', to: 'index.html' },
|
{ from: 'test/playground/index.html', to: 'index.html' },
|
||||||
{ from: 'test/playground/map-render/html/container.json', to: 'html/container.json' },
|
{ from: 'test/playground/map-render/html/container.json', to: 'html/container.json' },
|
||||||
{ from: 'test/playground/map-render/html/container.html', to: 'container.html' },
|
{ from: 'test/playground/map-render/html/container.html', to: 'container.html' },
|
||||||
|
{ from: 'test/playground/map-render/css/widget', to: 'css/widget' },
|
||||||
],
|
],
|
||||||
}),
|
}),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
@ -69,12 +81,12 @@ module.exports = {
|
|||||||
template: 'test/playground/layout/index.html',
|
template: 'test/playground/layout/index.html',
|
||||||
}),
|
}),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
chunks: ['editor'],
|
chunks: ['viewmode'],
|
||||||
filename: 'viewmode.html',
|
filename: 'viewmode.html',
|
||||||
template: 'test/playground/map-render/html/viewmode.html',
|
template: 'test/playground/map-render/html/viewmode.html',
|
||||||
}),
|
}),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
chunks: ['editor'],
|
chunks: ['embedded'],
|
||||||
filename: 'embedded.html',
|
filename: 'embedded.html',
|
||||||
template: 'test/playground/map-render/html/embedded.html',
|
template: 'test/playground/map-render/html/embedded.html',
|
||||||
}),
|
}),
|
||||||
|
73
yarn.lock
73
yarn.lock
@ -4199,6 +4199,13 @@ cookie@0.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
|
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba"
|
||||||
integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
|
integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==
|
||||||
|
|
||||||
|
copy-anything@^2.0.1:
|
||||||
|
version "2.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.3.tgz#842407ba02466b0df844819bbe3baebbe5d45d87"
|
||||||
|
integrity sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ==
|
||||||
|
dependencies:
|
||||||
|
is-what "^3.12.0"
|
||||||
|
|
||||||
copy-concurrently@^1.0.0:
|
copy-concurrently@^1.0.0:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
|
resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
|
||||||
@ -5055,7 +5062,7 @@ err-code@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960"
|
resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960"
|
||||||
integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=
|
integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=
|
||||||
|
|
||||||
errno@^0.1.3:
|
errno@^0.1.1, errno@^0.1.3:
|
||||||
version "0.1.8"
|
version "0.1.8"
|
||||||
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f"
|
resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f"
|
||||||
integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==
|
integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==
|
||||||
@ -6740,7 +6747,7 @@ hyphenate-style-name@^1.0.3:
|
|||||||
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
|
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
|
||||||
integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
|
integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
|
||||||
|
|
||||||
iconv-lite@0.4.24, iconv-lite@^0.4.24:
|
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
|
||||||
version "0.4.24"
|
version "0.4.24"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||||
@ -6802,6 +6809,11 @@ iltorb@^2.0.1:
|
|||||||
prebuild-install "^5.3.3"
|
prebuild-install "^5.3.3"
|
||||||
which-pm-runs "^1.0.0"
|
which-pm-runs "^1.0.0"
|
||||||
|
|
||||||
|
image-size@~0.5.0:
|
||||||
|
version "0.5.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c"
|
||||||
|
integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=
|
||||||
|
|
||||||
immer@^9.0.7:
|
immer@^9.0.7:
|
||||||
version "9.0.7"
|
version "9.0.7"
|
||||||
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.7.tgz#b6156bd7db55db7abc73fd2fdadf4e579a701075"
|
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.7.tgz#b6156bd7db55db7abc73fd2fdadf4e579a701075"
|
||||||
@ -7387,6 +7399,11 @@ is-weakref@^1.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
call-bind "^1.0.2"
|
call-bind "^1.0.2"
|
||||||
|
|
||||||
|
is-what@^3.12.0:
|
||||||
|
version "3.14.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1"
|
||||||
|
integrity sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==
|
||||||
|
|
||||||
is-windows@^1.0.0, is-windows@^1.0.2:
|
is-windows@^1.0.0, is-windows@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
|
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
|
||||||
@ -7782,6 +7799,30 @@ lerna@^3.16.4:
|
|||||||
import-local "^2.0.0"
|
import-local "^2.0.0"
|
||||||
npmlog "^4.1.2"
|
npmlog "^4.1.2"
|
||||||
|
|
||||||
|
less-loader@^10.2.0:
|
||||||
|
version "10.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-10.2.0.tgz#97286d8797dc3dc05b1d16b0ecec5f968bdd4e32"
|
||||||
|
integrity sha512-AV5KHWvCezW27GT90WATaDnfXBv99llDbtaj4bshq6DvAihMdNjaPDcUMa6EXKLRF+P2opFenJp89BXg91XLYg==
|
||||||
|
dependencies:
|
||||||
|
klona "^2.0.4"
|
||||||
|
|
||||||
|
less@^4.1.2:
|
||||||
|
version "4.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/less/-/less-4.1.2.tgz#6099ee584999750c2624b65f80145f8674e4b4b0"
|
||||||
|
integrity sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA==
|
||||||
|
dependencies:
|
||||||
|
copy-anything "^2.0.1"
|
||||||
|
parse-node-version "^1.0.1"
|
||||||
|
tslib "^2.3.0"
|
||||||
|
optionalDependencies:
|
||||||
|
errno "^0.1.1"
|
||||||
|
graceful-fs "^4.1.2"
|
||||||
|
image-size "~0.5.0"
|
||||||
|
make-dir "^2.1.0"
|
||||||
|
mime "^1.4.1"
|
||||||
|
needle "^2.5.2"
|
||||||
|
source-map "~0.6.0"
|
||||||
|
|
||||||
levn@^0.3.0, levn@~0.3.0:
|
levn@^0.3.0, levn@~0.3.0:
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
|
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
|
||||||
@ -8374,7 +8415,7 @@ mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.19,
|
|||||||
dependencies:
|
dependencies:
|
||||||
mime-db "1.51.0"
|
mime-db "1.51.0"
|
||||||
|
|
||||||
mime@1.6.0:
|
mime@1.6.0, mime@^1.4.1:
|
||||||
version "1.6.0"
|
version "1.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||||
@ -8652,6 +8693,15 @@ natural-compare@^1.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||||
|
|
||||||
|
needle@^2.5.2:
|
||||||
|
version "2.9.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/needle/-/needle-2.9.1.tgz#22d1dffbe3490c2b83e301f7709b6736cd8f2684"
|
||||||
|
integrity sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==
|
||||||
|
dependencies:
|
||||||
|
debug "^3.2.6"
|
||||||
|
iconv-lite "^0.4.4"
|
||||||
|
sax "^1.2.4"
|
||||||
|
|
||||||
negotiator@0.6.2:
|
negotiator@0.6.2:
|
||||||
version "0.6.2"
|
version "0.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
|
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
|
||||||
@ -9318,6 +9368,11 @@ parse-json@^5.0.0:
|
|||||||
json-parse-even-better-errors "^2.3.0"
|
json-parse-even-better-errors "^2.3.0"
|
||||||
lines-and-columns "^1.1.6"
|
lines-and-columns "^1.1.6"
|
||||||
|
|
||||||
|
parse-node-version@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b"
|
||||||
|
integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==
|
||||||
|
|
||||||
parse-path@^4.0.0:
|
parse-path@^4.0.0:
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-4.0.3.tgz#82d81ec3e071dcc4ab49aa9f2c9c0b8966bb22bf"
|
resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-4.0.3.tgz#82d81ec3e071dcc4ab49aa9f2c9c0b8966bb22bf"
|
||||||
@ -10617,6 +10672,11 @@ sass-loader@^10.1.0:
|
|||||||
schema-utils "^3.0.0"
|
schema-utils "^3.0.0"
|
||||||
semver "^7.3.2"
|
semver "^7.3.2"
|
||||||
|
|
||||||
|
sax@^1.2.4:
|
||||||
|
version "1.2.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||||
|
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
||||||
|
|
||||||
scheduler@^0.20.2:
|
scheduler@^0.20.2:
|
||||||
version "0.20.2"
|
version "0.20.2"
|
||||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
|
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
|
||||||
@ -11805,7 +11865,7 @@ tslib@^1.8.1, tslib@^1.9.0:
|
|||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||||
|
|
||||||
tslib@^2.0.1, tslib@^2.0.3, tslib@^2.2.0:
|
tslib@^2.0.1, tslib@^2.0.3, tslib@^2.2.0, tslib@^2.3.0:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
|
||||||
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
|
integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
|
||||||
@ -11933,6 +11993,11 @@ undefsafe@^2.0.5:
|
|||||||
resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c"
|
resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c"
|
||||||
integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==
|
integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==
|
||||||
|
|
||||||
|
underscore@^1.13.1:
|
||||||
|
version "1.13.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.1.tgz#0c1c6bd2df54b6b69f2314066d65b6cde6fcf9d1"
|
||||||
|
integrity sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==
|
||||||
|
|
||||||
unicode-canonical-property-names-ecmascript@^2.0.0:
|
unicode-canonical-property-names-ecmascript@^2.0.0:
|
||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc"
|
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc"
|
||||||
|
Loading…
Reference in New Issue
Block a user