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/releases
!.yarn/plugins !.yarn/plugins
.pnp.* .pnp.*
packages/**/.yalc/
packages/**/yalc.lock

View File

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

View File

@ -4,7 +4,7 @@
"description": "WiseMapping - Core Common Libraries", "description": "WiseMapping - Core Common Libraries",
"homepage": "http://www.wisemapping.org/", "homepage": "http://www.wisemapping.org/",
"license": "MIT", "license": "MIT",
"main": "dist/core.js", "main": "src/index.ts",
"files": [ "files": [
"src" "src"
], ],
@ -17,6 +17,7 @@
}, },
"scripts": { "scripts": {
"build": "webpack --config webpack.prod.js", "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 = { const prodConfig = {
output: { output: {
path: path.resolve(__dirname, 'dist'), path: path.resolve(__dirname, 'dist'),
filename: 'core.js', filename: 'index.ts',
publicPath: '',
library: { library: {
type: 'umd', type: 'umd',
}, },
}, }
target: 'web',
}; };
module.exports = merge(common, prodConfig); module.exports = merge(common, prodConfig);

View File

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

View File

@ -74,7 +74,7 @@ describe('Topic Shape Suite', () => {
.invoke('attr', 'rx') .invoke('attr', 'rx')
.then(parseInt) .then(parseInt)
.should('be.a', 'number') .should('be.a', 'number')
.should('be.gte', 12); .should('be.gte', 11);
cy.get('[test-id=2] > rect') cy.get('[test-id=2] > rect')
.eq(1) .eq(1)
.invoke('attr', 'rx') .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", "version": "0.4.2",
"main": "dist/editor.bundle.js", "main": "dist/editor.bundle.js",
"scripts": { "scripts": {
"bootstrap": "yalc publish;yalc add @wisemapping/mindplot",
"build": "webpack --config webpack.prod.js", "build": "webpack --config webpack.prod.js",
"playground": "webpack serve --config webpack.playground.js", "playground": "webpack serve --config webpack.playground.js",
"cy:run": "cypress run", "cy:run": "cypress run",

View File

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

View File

@ -10,7 +10,7 @@ module.exports = defineConfig({
setupNodeEvents(on, config) { setupNodeEvents(on, config) {
return require('./cypress/plugins/index.js')(on, config) return require('./cypress/plugins/index.js')(on, config)
}, },
baseUrl: 'http://localhost:8083', baseUrl: 'http://localhost:6006',
specPattern: 'cypress/e2e/**/*.{js,jsx,ts,tsx}', 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.js using ES2015 syntax:
import './commands'; import './commands';
// Alternatively you can use CommonJS syntax: Cypress.on('window:before:load', (win) => {
// require('./commands') 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', preset: 'ts-jest',
moduleFileExtensions: ['js', 'ts'], moduleFileExtensions: ['js', 'ts'],
transform: { transform: {
'^.+\\.js?$': 'babel-jest', '^.+\\.(ts)?$': 'ts-jest',
'^.+\\.(js)$': 'babel-jest',
}, },
}; };

View File

@ -10,8 +10,7 @@
"main": "src/index.ts", "main": "src/index.ts",
"files": [ "files": [
"src", "src",
"assets", "assets"
"dist"
], ],
"publishConfig": { "publishConfig": {
"registry": "https://registry.yarnpkg.com" "registry": "https://registry.yarnpkg.com"
@ -21,16 +20,16 @@
"url": "git@bitbucket.org:wisemapping/wisemapping-frontend.git" "url": "git@bitbucket.org:wisemapping/wisemapping-frontend.git"
}, },
"scripts": { "scripts": {
"bootstrap": "yalc publish;yalc add @wisemapping/core-js;yalc add @wisemapping/web2d",
"build": "webpack --config webpack.prod.js", "build": "webpack --config webpack.prod.js",
"dev": "webpack serve --config webpack.dev.js", "dev": "webpack serve --config webpack.dev.js",
"lint": "eslint src --ext js,ts", "lint": "eslint src --ext js,ts",
"playground": "webpack serve --config webpack.playground.js",
"cy:run": "cypress run", "cy:run": "cypress run",
"cy:open": "cypress open", "cy:open": "cypress open",
"test:unit": "jest ./test/unit/export/*.ts ./test/unit/import/*.ts ./test/unit/layout/*.js --verbose --silent --detectOpenHandles", "test:unit": "jest ./test/unit/export/*.ts ./test/unit/import/*.ts --verbose --silent --detectOpenHandles",
"test:integration": "start-server-and-test playground http-get://localhost:8083 cy:run", "test:integration": "start-server-and-test storybook http-get://localhost:6006 cy:run",
"test": "yarn test:unit && yarn test:integration", "test": "yarn test:unit && yarn test:integration",
"storybook": "start-storybook -p 6006", "storybook": "start-storybook -p 6006 --no-open",
"build-storybook": "build-storybook" "build-storybook": "build-storybook"
}, },
"dependencies": { "dependencies": {
@ -58,6 +57,8 @@
"blob-polyfill": "^6.0.20211015", "blob-polyfill": "^6.0.20211015",
"cypress": "^12.3.0", "cypress": "^12.3.0",
"cypress-image-snapshot": "^4.0.1", "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. * limitations under the License.
*/ */
import { $assert } from '@wisemapping/core-js'; import { $assert } from '@wisemapping/core-js';
import Point from '@wisemapping/web2d';
import { Mindmap } from '..'; import { Mindmap } from '..';
import CommandContext from './CommandContext'; import CommandContext from './CommandContext';
import { PivotType } from './RelationshipControlPoints'; import { PivotType } from './RelationshipControlPoints';
@ -51,12 +50,12 @@ abstract class ActionDispatcher extends Events {
abstract dragTopic( abstract dragTopic(
topicId: number, topicId: number,
position: Point, position: PositionType,
order: number | null, order: number | null,
parentTopic: Topic | null, parentTopic: Topic | null,
): void; ): void;
abstract moveTopic(topicId: number, position: Point): void; abstract moveTopic(topicId: number, position: PositionType): void;
abstract moveControlPoint( abstract moveControlPoint(
model: RelationshipModel, model: RelationshipModel,

View File

@ -15,12 +15,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 { $assert, $defined } from '@wisemapping/core-js'; import { $assert } from '@wisemapping/core-js';
import { Workspace as Workspace2D, ElementClass as Element2D } from '@wisemapping/web2d'; import { Workspace as Workspace2D, ElementClass, ElementPeer } from '@wisemapping/web2d';
import ScreenManager from './ScreenManager'; import ScreenManager from './ScreenManager';
import SizeType from './SizeType'; import SizeType from './SizeType';
import CanvasElement from './CanvasElement';
class Workspace { class Canvas {
private _zoom: number; private _zoom: number;
private _screenManager: ScreenManager; private _screenManager: ScreenManager;
@ -35,10 +36,14 @@ class Workspace {
private _visibleAreaSize!: SizeType; private _visibleAreaSize!: SizeType;
private _renderQueue: Element2D[]; private _renderQueue: (ElementClass<ElementPeer> | CanvasElement)[];
private _queueRenderEnabled: boolean; private _queueRenderEnabled: boolean;
private _mouseMoveListener;
private _mouseUpListener;
constructor(screenManager: ScreenManager, zoom: number, isReadOnly: boolean) { constructor(screenManager: ScreenManager, zoom: number, isReadOnly: boolean) {
// Create a suitable container ... // Create a suitable container ...
$assert(screenManager, 'Div container can not be null'); $assert(screenManager, 'Div container can not be null');
@ -64,6 +69,8 @@ class Workspace {
this._renderQueue = []; this._renderQueue = [];
this._eventsEnabled = false; this._eventsEnabled = false;
this._queueRenderEnabled = false; this._queueRenderEnabled = false;
this._mouseMoveListener = null;
this._mouseUpListener = null;
} }
private _adjustWorkspace(): void { private _adjustWorkspace(): void {
@ -105,7 +112,7 @@ class Workspace {
return new Workspace2D(workspaceProfile); return new Workspace2D(workspaceProfile);
} }
append(shape: Element2D): void { append(shape: ElementClass<ElementPeer> | CanvasElement): void {
if (this._queueRenderEnabled) { if (this._queueRenderEnabled) {
this._renderQueue.push(shape); this._renderQueue.push(shape);
} else { } else {
@ -113,11 +120,12 @@ class Workspace {
} }
} }
private appendInternal(shape: Element2D): void { private appendInternal(shape: CanvasElement | ElementClass<ElementPeer>): void {
if (shape.addToWorkspace) { // eslint-disable-next-line no-prototype-builtins, dot-notation
shape.addToWorkspace(this); if (typeof shape['addToWorkspace'] === 'function') {
(shape as CanvasElement).addToWorkspace(this);
} else { } else {
this._workspace.append(shape); this._workspace.append(shape as ElementClass<ElementPeer>);
} }
} }
@ -127,7 +135,7 @@ class Workspace {
let result = Promise.resolve(); let result = Promise.resolve();
if (!value) { if (!value) {
// eslint-disable-next-line arrow-body-style // eslint-disable-next-line arrow-body-style
result = Workspace.delay(100).then(() => { result = Canvas.delay(100).then(() => {
return this.processRenderQueue(this._renderQueue.reverse(), 300); return this.processRenderQueue(this._renderQueue.reverse(), 300);
}); });
} }
@ -138,29 +146,35 @@ class Workspace {
return new Promise((resolve) => setTimeout(resolve, t)); 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>; 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); if (renderQueue.length > 0) {
}).then((queue) => Workspace.delay(30).then(() => this.processRenderQueue(queue, batch))); 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 { } else {
result = Promise.resolve(); result = Promise.resolve();
} }
return result; return result;
} }
removeChild(shape: Element2D): void { removeChild(shape: ElementClass<ElementPeer> | CanvasElement): void {
// Element is a node, not a web2d element? // eslint-disable-next-line dot-notation
if (shape.removeFromWorkspace) { if (typeof shape['removeFromWorkspace'] === 'function') {
shape.removeFromWorkspace(this); (shape as CanvasElement).removeFromWorkspace(this);
} else { } else {
this._workspace.removeChild(shape); this._workspace.removeChild(shape as ElementClass<ElementPeer>);
} }
} }
@ -244,7 +258,7 @@ class Workspace {
return this._eventsEnabled; return this._eventsEnabled;
} }
getSVGElement() { getSVGElement(): Element {
return this._workspace.getSVGElement(); return this._workspace.getSVGElement();
} }
@ -252,8 +266,8 @@ class Workspace {
const workspace = this._workspace; const workspace = this._workspace;
const screenManager = this._screenManager; const screenManager = this._screenManager;
const mWorkspace = this; const mWorkspace = this;
const mouseDownListener = function mouseDownListener(event: MouseEvent) { const mouseDownListener = (event: MouseEvent) => {
if (!$defined(workspace._mouseMoveListener)) { if (!this._mouseMoveListener) {
if (mWorkspace.isWorkspaceEventsEnabled()) { if (mWorkspace.isWorkspaceEventsEnabled()) {
mWorkspace.enableWorkspaceEvents(false); mWorkspace.enableWorkspaceEvents(false);
@ -261,7 +275,7 @@ class Workspace {
const originalCoordOrigin = workspace.getCoordOrigin(); const originalCoordOrigin = workspace.getCoordOrigin();
let wasDragged = false; let wasDragged = false;
workspace._mouseMoveListener = (mouseMoveEvent: MouseEvent) => { this._mouseMoveListener = (mouseMoveEvent: MouseEvent) => {
const currentMousePosition = screenManager.getWorkspaceMousePosition(mouseMoveEvent); const currentMousePosition = screenManager.getWorkspaceMousePosition(mouseMoveEvent);
const offsetX = currentMousePosition.x - mouseDownPosition.x; const offsetX = currentMousePosition.x - mouseDownPosition.x;
@ -284,17 +298,17 @@ class Workspace {
screenManager.fireEvent('update'); screenManager.fireEvent('update');
wasDragged = true; wasDragged = true;
}; };
screenManager.addEvent('mousemove', workspace._mouseMoveListener); screenManager.addEvent('mousemove', this._mouseMoveListener);
screenManager.addEvent('touchmove', workspace._mouseMoveListener); screenManager.addEvent('touchmove', this._mouseMoveListener);
// Register mouse up listeners ... // Register mouse up listeners ...
workspace._mouseUpListener = () => { this._mouseUpListener = () => {
screenManager.removeEvent('mousemove', workspace._mouseMoveListener); screenManager.removeEvent('mousemove', this._mouseMoveListener);
screenManager.removeEvent('mouseup', workspace._mouseUpListener); screenManager.removeEvent('mouseup', this._mouseUpListener);
screenManager.removeEvent('touchmove', workspace._mouseUpListener); screenManager.removeEvent('touchmove', this._mouseUpListener);
screenManager.removeEvent('touchend', workspace._mouseMoveListener); screenManager.removeEvent('touchend', this._mouseMoveListener);
workspace._mouseUpListener = null; this._mouseUpListener = null;
workspace._mouseMoveListener = null; this._mouseMoveListener = null;
window.document.body.style.cursor = 'default'; window.document.body.style.cursor = 'default';
// Update screen manager offset. // Update screen manager offset.
@ -306,11 +320,11 @@ class Workspace {
screenManager.fireEvent('click'); screenManager.fireEvent('click');
} }
}; };
screenManager.addEvent('mouseup', workspace._mouseUpListener); screenManager.addEvent('mouseup', this._mouseUpListener);
screenManager.addEvent('touchend', workspace._mouseUpListener); screenManager.addEvent('touchend', this._mouseUpListener);
} }
} else { } else {
workspace._mouseUpListener(); this._mouseUpListener();
} }
}; };
screenManager.addEvent('mousedown', mouseDownListener); 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 * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { Point } from '@wisemapping/web2d';
import { $assert } from '@wisemapping/core-js'; import { $assert } from '@wisemapping/core-js';
import PositionType from './PositionType';
import Topic from './Topic'; import Topic from './Topic';
import Shape from './util/Shape'; import Shape from './util/Shape';
class CentralTopic extends Topic { class CentralTopic extends Topic {
_buildDragShape() { buildDragShape() {
// Ignore .. // Ignore ..
} }
_registerEvents(): void { registerEvents(): void {
super._registerEvents(); super.registerEvents();
// This disable the drag of the central topic. // This disable the drag of the central topic.
// But solves the problem of deselecting the nodes when the screen is clicked. // 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(); return this.getPosition();
} }
setCursor(type: string) { setCursor(type: string): void {
super.setCursor(type === 'move' ? 'default' : type); super.setCursor(type === 'move' ? 'default' : type);
} }
updateTopicShape() { updateTopicShape(): void {
// Overwite behaviour ... // Overwite behaviour ...
} }
_updatePositionOnChangeSize(): void { _updatePositionOnChangeSize(): void {
// Center main topic ... // Center main topic ...
const zeroPoint = new Point(0, 0); const zeroPoint = { x: 0, y: 0 };
this.setPosition(zeroPoint); this.setPosition(zeroPoint);
} }
getShrinkConnector() { getShrinkConnector(): null {
return null; return null;
} }
workoutOutgoingConnectionPoint(targetPosition: Point) { workoutOutgoingConnectionPoint(targetPosition: PositionType) {
$assert(targetPosition, 'targetPoint can not be null'); $assert(targetPosition, 'targetPoint can not be null');
const pos = this.getPosition(); const pos = this.getPosition();

View File

@ -16,11 +16,11 @@
* limitations under the License. * limitations under the License.
*/ */
import { $assert, $defined } from '@wisemapping/core-js'; import { $assert, $defined } from '@wisemapping/core-js';
import Point from '@wisemapping/web2d';
import { Designer } from '..'; import { Designer } from '..';
import EventBus from './layout/EventBus'; import EventBus from './layout/EventBus';
import NodeModel from './model/NodeModel'; import NodeModel from './model/NodeModel';
import RelationshipModel from './model/RelationshipModel'; import RelationshipModel from './model/RelationshipModel';
import PositionType from './PositionType';
import Relationship from './Relationship'; import Relationship from './Relationship';
import Topic from './Topic'; 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(topic, 'topic cannot be null');
$assert(position, 'position cannot be null'); $assert(position, 'position cannot be null');
EventBus.instance.fireEvent('topicMoved', { EventBus.instance.fireEvent('topicMoved', {

View File

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

View File

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

View File

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

View File

@ -16,19 +16,19 @@
* limitations under the License. * limitations under the License.
*/ */
import { $assert } from '@wisemapping/core-js'; import { $assert } from '@wisemapping/core-js';
import { Point } from '@wisemapping/web2d';
import DesignerModel from './DesignerModel'; import DesignerModel from './DesignerModel';
import DragTopic from './DragTopic'; import DragTopic from './DragTopic';
import SizeType from './SizeType'; import SizeType from './SizeType';
import Topic from './Topic'; import Topic from './Topic';
import Workspace from './Workspace'; import Canvas from './Canvas';
import PositionType from './PositionType';
class DragConnector { class DragConnector {
private _designerModel: DesignerModel; 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(designerModel, 'designerModel can not be null');
$assert(workspace, 'workspace can not be null'); $assert(workspace, 'workspace can not be null');
@ -114,7 +114,7 @@ class DragConnector {
private _proximityWeight( private _proximityWeight(
isAligned: boolean, isAligned: boolean,
target: Topic, target: Topic,
sPos: Point, sPos: PositionType,
currentConnection: Topic, currentConnection: Topic,
): number { ): number {
const tPos = target.getPosition(); const tPos = target.getPosition();
@ -128,8 +128,8 @@ class DragConnector {
private _isVerticallyAligned( private _isVerticallyAligned(
targetSize: SizeType, targetSize: SizeType,
targetPosition: Point, targetPosition: PositionType,
sourcePosition: Point, sourcePosition: PositionType,
): boolean { ): boolean {
return Math.abs(sourcePosition.y - targetPosition.y) < targetSize.height / 2; 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 DragTopic from './DragTopic';
import EventBusDispatcher from './layout/EventBusDispatcher'; import EventBusDispatcher from './layout/EventBusDispatcher';
import Topic from './Topic'; import Topic from './Topic';
import Workspace from './Workspace'; import Canvas from './Canvas';
class DragManager { class DragManager {
private _workspace: Workspace; private _workspace: Canvas;
private _isDragInProcess: boolean; private _isDragInProcess: boolean;
@ -34,7 +34,7 @@ class DragManager {
private _mouseUpListener; private _mouseUpListener;
constructor(workspace: Workspace, eventDispatcher: EventBusDispatcher) { constructor(workspace: Canvas, eventDispatcher: EventBusDispatcher) {
this._workspace = workspace; this._workspace = workspace;
this._listeners = {}; this._listeners = {};
this._isDragInProcess = false; this._isDragInProcess = false;
@ -81,7 +81,7 @@ class DragManager {
} }
protected buildMouseMoveListener( protected buildMouseMoveListener(
workspace: Workspace, workspace: Canvas,
dragNode: DragTopic, dragNode: DragTopic,
dragManager: DragManager, dragManager: DragManager,
): (event: MouseEvent) => void { ): (event: MouseEvent) => void {
@ -115,7 +115,7 @@ class DragManager {
} }
protected _buildMouseUpListener( protected _buildMouseUpListener(
workspace: Workspace, workspace: Canvas,
dragNode: DragTopic, dragNode: DragTopic,
dragManager: DragManager, dragManager: DragManager,
) { ) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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