Migrate web2d to typescript

This commit is contained in:
Paulo Veiga 2023-02-10 02:51:52 +00:00
parent 44a6c19912
commit a837d5b01a
198 changed files with 2295 additions and 2384 deletions

3
.gitignore vendored
View File

@ -28,3 +28,6 @@ wisemapping-frontend.code-workspace
!.yarn/releases
!.yarn/plugins
.pnp.*
packages/**/.yalc/
packages/**/yalc.lock

View File

@ -1,7 +1,7 @@
{
"name": "wisemapping-front-end",
"scripts": {
"bootstrap": "lerna bootstrap",
"bootstrap": "lerna run bootstrap",
"build": "lerna run build",
"clean": "lerna clean && rm -rf node_modules",
"lint": "lerna run lint --stream",

View File

@ -4,7 +4,7 @@
"description": "WiseMapping - Core Common Libraries",
"homepage": "http://www.wisemapping.org/",
"license": "MIT",
"main": "dist/core.js",
"main": "src/index.ts",
"files": [
"src"
],
@ -17,6 +17,7 @@
},
"scripts": {
"build": "webpack --config webpack.prod.js",
"dev": "webpack --mode development --config webpack.dev.js"
"dev": "webpack --mode development --config webpack.dev.js",
"bootstrap": "yalc publish"
}
}

View File

@ -1,93 +0,0 @@
/*
* 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.
*/
/**
* Cross-browser implementation of creating an XML document object.
*/
export const createDocument = function () {
var doc = null;
if ($defined(window.ActiveXObject)) {
//http://blogs.msdn.com/b/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx
var progIDs = ['Msxml2.DOMDocument.6.0', 'Msxml2.DOMDocument.3.0'];
for (var i = 0; i < progIDs.length; i++) {
try {
doc = new ActiveXObject(progIDs[i]);
break;
} catch (ex) {}
}
} else if (window.document.implementation && window.document.implementation.createDocument) {
doc = window.document.implementation.createDocument('', '', null);
}
$assert(doc, 'Parser could not be instantiated');
return doc;
};
/*
Function: $defined
Returns true if the passed in value/object is defined, that means is not null or undefined.
Arguments:
obj - object to inspect
*/
export const $defined = function (obj) {
return obj != undefined;
};
export const $assert = function (assert, message) {
if (!$defined(assert) || !assert) {
logStackTrace();
console.log(message);
throw new Error(message);
}
};
export const sign = function (value) {
return value >= 0 ? 1 : -1;
};
export function logStackTrace(exception) {
if (!$defined(exception)) {
try {
throw Error('Unexpected Exception');
} catch (e) {
exception = e;
}
}
var result = '';
if (exception.stack) {
//Firefox and Chrome...
result = exception.stack;
} else if (window.opera && exception.message) {
//Opera
result = exception.message;
} else {
//IE and Safari
result = exception.sourceURL + ': ' + exception.line + '\n\n';
var currentFunction = arguments.callee.caller;
while (currentFunction) {
var fn = currentFunction.toString();
result = result + '\n' + fn;
currentFunction = currentFunction.caller;
}
}
window.errorStack = result;
return result;
}

View File

@ -0,0 +1,45 @@
/*
* 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.
*/
export const createDocument = (): Document => {
var doc: Document | null = null;
if (window.document.implementation?.createDocument) {
doc = window.document.implementation.createDocument('', '', null);
}
if (!doc) {
throw new Error('Document could not be initialized');
}
return doc;
};
export const $defined = (obj: any) => {
return obj != undefined && obj != null;
};
export const $assert = (assert, message: string): void => {
if (!$defined(assert) || !assert) {
console.error(message);
throw new Error(message);
}
};
export const sign = (value: number): 1 | -1 => {
return value >= 0 ? 1 : -1;
};

View File

@ -0,0 +1,31 @@
{
"compilerOptions": {
"outDir": "./dist/",
"sourceMap": true,
"module": "amd",
"moduleResolution": "node",
"target": "es6",
"allowJs": true,
"strict": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"declaration": true,
"strictNullChecks": true,
"noImplicitAny": false,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"strictFunctionTypes": true,
"rootDirs": [
"src",
]
},
"include": [
"src/**/*", "storybook/src/stories",
],
"exclude": [
"node_modules"
]
}

View File

@ -5,15 +5,11 @@ const common = require('../../webpack.common');
const prodConfig = {
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'core.js',
publicPath: '',
filename: 'index.ts',
library: {
type: 'umd',
},
},
target: 'web',
}
};
module.exports = merge(common, prodConfig);

View File

@ -4,6 +4,11 @@ const common = require('./webpack.common');
const prodConfig = {
mode: 'production',
devtool: 'source-map',
output: {
library: {
type: 'umd',
},
},
optimization: {
splitChunks: {
chunks: 'all',

View File

@ -74,7 +74,7 @@ describe('Topic Shape Suite', () => {
.invoke('attr', 'rx')
.then(parseInt)
.should('be.a', 'number')
.should('be.gte', 12);
.should('be.gte', 11);
cy.get('[test-id=2] > rect')
.eq(1)
.invoke('attr', 'rx')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 119 KiB

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 93 KiB

View File

@ -3,6 +3,7 @@
"version": "0.4.2",
"main": "dist/editor.bundle.js",
"scripts": {
"bootstrap": "yalc publish;yalc add @wisemapping/mindplot",
"build": "webpack --config webpack.prod.js",
"playground": "webpack serve --config webpack.playground.js",
"cy:run": "cypress run",

View File

@ -11,8 +11,5 @@
"@babel/preset-typescript"
]
],
"plugins": [
"@babel/plugin-proposal-class-properties"
],
"sourceType": "module"
}

View File

@ -10,7 +10,7 @@ module.exports = defineConfig({
setupNodeEvents(on, config) {
return require('./cypress/plugins/index.js')(on, config)
},
baseUrl: 'http://localhost:8083',
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}',
baseUrl: 'http://localhost:6006',
specPattern: 'cypress/e2e/**/*.{js,ts}',
},
})

View File

@ -0,0 +1,7 @@
context('Layout suite', () => {
it('basic layout', () => {
cy.visit('/iframe.html?args=&id=mindplot-layout--basic-suite&viewMode=story');
cy.wait(2000);
cy.matchImageSnapshot('layout-suite');
});
});

View File

@ -1,11 +0,0 @@
context('Playground', () => {
it('the playground layout page should match its snapshot', () => {
// TODO: check why this error is happening, and remove this handling
cy.on('uncaught:exception', (err) => {
expect(err.message).to.include('Prediction is incorrectly positioned');
return false;
});
cy.visit('/layout.html');
cy.matchImageSnapshot('layout');
});
});

View File

@ -0,0 +1,36 @@
context('Topic suite', () => {
it('topic border', () => {
cy.visit('/iframe.html?args=&id=mindplot-topic--border-style&viewMode=story');
cy.matchImageSnapshot('topic-border');
});
it('topic style', () => {
cy.visit('/iframe.html?args=&id=mindplot-topic--font-style&viewMode=story');
cy.matchImageSnapshot('topic-style');
});
it('topic color', () => {
cy.visit('/iframe.html?args=&id=mindplot-topic--background-color&viewMode=story');
cy.matchImageSnapshot('topic-color');
});
it('topic note', () => {
cy.visit('/iframe.html?args=&id=mindplot-topic--note-feature&viewMode=story');
cy.matchImageSnapshot('topic-note');
});
it('topic link feature', () => {
cy.visit('/iframe.html?args=&id=mindplot-topic--link-feature&viewMode=story');
cy.matchImageSnapshot('topic-link-feature');
});
it('topic icon feature', () => {
cy.visit('/iframe.html?args=&id=mindplot-topic--icon-feature&viewMode=story');
cy.matchImageSnapshot('topic-icon-feature');
});
it('topic shape line', () => {
cy.visit('/iframe.html?args=&id=mindplot-topic--shape-line&viewMode=story');
cy.matchImageSnapshot('topic-shape-line');
});
it('topic ellipse line', () => {
cy.visit('/iframe.html?args=&id=mindplot-topic--shape-ellipse&viewMode=story');
cy.matchImageSnapshot('topic-shape-ellipse');
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -16,5 +16,14 @@
// Import commands.js using ES2015 syntax:
import './commands';
// Alternatively you can use CommonJS syntax:
// require('./commands')
Cypress.on('window:before:load', (win) => {
cy.spy(win.console, 'error');
cy.spy(win.console, 'warn');
});
afterEach(() => {
cy.window().then((win) => {
expect(win.console.error).to.have.callCount(0);
expect(win.console.warn).to.have.callCount(0);
});
});

View File

@ -4,7 +4,8 @@ const config = {
preset: 'ts-jest',
moduleFileExtensions: ['js', 'ts'],
transform: {
'^.+\\.js?$': 'babel-jest',
'^.+\\.(ts)?$': 'ts-jest',
'^.+\\.(js)$': 'babel-jest',
},
};

View File

@ -10,8 +10,7 @@
"main": "src/index.ts",
"files": [
"src",
"assets",
"dist"
"assets"
],
"publishConfig": {
"registry": "https://registry.yarnpkg.com"
@ -21,16 +20,16 @@
"url": "git@bitbucket.org:wisemapping/wisemapping-frontend.git"
},
"scripts": {
"bootstrap": "yalc publish;yalc add @wisemapping/core-js;yalc add @wisemapping/web2d",
"build": "webpack --config webpack.prod.js",
"dev": "webpack serve --config webpack.dev.js",
"lint": "eslint src --ext js,ts",
"playground": "webpack serve --config webpack.playground.js",
"cy:run": "cypress run",
"cy:open": "cypress open",
"test:unit": "jest ./test/unit/export/*.ts ./test/unit/import/*.ts ./test/unit/layout/*.js --verbose --silent --detectOpenHandles",
"test:integration": "start-server-and-test playground http-get://localhost:8083 cy:run",
"test:unit": "jest ./test/unit/export/*.ts ./test/unit/import/*.ts --verbose --silent --detectOpenHandles",
"test:integration": "start-server-and-test storybook http-get://localhost:6006 cy:run",
"test": "yarn test:unit && yarn test:integration",
"storybook": "start-storybook -p 6006",
"storybook": "start-storybook -p 6006 --no-open",
"build-storybook": "build-storybook"
},
"dependencies": {
@ -58,6 +57,8 @@
"blob-polyfill": "^6.0.20211015",
"cypress": "^12.3.0",
"cypress-image-snapshot": "^4.0.1",
"mocha": "^9.1.3"
"jest": "^29.4.1",
"mocha": "^9.1.3",
"start-server-and-test": "^1.15.3"
}
}

View File

@ -18,7 +18,6 @@
* limitations under the License.
*/
import { $assert } from '@wisemapping/core-js';
import Point from '@wisemapping/web2d';
import { Mindmap } from '..';
import CommandContext from './CommandContext';
import { PivotType } from './RelationshipControlPoints';
@ -51,12 +50,12 @@ abstract class ActionDispatcher extends Events {
abstract dragTopic(
topicId: number,
position: Point,
position: PositionType,
order: number | null,
parentTopic: Topic | null,
): void;
abstract moveTopic(topicId: number, position: Point): void;
abstract moveTopic(topicId: number, position: PositionType): void;
abstract moveControlPoint(
model: RelationshipModel,

View File

@ -15,12 +15,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { $assert, $defined } from '@wisemapping/core-js';
import { Workspace as Workspace2D, ElementClass as Element2D } from '@wisemapping/web2d';
import { $assert } from '@wisemapping/core-js';
import { Workspace as Workspace2D, ElementClass, ElementPeer } from '@wisemapping/web2d';
import ScreenManager from './ScreenManager';
import SizeType from './SizeType';
import CanvasElement from './CanvasElement';
class Workspace {
class Canvas {
private _zoom: number;
private _screenManager: ScreenManager;
@ -35,10 +36,14 @@ class Workspace {
private _visibleAreaSize!: SizeType;
private _renderQueue: Element2D[];
private _renderQueue: (ElementClass<ElementPeer> | CanvasElement)[];
private _queueRenderEnabled: boolean;
private _mouseMoveListener;
private _mouseUpListener;
constructor(screenManager: ScreenManager, zoom: number, isReadOnly: boolean) {
// Create a suitable container ...
$assert(screenManager, 'Div container can not be null');
@ -64,6 +69,8 @@ class Workspace {
this._renderQueue = [];
this._eventsEnabled = false;
this._queueRenderEnabled = false;
this._mouseMoveListener = null;
this._mouseUpListener = null;
}
private _adjustWorkspace(): void {
@ -105,7 +112,7 @@ class Workspace {
return new Workspace2D(workspaceProfile);
}
append(shape: Element2D): void {
append(shape: ElementClass<ElementPeer> | CanvasElement): void {
if (this._queueRenderEnabled) {
this._renderQueue.push(shape);
} else {
@ -113,11 +120,12 @@ class Workspace {
}
}
private appendInternal(shape: Element2D): void {
if (shape.addToWorkspace) {
shape.addToWorkspace(this);
private appendInternal(shape: CanvasElement | ElementClass<ElementPeer>): void {
// eslint-disable-next-line no-prototype-builtins, dot-notation
if (typeof shape['addToWorkspace'] === 'function') {
(shape as CanvasElement).addToWorkspace(this);
} else {
this._workspace.append(shape);
this._workspace.append(shape as ElementClass<ElementPeer>);
}
}
@ -127,7 +135,7 @@ class Workspace {
let result = Promise.resolve();
if (!value) {
// eslint-disable-next-line arrow-body-style
result = Workspace.delay(100).then(() => {
result = Canvas.delay(100).then(() => {
return this.processRenderQueue(this._renderQueue.reverse(), 300);
});
}
@ -138,29 +146,35 @@ class Workspace {
return new Promise((resolve) => setTimeout(resolve, t));
}
private processRenderQueue(renderQueue: Element2D[], batch: number): Promise<void> {
private processRenderQueue(
renderQueue: (ElementClass<ElementPeer> | CanvasElement)[],
batch: number,
): Promise<void> {
let result: Promise<void>;
if (renderQueue.length > 0) {
result = new Promise((resolve: (queue: Element2D[]) => void) => {
for (let i = 0; i < batch && renderQueue.length > 0; i++) {
const elem = renderQueue.pop();
this.appendInternal(elem);
}
resolve(renderQueue);
}).then((queue) => Workspace.delay(30).then(() => this.processRenderQueue(queue, batch)));
if (renderQueue.length > 0) {
result = new Promise(
(resolve: (queue: (ElementClass<ElementPeer> | CanvasElement)[]) => void) => {
for (let i = 0; i < batch && renderQueue.length > 0; i++) {
const elem = renderQueue.pop()!;
this.appendInternal(elem);
}
resolve(renderQueue);
},
).then((queue) => Canvas.delay(30).then(() => this.processRenderQueue(queue, batch)));
} else {
result = Promise.resolve();
}
return result;
}
removeChild(shape: Element2D): void {
// Element is a node, not a web2d element?
if (shape.removeFromWorkspace) {
shape.removeFromWorkspace(this);
removeChild(shape: ElementClass<ElementPeer> | CanvasElement): void {
// eslint-disable-next-line dot-notation
if (typeof shape['removeFromWorkspace'] === 'function') {
(shape as CanvasElement).removeFromWorkspace(this);
} else {
this._workspace.removeChild(shape);
this._workspace.removeChild(shape as ElementClass<ElementPeer>);
}
}
@ -244,7 +258,7 @@ class Workspace {
return this._eventsEnabled;
}
getSVGElement() {
getSVGElement(): Element {
return this._workspace.getSVGElement();
}
@ -252,8 +266,8 @@ class Workspace {
const workspace = this._workspace;
const screenManager = this._screenManager;
const mWorkspace = this;
const mouseDownListener = function mouseDownListener(event: MouseEvent) {
if (!$defined(workspace._mouseMoveListener)) {
const mouseDownListener = (event: MouseEvent) => {
if (!this._mouseMoveListener) {
if (mWorkspace.isWorkspaceEventsEnabled()) {
mWorkspace.enableWorkspaceEvents(false);
@ -261,7 +275,7 @@ class Workspace {
const originalCoordOrigin = workspace.getCoordOrigin();
let wasDragged = false;
workspace._mouseMoveListener = (mouseMoveEvent: MouseEvent) => {
this._mouseMoveListener = (mouseMoveEvent: MouseEvent) => {
const currentMousePosition = screenManager.getWorkspaceMousePosition(mouseMoveEvent);
const offsetX = currentMousePosition.x - mouseDownPosition.x;
@ -284,17 +298,17 @@ class Workspace {
screenManager.fireEvent('update');
wasDragged = true;
};
screenManager.addEvent('mousemove', workspace._mouseMoveListener);
screenManager.addEvent('touchmove', workspace._mouseMoveListener);
screenManager.addEvent('mousemove', this._mouseMoveListener);
screenManager.addEvent('touchmove', this._mouseMoveListener);
// Register mouse up listeners ...
workspace._mouseUpListener = () => {
screenManager.removeEvent('mousemove', workspace._mouseMoveListener);
screenManager.removeEvent('mouseup', workspace._mouseUpListener);
screenManager.removeEvent('touchmove', workspace._mouseUpListener);
screenManager.removeEvent('touchend', workspace._mouseMoveListener);
workspace._mouseUpListener = null;
workspace._mouseMoveListener = null;
this._mouseUpListener = () => {
screenManager.removeEvent('mousemove', this._mouseMoveListener);
screenManager.removeEvent('mouseup', this._mouseUpListener);
screenManager.removeEvent('touchmove', this._mouseUpListener);
screenManager.removeEvent('touchend', this._mouseMoveListener);
this._mouseUpListener = null;
this._mouseMoveListener = null;
window.document.body.style.cursor = 'default';
// Update screen manager offset.
@ -306,11 +320,11 @@ class Workspace {
screenManager.fireEvent('click');
}
};
screenManager.addEvent('mouseup', workspace._mouseUpListener);
screenManager.addEvent('touchend', workspace._mouseUpListener);
screenManager.addEvent('mouseup', this._mouseUpListener);
screenManager.addEvent('touchend', this._mouseUpListener);
}
} else {
workspace._mouseUpListener();
this._mouseUpListener();
}
};
screenManager.addEvent('mousedown', mouseDownListener);
@ -322,4 +336,4 @@ class Workspace {
}
}
export default Workspace;
export default Canvas;

View File

@ -0,0 +1,9 @@
import Canvas from './Canvas';
interface CanvasElement {
addToWorkspace(workspace: Canvas): void;
removeFromWorkspace(workspace: Canvas): void;
}
export default CanvasElement;

View File

@ -15,18 +15,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Point } from '@wisemapping/web2d';
import { $assert } from '@wisemapping/core-js';
import PositionType from './PositionType';
import Topic from './Topic';
import Shape from './util/Shape';
class CentralTopic extends Topic {
_buildDragShape() {
buildDragShape() {
// Ignore ..
}
_registerEvents(): void {
super._registerEvents();
registerEvents(): void {
super.registerEvents();
// This disable the drag of the central topic.
// But solves the problem of deselecting the nodes when the screen is clicked.
@ -35,29 +35,29 @@ class CentralTopic extends Topic {
});
}
workoutIncomingConnectionPoint(): Point {
workoutIncomingConnectionPoint(): PositionType {
return this.getPosition();
}
setCursor(type: string) {
setCursor(type: string): void {
super.setCursor(type === 'move' ? 'default' : type);
}
updateTopicShape() {
updateTopicShape(): void {
// Overwite behaviour ...
}
_updatePositionOnChangeSize(): void {
// Center main topic ...
const zeroPoint = new Point(0, 0);
const zeroPoint = { x: 0, y: 0 };
this.setPosition(zeroPoint);
}
getShrinkConnector() {
getShrinkConnector(): null {
return null;
}
workoutOutgoingConnectionPoint(targetPosition: Point) {
workoutOutgoingConnectionPoint(targetPosition: PositionType) {
$assert(targetPosition, 'targetPoint can not be null');
const pos = this.getPosition();

View File

@ -16,11 +16,11 @@
* limitations under the License.
*/
import { $assert, $defined } from '@wisemapping/core-js';
import Point from '@wisemapping/web2d';
import { Designer } from '..';
import EventBus from './layout/EventBus';
import NodeModel from './model/NodeModel';
import RelationshipModel from './model/RelationshipModel';
import PositionType from './PositionType';
import Relationship from './Relationship';
import Topic from './Topic';
@ -102,7 +102,7 @@ class CommandContext {
}
/** */
moveTopic(topic: Topic, position: Point): void {
moveTopic(topic: Topic, position: PositionType): void {
$assert(topic, 'topic cannot be null');
$assert(position, 'position cannot be null');
EventBus.instance.fireEvent('topicMoved', {

View File

@ -17,10 +17,11 @@
*/
import { $assert } from '@wisemapping/core-js';
import { CurvedLine, PolyLine, Line } from '@wisemapping/web2d';
import { CurvedLine, Line, PolyLine } from '@wisemapping/web2d';
import PositionType from './PositionType';
import Topic from './Topic';
import TopicConfig from './TopicConfig';
import Workspace from './Workspace';
import Canvas from './Canvas';
// eslint-disable-next-line no-shadow
export enum LineType {
@ -51,7 +52,7 @@ class ConnectionLine {
this._color = this.updateColor();
}
private _getCtrlPoints(sourceNode: Topic, targetNode: Topic) {
private _getCtrlPoints(sourceNode: Topic, targetNode: Topic): [PositionType, PositionType] {
const srcPos = sourceNode.workoutOutgoingConnectionPoint(targetNode.getPosition());
const destPos = targetNode.workoutIncomingConnectionPoint(sourceNode.getPosition());
const deltaX = (srcPos.x - destPos.x) / 3;
@ -61,8 +62,8 @@ class ConnectionLine {
];
}
protected createLine(lineType: LineType): ConnectionLine {
let line: ConnectionLine;
protected createLine(lineType: LineType): Line {
let line: Line;
switch (lineType) {
case LineType.POLYLINE_MIDDLE:
line = new PolyLine();
@ -142,8 +143,8 @@ class ConnectionLine {
if (this._type === LineType.THICK_CURVED || this._type === LineType.THIN_CURVED) {
const ctrlPoints = this._getCtrlPoints(this._sourceTopic, this._targetTopic);
line2d.setSrcControlPoint(ctrlPoints[0]);
line2d.setDestControlPoint(ctrlPoints[1]);
(line2d as CurvedLine).setSrcControlPoint(ctrlPoints[0]);
(line2d as CurvedLine).setDestControlPoint(ctrlPoints[1]);
}
// Add connector ...
@ -179,7 +180,7 @@ class ConnectionLine {
}
setStroke(color: string, style: string, opacity: number) {
this._line.setStroke(null, null, color, opacity);
this._line.setStroke(1, style, color, opacity);
this._color = color;
}
@ -187,13 +188,13 @@ class ConnectionLine {
return this._color;
}
addToWorkspace(workspace: Workspace) {
workspace.append(this._line);
addToWorkspace(workspace: Canvas) {
workspace.append(this._line.getElementClass());
this._line.moveToBack();
}
removeFromWorkspace(workspace: Workspace) {
workspace.removeChild(this._line);
removeFromWorkspace(workspace: Canvas) {
workspace.removeChild(this._line.getElementClass());
}
getTargetTopic(): Topic {

View File

@ -18,7 +18,6 @@
import $ from 'jquery';
import { $assert, $defined } from '@wisemapping/core-js';
import Point from '@wisemapping/web2d';
import Messages, { $msg } from './Messages';
import Events from './Events';
@ -31,7 +30,7 @@ import DesignerModel from './DesignerModel';
import DesignerKeyboard from './DesignerKeyboard';
import ScreenManager from './ScreenManager';
import Workspace from './Workspace';
import Canvas from './Canvas';
import DragConnector from './DragConnector';
import DragManager from './DragManager';
@ -60,6 +59,7 @@ import { TopicShapeType } from './model/INodeModel';
import { LineType } from './ConnectionLine';
import XMLSerializerFactory from './persistence/XMLSerializerFactory';
import ImageExpoterFactory from './export/ImageExporterFactory';
import PositionType from './PositionType';
class Designer extends Events {
private _mindmap: Mindmap | null;
@ -70,7 +70,7 @@ class Designer extends Events {
private _model: DesignerModel;
private _workspace: Workspace;
private _workspace: Canvas;
_eventBussDispatcher: EventBusDispatcher;
@ -108,7 +108,7 @@ class Designer extends Events {
// Init Screen manager..
const screenManager = new ScreenManager(divElem);
this._workspace = new Workspace(screenManager, this._model.getZoom(), this.isReadOnly());
this._workspace = new Canvas(screenManager, this._model.getZoom(), this.isReadOnly());
// Init layout manager ...
this._eventBussDispatcher = new EventBusDispatcher();
@ -200,7 +200,7 @@ class Designer extends Events {
});
}
private _buildDragManager(workspace: Workspace): DragManager {
private _buildDragManager(workspace: Canvas): DragManager {
const designerModel = this.getModel();
const dragConnector = new DragConnector(designerModel, this._workspace);
const dragManager = new DragManager(workspace, this._eventBussDispatcher);
@ -504,7 +504,7 @@ class Designer extends Events {
this._actionDispatcher.addTopics([childModel], [parentTopicId]);
}
private _createChildModel(topic: Topic, mousePos: Point = null): NodeModel {
private _createChildModel(topic: Topic, mousePos?: PositionType): NodeModel {
// Create a new node ...
const parentModel = topic.getModel();
const mindmap = parentModel.getMindmap();
@ -517,7 +517,7 @@ class Designer extends Events {
// Create a new node ...
const layoutManager = this._eventBussDispatcher.getLayoutManager();
const result = layoutManager.predict(topic.getId(), null, mousePos);
const result = layoutManager.predict(topic.getId(), null, mousePos || null);
childModel.setOrder(result.order);
const { position } = result;
@ -949,7 +949,7 @@ class Designer extends Events {
this.onObjectFocusEvent(node);
}
getWorkSpace(): Workspace {
getWorkSpace(): Canvas {
return this._workspace;
}

View File

@ -21,7 +21,7 @@ import Keyboard from './Keyboard';
import { Designer } from '..';
import Topic from './Topic';
import initHotKeyPluggin from '../../../../libraries/jquery.hotkeys';
import initHotKeyPluggin from '../../libraries/jquery.hotkeys';
// Provides dispatcher of keyevents by key...
initHotKeyPluggin($);
@ -262,7 +262,7 @@ class DesignerKeyboard extends Keyboard {
const children = node.getChildren();
if (children.length > 0) {
let target = children[0];
let top = null;
let top: number | null = null;
for (let i = 0; i < children.length; i++) {
const child = children[i];
const childY = child.getPosition().y;

View File

@ -16,19 +16,19 @@
* limitations under the License.
*/
import { $assert } from '@wisemapping/core-js';
import { Point } from '@wisemapping/web2d';
import DesignerModel from './DesignerModel';
import DragTopic from './DragTopic';
import SizeType from './SizeType';
import Topic from './Topic';
import Workspace from './Workspace';
import Canvas from './Canvas';
import PositionType from './PositionType';
class DragConnector {
private _designerModel: DesignerModel;
private _workspace: Workspace;
private _workspace: Canvas;
constructor(designerModel: DesignerModel, workspace: Workspace) {
constructor(designerModel: DesignerModel, workspace: Canvas) {
$assert(designerModel, 'designerModel can not be null');
$assert(workspace, 'workspace can not be null');
@ -114,7 +114,7 @@ class DragConnector {
private _proximityWeight(
isAligned: boolean,
target: Topic,
sPos: Point,
sPos: PositionType,
currentConnection: Topic,
): number {
const tPos = target.getPosition();
@ -128,8 +128,8 @@ class DragConnector {
private _isVerticallyAligned(
targetSize: SizeType,
targetPosition: Point,
sourcePosition: Point,
targetPosition: PositionType,
sourcePosition: PositionType,
): boolean {
return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2;
}

View File

@ -19,10 +19,10 @@ import { $assert } from '@wisemapping/core-js';
import DragTopic from './DragTopic';
import EventBusDispatcher from './layout/EventBusDispatcher';
import Topic from './Topic';
import Workspace from './Workspace';
import Canvas from './Canvas';
class DragManager {
private _workspace: Workspace;
private _workspace: Canvas;
private _isDragInProcess: boolean;
@ -34,7 +34,7 @@ class DragManager {
private _mouseUpListener;
constructor(workspace: Workspace, eventDispatcher: EventBusDispatcher) {
constructor(workspace: Canvas, eventDispatcher: EventBusDispatcher) {
this._workspace = workspace;
this._listeners = {};
this._isDragInProcess = false;
@ -81,7 +81,7 @@ class DragManager {
}
protected buildMouseMoveListener(
workspace: Workspace,
workspace: Canvas,
dragNode: DragTopic,
dragManager: DragManager,
): (event: MouseEvent) => void {
@ -115,7 +115,7 @@ class DragManager {
}
protected _buildMouseUpListener(
workspace: Workspace,
workspace: Canvas,
dragNode: DragTopic,
dragManager: DragManager,
) {

View File

@ -22,9 +22,10 @@ import PositionType from './PositionType';
import SizeType from './SizeType';
import Topic from './Topic';
import Shape from './util/Shape';
import Workspace from './Workspace';
import Canvas from './Canvas';
import CanvasElement from './CanvasElement';
class DragPivot {
class DragPivot implements CanvasElement {
private _position: PositionType;
private _isVisible: boolean;
@ -95,7 +96,7 @@ class DragPivot {
// Update Line position.
const isAtRight = Shape.isAtRight(targetPosition, position);
const pivotPoint = Shape.calculateRectConnectionPoint(position, size, isAtRight);
line.setFrom(pivotPoint.x, pivotPoint.y);
line?.setFrom(pivotPoint.x, pivotPoint.y);
// Update rect position
const cx = position.x - size.width / 2;
@ -105,7 +106,7 @@ class DragPivot {
// Make line visible only when the position has been already changed.
// This solve several strange effects ;)
const targetPoint = targetTopic!.workoutIncomingConnectionPoint(pivotPoint);
line.setTo(targetPoint.x, targetPoint.y);
line?.setTo(targetPoint.x, targetPoint.y);
}
setPosition(point: Point): void {
@ -113,7 +114,7 @@ class DragPivot {
this._redrawLine();
}
getPosition(): Point {
getPosition(): PositionType {
return this._position;
}
@ -157,8 +158,8 @@ class DragPivot {
}
// If the node is connected, validate that there is a line connecting both...
_getConnectionLine(): CurvedLine {
let result = null;
_getConnectionLine(): CurvedLine | null {
let result: CurvedLine | null = null;
const parentTopic = this._targetTopic;
if (parentTopic) {
if (parentTopic.getType() === 'CentralTopic') {
@ -170,7 +171,7 @@ class DragPivot {
return result;
}
addToWorkspace(workspace: Workspace) {
addToWorkspace(workspace: Canvas) {
const pivotRect = this._getPivotRect();
workspace.append(pivotRect);
@ -196,7 +197,7 @@ class DragPivot {
connectRect.moveToBack();
}
removeFromWorkspace(workspace: Workspace) {
removeFromWorkspace(workspace: Canvas) {
const shape = this._getPivotRect();
workspace.removeChild(shape);
@ -212,7 +213,7 @@ class DragPivot {
}
}
connectTo(targetTopic: Topic, position: Point) {
connectTo(targetTopic: Topic, position: PositionType) {
$assert(position, 'position can not be null');
$assert(targetTopic, 'parent can not be null');
@ -242,7 +243,7 @@ class DragPivot {
this._redrawLine();
}
disconnect(workspace: Workspace): void {
disconnect(workspace: Canvas): void {
$assert(workspace, 'workspace can not be null.');
$assert(this._targetTopic, 'There are not connected topic.');

View File

@ -16,17 +16,19 @@
* limitations under the License.
*/
import { $assert } from '@wisemapping/core-js';
import { Point, ElementClass } from '@wisemapping/web2d';
import { ElementClass, ElementPeer, Group } from '@wisemapping/web2d';
import ActionDispatcher from './ActionDispatcher';
import DragPivot from './DragPivot';
import LayoutManager from './layout/LayoutManager';
import NodeGraph from './NodeGraph';
import PositionType from './PositionType';
import Topic from './Topic';
import Workspace from './Workspace';
import Canvas from './Canvas';
import CanvasElement from './CanvasElement';
class DragTopic {
private _elem2d: ElementClass;
private _elem2d: Group;
private _order: number | null;
@ -34,23 +36,19 @@ class DragTopic {
private _layoutManager: LayoutManager;
private _position: Point;
private _position: PositionType;
private _isInWorkspace: boolean;
static _dragPivot: DragPivot = new DragPivot();
constructor(dragShape: ElementClass, draggedNode: NodeGraph, layoutManger: LayoutManager) {
$assert(dragShape, 'Rect can not be null.');
$assert(draggedNode, 'draggedNode can not be null.');
$assert(layoutManger, 'layoutManger can not be null.');
constructor(dragShape: Group, draggedNode: NodeGraph, layoutManger: LayoutManager) {
this._elem2d = dragShape;
this._order = null;
this._draggedNode = draggedNode;
this._layoutManager = layoutManger;
this._isInWorkspace = false;
this._position = new Point(0, 0);
this._position = { x: 0, y: 0 };
}
setOrder(order: number): void {
@ -97,11 +95,11 @@ class DragTopic {
return dragPivot.isVisible();
}
getInnerShape(): ElementClass {
getInnerShape(): ElementClass<ElementPeer> {
return this._elem2d;
}
disconnect(workspace: Workspace) {
disconnect(workspace: Canvas) {
// Clear connection line ...
const dragPivot = this._getDragPivot();
dragPivot.disconnect(workspace);
@ -128,7 +126,7 @@ class DragTopic {
return this._draggedNode as Topic;
}
removeFromWorkspace(workspace: Workspace) {
removeFromWorkspace(workspace: Canvas) {
if (this._isInWorkspace) {
// Remove drag shadow.
workspace.removeChild(this._elem2d);
@ -146,7 +144,7 @@ class DragTopic {
return this._isInWorkspace;
}
addToWorkspace(workspace: Workspace) {
addToWorkspace(workspace: Canvas) {
if (!this._isInWorkspace) {
workspace.append(this._elem2d);
const dragPivot = this._getDragPivot();
@ -159,7 +157,7 @@ class DragTopic {
return DragTopic._dragPivot;
}
getPosition(): Point {
getPosition(): PositionType {
return this._position;
}
@ -167,7 +165,7 @@ class DragTopic {
return true;
}
applyChanges(workspace: Workspace) {
applyChanges(workspace: Canvas) {
$assert(workspace, 'workspace can not be null');
const actionDispatcher = ActionDispatcher.getInstance();
@ -205,9 +203,9 @@ class DragTopic {
return false;
}
static init(workspace: Workspace) {
static init(workspace: Canvas) {
$assert(workspace, 'workspace can not be null');
const pivot = DragTopic._dragPivot;
const pivot: CanvasElement = DragTopic._dragPivot;
workspace.append(pivot);
}
}

View File

@ -15,7 +15,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Text, Group, ElementClass, Point } from '@wisemapping/web2d';
import { Text, Group } from '@wisemapping/web2d';
import Icon from './Icon';
import IconGroup from './IconGroup';
@ -23,11 +23,12 @@ import SvgIconModel from './model/SvgIconModel';
import SizeType from './SizeType';
import Topic from './Topic';
import ActionDispatcher from './ActionDispatcher';
import PositionType from './PositionType';
class EmojiCharIcon implements Icon {
private element: ElementClass;
private _group: Group;
private _group: IconGroup | null;
private _iconGroup: IconGroup | null;
private _iconModel: SvgIconModel;
@ -37,48 +38,48 @@ class EmojiCharIcon implements Icon {
this._iconModel = iconModel;
this._topic = topic;
this.element = new Group({
width: 90,
height: 90,
this._group = new Group({
width: 70,
height: 70,
x: 0,
y: 0,
coordSizeWidth: 15,
coordSizeHeight: 15,
coordOriginY: 2,
coordOriginY: 0,
});
const iconText = new Text();
iconText.setText(iconModel.getIconType());
this.element.append(iconText);
this._group.append(iconText);
// Add events ...
if (!readOnly) {
this.element.setCursor('pointer');
this._group.setCursor('pointer');
}
this._group = null;
this._iconGroup = null;
}
getElement(): ElementClass {
return this.element;
getElement(): Group {
return this._group;
}
setGroup(group: IconGroup) {
this._group = group;
this._iconGroup = group;
}
getGroup(): IconGroup {
return this._group!;
return this._iconGroup!;
}
getSize(): SizeType {
return this._group!.getSize();
return this._iconGroup!.getSize();
}
getPosition(): Point {
return this._group!.getPosition();
getPosition(): PositionType {
return this._iconGroup!.getPosition();
}
addEvent(type: string, fnc: (e: object) => void): void {
this.element.addEvent(type, fnc);
this._group.addEvent(type, fnc);
}
remove() {

View File

@ -1,18 +1,36 @@
import { Point, ElementClass, Group } from '@wisemapping/web2d';
/*
* Copyright [2021] [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 { Group, Image } from '@wisemapping/web2d';
import IconGroup from './IconGroup';
import FeatureModel from './model/FeatureModel';
import PositionType from './PositionType';
import SizeType from './SizeType';
interface Icon {
getElement(): ElementClass;
getElement(): Group | Image;
setGroup(group: IconGroup): Group;
setGroup(group: IconGroup): void;
getGroup(): IconGroup | null;
getSize(): SizeType;
getSize(): SizeType | undefined;
getPosition(): Point;
getPosition(): PositionType;
addEvent(type: string, fnc: () => void): void;

View File

@ -16,13 +16,14 @@
* limitations under the License.
*/
import { $assert, $defined } from '@wisemapping/core-js';
import { Group, ElementClass, Point } from '@wisemapping/web2d';
import { $assert } from '@wisemapping/core-js';
import { Group } from '@wisemapping/web2d';
import IconGroupRemoveTip from './IconGroupRemoveTip';
import ImageIcon from './ImageIcon';
import SizeType from './SizeType';
import FeatureModel from './model/FeatureModel';
import Icon from './Icon';
import PositionType from './PositionType';
const ORDER_BY_TYPE = new Map<string, number>();
ORDER_BY_TYPE.set('icon', 0);
@ -61,14 +62,10 @@ class IconGroup {
this._group.setPosition(x, y);
}
getPosition(): Point {
getPosition(): PositionType {
return this._group.getPosition();
}
getNativeElement(): ElementClass {
return this._group;
}
/** */
getSize(): SizeType {
return this._group.getSize();
@ -84,8 +81,6 @@ class IconGroup {
}
addIcon(icon: Icon, remove: boolean): void {
$defined(icon, 'icon is not defined');
// Order could have change, need to re-add all.
const icons = this._icons.slice();
this._icons.forEach((i) => {
@ -102,7 +97,7 @@ class IconGroup {
// Add all the nodes back ...
this._resize(this._icons.length);
this._icons.forEach((i, index) => {
this._positionIcon(i, index);
this.positionIcon(i, index);
const imageShape = i.getElement();
this._group.append(imageShape);
});
@ -132,14 +127,14 @@ class IconGroup {
}
/** */
removeIconByModel(featureModel: FeatureModel) {
removeIconByModel(featureModel: FeatureModel): void {
$assert(featureModel, 'featureModel can not be null');
const icon = this._findIconFromModel(featureModel);
this._removeIcon(icon);
}
private _removeIcon(icon: Icon) {
private _removeIcon(icon: Icon): void {
this._removeTip.close(0);
this._group.removeChild(icon.getElement());
@ -149,7 +144,7 @@ class IconGroup {
// Add all again ...
this._icons.forEach((elem, i) => {
me._positionIcon(elem, i);
me.positionIcon(elem, i);
});
}
@ -169,7 +164,7 @@ class IconGroup {
});
}
private _resize(iconsLength: number) {
private _resize(iconsLength: number): void {
if (this._iconSize) {
this._group.setSize(iconsLength * this._iconSize.width, this._iconSize.height);
@ -178,14 +173,19 @@ class IconGroup {
}
}
private _positionIcon(icon: Icon, order: number) {
private positionIcon(icon: Icon, order: number): void {
const iconSize = ImageIcon.SIZE + IconGroup.ICON_PADDING * 2;
icon
.getElement()
.setPosition(iconSize * order + IconGroup.ICON_PADDING, IconGroup.ICON_PADDING);
}
static ICON_PADDING = 5;
appendTo(group: Group): void {
group.append(this._group);
this._group.moveToFront();
}
static ICON_PADDING = 2;
}
export default IconGroup;

View File

@ -7,7 +7,7 @@ class IconGroupRemoveTip {
private _activeIcon: ImageIcon | null;
private _widget: Group;
private _widget: Group | null;
private _closeTimeoutId;
@ -15,6 +15,7 @@ class IconGroupRemoveTip {
$assert(group, 'group can not be null');
this._group = group;
this._activeIcon = null;
this._widget = null;
}
show(topicId: number, icon: ImageIcon) {
@ -71,7 +72,9 @@ class IconGroupRemoveTip {
const close = () => {
this._activeIcon = null;
this._group.removeChild(widget);
if (widget) {
this._group.removeChild(widget);
}
this._widget = null;
this._closeTimeoutId = null;
};

View File

@ -16,11 +16,12 @@
* limitations under the License.
*/
import { $assert } from '@wisemapping/core-js';
import { Image, Point, ElementClass } from '@wisemapping/web2d';
import { Group, Image } from '@wisemapping/web2d';
import IconGroup from './IconGroup';
import SizeType from './SizeType';
import FeatureModel from './model/FeatureModel';
import Icon from './Icon';
import PositionType from './PositionType';
abstract class ImageIcon implements Icon {
private _image: Image;
@ -35,11 +36,11 @@ abstract class ImageIcon implements Icon {
this._group = null;
}
getElement(): ElementClass {
getElement(): Image | Group {
return this._image;
}
setGroup(group: IconGroup) {
setGroup(group: IconGroup): void {
this._group = group;
}
@ -47,11 +48,11 @@ abstract class ImageIcon implements Icon {
return this._group;
}
getSize(): SizeType {
getSize(): SizeType | undefined {
return this._image.getSize();
}
getPosition(): Point {
getPosition(): PositionType {
return this._image.getPosition();
}

View File

@ -16,7 +16,7 @@
* limitations under the License.
*/
import $ from 'jquery';
import initHotKeyPluggin from '../../../../libraries/jquery.hotkeys';
import initHotKeyPluggin from '../../libraries/jquery.hotkeys';
// Provides dispatcher of keyevents by key...
initHotKeyPluggin($);

View File

@ -16,12 +16,12 @@
* limitations under the License.
*/
import { $assert, $defined } from '@wisemapping/core-js';
import { Point, Group, ElementClass } from '@wisemapping/web2d';
import { Group, ElementClass, ElementPeer } from '@wisemapping/web2d';
import Topic from './Topic';
import Shape from './util/Shape';
import NodeModel from './model/NodeModel';
import Workspace from './Workspace';
import Canvas from './Canvas';
import SizeType from './SizeType';
import PositionType from './PositionType';
import { NodeOption } from './NodeGraph';
@ -34,7 +34,7 @@ class MainTopic extends Topic {
this.INNER_RECT_ATTRIBUTES = { stroke: '0.5 solid #009900' };
}
_buildDragShape(): ElementClass {
buildDragShape(): ElementClass<ElementPeer> {
const innerShape = this._buildShape(this.INNER_RECT_ATTRIBUTES, this.getShapeType());
const size = this.getSize();
innerShape.setSize(size.width, size.height);
@ -82,9 +82,8 @@ class MainTopic extends Topic {
}
}
disconnect(workspace: Workspace) {
disconnect(workspace: Canvas) {
super.disconnect(workspace);
this.redrawShapeType();
const innerShape = this.getInnerShape();
innerShape.setVisibility(true);
@ -113,7 +112,7 @@ class MainTopic extends Topic {
const isAtRight = Shape.isAtRight(targetPosition, pos);
const size = this.getSize();
let result: Point = { x: 0, y: 0 };
let result: PositionType = { x: 0, y: 0 };
if (this.getShapeType() === 'line') {
const groupPosition = this.get2DElement().getPosition();
const innerShareSize = this.getInnerShape().getSize();

Some files were not shown because too many files have changed in this diff Show More