WIP Networklink POC
This commit is contained in:
parent
27ba6a3adf
commit
8e09a30a05
|
@ -119,6 +119,7 @@ foreach ($layoutDatas as $layoutData) {
|
|||
}
|
||||
|
||||
switch ($layoutData['type']) {
|
||||
case NETWORK_LINK:
|
||||
case LINE_ITEM:
|
||||
visual_map_print_user_line_handles($layoutData);
|
||||
visual_map_print_user_lines($layoutData);
|
||||
|
|
|
@ -271,6 +271,7 @@ foreach ($layoutDatas as $layoutData) {
|
|||
);
|
||||
break;
|
||||
|
||||
case NETWORK_LINK:
|
||||
case LINE_ITEM:
|
||||
$table->data[($i + 1)]['icon'] = html_print_image(
|
||||
'images/line_item.png',
|
||||
|
@ -303,6 +304,7 @@ foreach ($layoutDatas as $layoutData) {
|
|||
switch ($layoutData['type']) {
|
||||
case ICON:
|
||||
case BOX_ITEM:
|
||||
case NETWORK_LINK:
|
||||
case LINE_ITEM:
|
||||
// hasn't the label.
|
||||
$table->data[($i + 1)][0] = '';
|
||||
|
@ -345,6 +347,7 @@ foreach ($layoutDatas as $layoutData) {
|
|||
|
||||
// Width and height
|
||||
switch ($layoutData['type']) {
|
||||
case NETWORK_LINK:
|
||||
case LINE_ITEM:
|
||||
// hasn't the width and height.
|
||||
$table->data[($i + 1)][2] = '';
|
||||
|
@ -361,6 +364,7 @@ foreach ($layoutDatas as $layoutData) {
|
|||
|
||||
// Position
|
||||
switch ($layoutData['type']) {
|
||||
case NETWORK_LINK:
|
||||
case LINE_ITEM:
|
||||
// hasn't the width and height.
|
||||
$table->data[($i + 1)][3] = '';
|
||||
|
@ -375,6 +379,7 @@ foreach ($layoutDatas as $layoutData) {
|
|||
// Parent
|
||||
switch ($layoutData['type']) {
|
||||
case BOX_ITEM:
|
||||
case NETWORK_LINK:
|
||||
case LINE_ITEM:
|
||||
case COLOR_CLOUD:
|
||||
$table->data[($i + 1)][4] = '';
|
||||
|
@ -434,6 +439,7 @@ foreach ($layoutDatas as $layoutData) {
|
|||
case BOX_ITEM:
|
||||
case ICON:
|
||||
case LABEL:
|
||||
case NETWORK_LINK:
|
||||
case LINE_ITEM:
|
||||
$table->data[($i + 2)][0] = '';
|
||||
break;
|
||||
|
@ -494,6 +500,7 @@ foreach ($layoutDatas as $layoutData) {
|
|||
case ICON:
|
||||
case LABEL:
|
||||
case BOX_ITEM:
|
||||
case NETWORK_LINK:
|
||||
case LINE_ITEM:
|
||||
case GROUP_ITEM:
|
||||
$table->data[($i + 2)][1] = '';
|
||||
|
@ -598,6 +605,7 @@ foreach ($layoutDatas as $layoutData) {
|
|||
|
||||
// Map linked
|
||||
switch ($layoutData['type']) {
|
||||
case NETWORK_LINK:
|
||||
case LINE_ITEM:
|
||||
case BOX_ITEM:
|
||||
case AUTO_SLA_GRAPH:
|
||||
|
|
|
@ -1449,6 +1449,16 @@ switch ($action) {
|
|||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'network_link':
|
||||
$values['type'] = NETWORK_LINK;
|
||||
$values['border_width'] = $line_width;
|
||||
$values['border_color'] = $line_color;
|
||||
$values['pos_x'] = $line_start_x;
|
||||
$values['pos_y'] = $line_start_y;
|
||||
$values['width'] = $line_end_x;
|
||||
$values['height'] = $line_end_y;
|
||||
break;
|
||||
|
||||
case 'line_item':
|
||||
$values['type'] = LINE_ITEM;
|
||||
$values['border_width'] = $line_width;
|
||||
|
|
|
@ -3670,6 +3670,7 @@ function visual_map_print_visual_map(
|
|||
$layout_data['label'] = visual_map_macro($layout_data['label'], $layout_data['id_agente_modulo']);
|
||||
|
||||
switch ($layout_data['type']) {
|
||||
case NETWORK_LINK:
|
||||
case LINE_ITEM:
|
||||
visual_map_print_user_lines($layout_data, $proportion);
|
||||
break;
|
||||
|
@ -4382,6 +4383,9 @@ function visual_map_type_in_js($type)
|
|||
case LINE_ITEM:
|
||||
return 'line_item';
|
||||
|
||||
case NETWORK_LINK:
|
||||
return 'network_link';
|
||||
|
||||
case COLOR_CLOUD:
|
||||
return 'color_cloud';
|
||||
|
||||
|
|
|
@ -186,13 +186,17 @@ function createVisualConsole(
|
|||
var item = e.item || {};
|
||||
var meta = item.meta || {};
|
||||
|
||||
if ((meta.editMode || meta.lineMode) && !meta.isUpdating) {
|
||||
if (meta.editMode && !meta.isUpdating) {
|
||||
createOrUpdateVisualConsoleItem(
|
||||
visualConsole,
|
||||
asyncTaskManager,
|
||||
baseUrl,
|
||||
item
|
||||
);
|
||||
} else if (meta.lineMode && item.props.type == 21) {
|
||||
confirmDialog({
|
||||
title: "todo"
|
||||
});
|
||||
}
|
||||
});
|
||||
// VC Item moved.
|
||||
|
@ -203,7 +207,7 @@ function createVisualConsole(
|
|||
y: e.newPosition.y,
|
||||
type: e.item.props.type
|
||||
};
|
||||
if (e.item.props.type === 13) {
|
||||
if (e.item.props.type === 13 || e.item.props.type === 21) {
|
||||
var startIsLeft =
|
||||
e.item.props.startPosition.x - e.item.props.endPosition.x <= 0;
|
||||
var startIsTop =
|
||||
|
@ -427,6 +431,7 @@ function createVisualConsole(
|
|||
},
|
||||
createItem: function(typeString) {
|
||||
var type;
|
||||
console.log(typeString);
|
||||
switch (typeString) {
|
||||
case "STATIC_GRAPH":
|
||||
type = 0;
|
||||
|
@ -479,6 +484,9 @@ function createVisualConsole(
|
|||
case "COLOR_CLOUD":
|
||||
type = 20;
|
||||
break;
|
||||
case "NETWORK_LINK":
|
||||
type = 21;
|
||||
break;
|
||||
default:
|
||||
type = 0;
|
||||
}
|
||||
|
@ -565,7 +573,7 @@ function createVisualConsole(
|
|||
item.setMeta({ isUpdating: false });
|
||||
|
||||
var itemRetrieved = item.props;
|
||||
if (itemRetrieved["type"] == 13) {
|
||||
if (itemRetrieved["type"] == 13 || itemRetrieved["type"] == 21) {
|
||||
var startIsLeft =
|
||||
itemRetrieved["startPosition"]["x"] -
|
||||
itemRetrieved["endPosition"]["x"] <=
|
||||
|
@ -1179,6 +1187,9 @@ function createOrUpdateVisualConsoleItem(
|
|||
case 20:
|
||||
nameType = "Color Cloud";
|
||||
break;
|
||||
case 21:
|
||||
nameType = "Network Link";
|
||||
break;
|
||||
|
||||
default:
|
||||
nameType = "Static graph";
|
||||
|
@ -1259,7 +1270,8 @@ function createOrUpdateVisualConsoleItem(
|
|||
tinyMCE != undefined &&
|
||||
tinyMCE.editors.length > 0 &&
|
||||
item.itemProps.type != 12 &&
|
||||
item.itemProps.type != 13
|
||||
item.itemProps.type != 13 &&
|
||||
item.itemProps.type != 21
|
||||
) {
|
||||
// Content tiny.
|
||||
var label = tinyMCE.activeEditor.getContent();
|
||||
|
|
|
@ -109,7 +109,7 @@ if ($getVisualConsole === true) {
|
|||
$ratio
|
||||
);
|
||||
|
||||
echo '['.implode($vcItems, ',').']';
|
||||
echo '['.implode(',', $vcItems).']';
|
||||
return;
|
||||
} else if ($getVisualConsoleItem === true
|
||||
|| $updateVisualConsoleItem === true
|
||||
|
@ -245,7 +245,9 @@ if ($getVisualConsole === true) {
|
|||
$item = VisualConsole::getItemFromDB($itemId);
|
||||
$data = $item->toArray();
|
||||
$data['id_layout'] = $visualConsoleId;
|
||||
if ($data['type'] === LINE_ITEM) {
|
||||
if ($data['type'] === LINE_ITEM
|
||||
|| $data['type'] === NETWORK_LINK
|
||||
) {
|
||||
$data['endX'] = ($data['endX'] + 20);
|
||||
$data['endY'] = ($data['endY'] + 20);
|
||||
$data['startX'] = ($data['startX'] + 20);
|
||||
|
|
|
@ -186,6 +186,7 @@ final class NetworkLink extends Model
|
|||
* Obtain a vc item data structure from the database using a filter.
|
||||
*
|
||||
* @param array $filter Filter of the Visual Console Item.
|
||||
* @param float $ratio Adjustment ratio factor.
|
||||
*
|
||||
* @return array The Visual Console line data structure stored into the DB.
|
||||
* @throws \Exception When the data cannot be retrieved from the DB.
|
||||
|
|
|
@ -81,7 +81,9 @@ class View extends \HTML
|
|||
$activetabs = 2;
|
||||
if ($type === LABEL) {
|
||||
$activetabs = 0;
|
||||
} else if ($type === LINE_ITEM) {
|
||||
} else if ($type === LINE_ITEM
|
||||
|| $type === NETWORK_LINK
|
||||
) {
|
||||
$activetabs = 0;
|
||||
$tabs = [
|
||||
[
|
||||
|
@ -306,7 +308,7 @@ class View extends \HTML
|
|||
);
|
||||
} else {
|
||||
// Only Create, settings default values if not enter tab general.
|
||||
if ($itemId === 0 && $type != LINE_ITEM) {
|
||||
if ($itemId === 0 && $type != LINE_ITEM && $type != NETWORK_LINK) {
|
||||
$class = VisualConsole::getItemClass((int) $type);
|
||||
$data = $class::getDefaultGeneralValues($data);
|
||||
}
|
||||
|
@ -491,6 +493,17 @@ class View extends \HTML
|
|||
$data['isLinkEnabled'] = true;
|
||||
break;
|
||||
|
||||
case NETWORK_LINK:
|
||||
$data['borderColor'] = \get_parameter('borderColor');
|
||||
$data['borderWidth'] = \get_parameter('borderWidth');
|
||||
$data['isOnTop'] = \get_parameter_switch('isOnTop');
|
||||
// Insert line default position ball end.
|
||||
if ($itemId === 0) {
|
||||
$data['height'] = 100;
|
||||
$data['width'] = 100;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Not posible.
|
||||
break;
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -843,6 +843,7 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
|
|||
this.elementRef.classList.remove("is-editing");
|
||||
}
|
||||
}
|
||||
|
||||
if (!prevMeta || prevMeta.isFetching !== this.meta.isFetching) {
|
||||
if (this.meta.isFetching) {
|
||||
this.elementRef.classList.add("is-fetching");
|
||||
|
@ -1003,8 +1004,13 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
|
|||
*/
|
||||
protected resizeElement(width: number, height: number): void {
|
||||
// The most valuable size is the content size.
|
||||
this.childElementRef.style.width = width > 0 ? `${width}px` : null;
|
||||
this.childElementRef.style.height = height > 0 ? `${height}px` : null;
|
||||
if (
|
||||
this.props.type != ItemType.LINE_ITEM &&
|
||||
this.props.type != ItemType.NETWORK_LINK
|
||||
) {
|
||||
this.childElementRef.style.width = width > 0 ? `${width}px` : "0";
|
||||
this.childElementRef.style.height = height > 0 ? `${height}px` : "0";
|
||||
}
|
||||
|
||||
if (this.props.label && this.props.label.length > 0) {
|
||||
// Ugly table to show the label as its legacy counterpart.
|
||||
|
@ -1015,11 +1021,11 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
|
|||
switch (this.props.labelPosition) {
|
||||
case "up":
|
||||
case "down":
|
||||
table.style.width = width > 0 ? `${width}px` : null;
|
||||
table.style.width = width > 0 ? `${width}px` : "0";
|
||||
break;
|
||||
case "left":
|
||||
case "right":
|
||||
table.style.height = height > 0 ? `${height}px` : null;
|
||||
table.style.height = height > 0 ? `${height}px` : "0";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1182,7 +1188,7 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
|
|||
};
|
||||
|
||||
this.initMovementListener(this.elementRef);
|
||||
if (this.props.type !== 13) {
|
||||
if (this.props.type !== ItemType.LINE_ITEM) {
|
||||
this.initResizementListener(this.elementRef);
|
||||
}
|
||||
}
|
||||
|
@ -1198,7 +1204,7 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
|
|||
};
|
||||
|
||||
this.stopMovementListener();
|
||||
if (this.props.type !== 13) {
|
||||
if (this.props.type !== ItemType.LINE_ITEM) {
|
||||
this.stopResizementListener();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ import {
|
|||
import Item, { ItemType, ItemProps, itemBasePropsDecoder } from "../Item";
|
||||
import TypedEvent, { Listener, Disposable } from "../lib/TypedEvent";
|
||||
|
||||
interface LineProps extends ItemProps {
|
||||
export interface LineProps extends ItemProps {
|
||||
// Overrided properties.
|
||||
readonly type: ItemType.LINE_ITEM;
|
||||
type: number;
|
||||
label: null;
|
||||
isLinkEnabled: false;
|
||||
parentId: null;
|
||||
|
@ -20,6 +20,8 @@ interface LineProps extends ItemProps {
|
|||
endPosition: Position;
|
||||
lineWidth: number;
|
||||
color: string | null;
|
||||
viewportOffsetX: number;
|
||||
viewportOffsetY: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,7 +56,9 @@ export function linePropsDecoder(data: AnyObject): LineProps | never {
|
|||
y: parseIntOr(data.endY, 0)
|
||||
},
|
||||
lineWidth: parseIntOr(data.lineWidth || data.borderWidth, 1),
|
||||
color: notEmptyStringOr(data.borderColor || data.color, null)
|
||||
color: notEmptyStringOr(data.borderColor || data.color, null),
|
||||
viewportOffsetX: 0,
|
||||
viewportOffsetY: 0
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -82,20 +86,20 @@ export interface LineMovedEvent {
|
|||
}
|
||||
|
||||
export default class Line extends Item<LineProps> {
|
||||
private circleRadius = 8;
|
||||
protected circleRadius = 8;
|
||||
// To control if the line movement is enabled.
|
||||
private moveMode: boolean = false;
|
||||
protected moveMode: boolean = false;
|
||||
// To control if the line is moving.
|
||||
private isMoving: boolean = false;
|
||||
protected isMoving: boolean = false;
|
||||
|
||||
// Event manager for moved events.
|
||||
private readonly lineMovedEventManager = new TypedEvent<LineMovedEvent>();
|
||||
protected readonly lineMovedEventManager = new TypedEvent<LineMovedEvent>();
|
||||
// List of references to clean the event listeners.
|
||||
private readonly lineMovedEventDisposables: Disposable[] = [];
|
||||
protected readonly lineMovedEventDisposables: Disposable[] = [];
|
||||
|
||||
// This function will only run the 2nd arg function after the time
|
||||
// of the first arg have passed after its last execution.
|
||||
private debouncedStartPositionMovementSave = debounce(
|
||||
protected debouncedStartPositionMovementSave = debounce(
|
||||
500, // ms.
|
||||
(x: Position["x"], y: Position["y"]) => {
|
||||
this.isMoving = false;
|
||||
|
@ -110,13 +114,13 @@ export default class Line extends Item<LineProps> {
|
|||
);
|
||||
// This property will store the function
|
||||
// to clean the movement listener.
|
||||
private removeStartPositionMovement: Function | null = null;
|
||||
protected removeStartPositionMovement: Function | null = null;
|
||||
|
||||
/**
|
||||
* Start the movement funtionality for the start position.
|
||||
* @param element Element to move inside its container.
|
||||
*/
|
||||
private initStartPositionMovementListener(
|
||||
protected initStartPositionMovementListener(
|
||||
element: HTMLElement,
|
||||
container: HTMLElement
|
||||
): void {
|
||||
|
@ -124,8 +128,8 @@ export default class Line extends Item<LineProps> {
|
|||
element,
|
||||
(x: Position["x"], y: Position["y"]) => {
|
||||
// Calculate the center of the circle.
|
||||
x += this.circleRadius;
|
||||
y += this.circleRadius;
|
||||
x += this.circleRadius - this.props.viewportOffsetX / 2;
|
||||
y += this.circleRadius - this.props.viewportOffsetY / 2;
|
||||
|
||||
const startPosition = { x, y };
|
||||
|
||||
|
@ -153,7 +157,7 @@ export default class Line extends Item<LineProps> {
|
|||
|
||||
// This function will only run the 2nd arg function after the time
|
||||
// of the first arg have passed after its last execution.
|
||||
private debouncedEndPositionMovementSave = debounce(
|
||||
protected debouncedEndPositionMovementSave = debounce(
|
||||
500, // ms.
|
||||
(x: Position["x"], y: Position["y"]) => {
|
||||
this.isMoving = false;
|
||||
|
@ -168,13 +172,13 @@ export default class Line extends Item<LineProps> {
|
|||
);
|
||||
// This property will store the function
|
||||
// to clean the movement listener.
|
||||
private removeEndPositionMovement: Function | null = null;
|
||||
protected removeEndPositionMovement: Function | null = null;
|
||||
|
||||
/**
|
||||
* End the movement funtionality for the end position.
|
||||
* @param element Element to move inside its container.
|
||||
*/
|
||||
private initEndPositionMovementListener(
|
||||
protected initEndPositionMovementListener(
|
||||
element: HTMLElement,
|
||||
container: HTMLElement
|
||||
): void {
|
||||
|
@ -182,8 +186,8 @@ export default class Line extends Item<LineProps> {
|
|||
element,
|
||||
(x: Position["x"], y: Position["y"]) => {
|
||||
// Calculate the center of the circle.
|
||||
x += this.circleRadius;
|
||||
y += this.circleRadius;
|
||||
x += this.circleRadius - this.props.viewportOffsetX / 2;
|
||||
y += this.circleRadius - this.props.viewportOffsetY / 2;
|
||||
|
||||
this.isMoving = true;
|
||||
this.props = {
|
||||
|
@ -231,6 +235,11 @@ export default class Line extends Item<LineProps> {
|
|||
|
||||
this.moveMode = meta.editMode;
|
||||
this.init();
|
||||
|
||||
super.resizeElement(
|
||||
Math.max(props.width, props.viewportOffsetX),
|
||||
Math.max(props.height, props.viewportOffsetY)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -272,27 +281,33 @@ export default class Line extends Item<LineProps> {
|
|||
const element: HTMLDivElement = document.createElement("div");
|
||||
element.className = "line";
|
||||
|
||||
const {
|
||||
let {
|
||||
x, // Box x
|
||||
y, // Box y
|
||||
width, // Box width
|
||||
height, // Box height
|
||||
lineWidth, // Line thickness
|
||||
lineWidth, // Line thickness,
|
||||
viewportOffsetX, // viewport width,
|
||||
viewportOffsetY, // viewport heigth,
|
||||
startPosition, // Line start position
|
||||
endPosition, // Line end position
|
||||
color // Line color
|
||||
} = this.props;
|
||||
|
||||
const x1 = startPosition.x - x + lineWidth / 2;
|
||||
const y1 = startPosition.y - y + lineWidth / 2;
|
||||
const x2 = endPosition.x - x + lineWidth / 2;
|
||||
const y2 = endPosition.y - y + lineWidth / 2;
|
||||
width = width + viewportOffsetX;
|
||||
height = height + viewportOffsetY;
|
||||
|
||||
const x1 = startPosition.x - x + lineWidth / 2 + viewportOffsetX / 2;
|
||||
const y1 = startPosition.y - y + lineWidth / 2 + viewportOffsetY / 2;
|
||||
const x2 = endPosition.x - x + lineWidth / 2 + viewportOffsetX / 2;
|
||||
const y2 = endPosition.y - y + lineWidth / 2 + viewportOffsetY / 2;
|
||||
|
||||
// SVG container.
|
||||
const svg = document.createElementNS(svgNS, "svg");
|
||||
// Set SVG size.
|
||||
svg.setAttribute("width", `${width + lineWidth}`);
|
||||
svg.setAttribute("height", `${height + lineWidth}`);
|
||||
|
||||
const line = document.createElementNS(svgNS, "line");
|
||||
line.setAttribute("x1", `${x1}`);
|
||||
line.setAttribute("y1", `${y1}`);
|
||||
|
@ -308,21 +323,26 @@ export default class Line extends Item<LineProps> {
|
|||
}
|
||||
|
||||
protected updateDomElement(element: HTMLElement): void {
|
||||
const {
|
||||
let {
|
||||
x, // Box x
|
||||
y, // Box y
|
||||
width, // Box width
|
||||
height, // Box height
|
||||
lineWidth, // Line thickness
|
||||
viewportOffsetX, // viewport width,
|
||||
viewportOffsetY, // viewport heigth,
|
||||
startPosition, // Line start position
|
||||
endPosition, // Line end position
|
||||
color // Line color
|
||||
} = this.props;
|
||||
|
||||
const x1 = startPosition.x - x + lineWidth / 2;
|
||||
const y1 = startPosition.y - y + lineWidth / 2;
|
||||
const x2 = endPosition.x - x + lineWidth / 2;
|
||||
const y2 = endPosition.y - y + lineWidth / 2;
|
||||
width = width + viewportOffsetX;
|
||||
height = height + viewportOffsetY;
|
||||
|
||||
const x1 = startPosition.x - x + lineWidth / 2 + viewportOffsetX / 2;
|
||||
const y1 = startPosition.y - y + lineWidth / 2 + viewportOffsetY / 2;
|
||||
const x2 = endPosition.x - x + lineWidth / 2 + viewportOffsetX / 2;
|
||||
const y2 = endPosition.y - y + lineWidth / 2 + viewportOffsetY / 2;
|
||||
|
||||
const svgs = element.getElementsByTagName("svg");
|
||||
|
||||
|
@ -352,9 +372,6 @@ export default class Line extends Item<LineProps> {
|
|||
}
|
||||
|
||||
if (this.moveMode) {
|
||||
const startIsLeft = startPosition.x - endPosition.x <= 0;
|
||||
const startIsTop = startPosition.y - endPosition.y <= 0;
|
||||
|
||||
let startCircle: HTMLElement = document.createElement("div");
|
||||
let endCircle: HTMLElement = document.createElement("div");
|
||||
|
||||
|
@ -384,12 +401,8 @@ export default class Line extends Item<LineProps> {
|
|||
startCircle.style.borderRadius = "50%";
|
||||
startCircle.style.backgroundColor = `${color}`;
|
||||
startCircle.style.position = "absolute";
|
||||
startCircle.style.left = startIsLeft
|
||||
? `-${this.circleRadius}px`
|
||||
: `${width + lineWidth - this.circleRadius}px`;
|
||||
startCircle.style.top = startIsTop
|
||||
? `-${this.circleRadius}px`
|
||||
: `${height + lineWidth - this.circleRadius}px`;
|
||||
startCircle.style.left = `${x1 - this.circleRadius}px`;
|
||||
startCircle.style.top = `${y1 - this.circleRadius}px`;
|
||||
|
||||
endCircle.classList.add(
|
||||
"visual-console-item-line-circle",
|
||||
|
@ -400,12 +413,8 @@ export default class Line extends Item<LineProps> {
|
|||
endCircle.style.borderRadius = "50%";
|
||||
endCircle.style.backgroundColor = `${color}`;
|
||||
endCircle.style.position = "absolute";
|
||||
endCircle.style.left = startIsLeft
|
||||
? `${width + lineWidth - 8}px`
|
||||
: `-${this.circleRadius}px`;
|
||||
endCircle.style.top = startIsTop
|
||||
? `${height + lineWidth - this.circleRadius}px`
|
||||
: `-${this.circleRadius}px`;
|
||||
endCircle.style.left = `${x2 - this.circleRadius}px`;
|
||||
endCircle.style.top = `${y2 - this.circleRadius}px`;
|
||||
|
||||
if (element.parentElement !== null) {
|
||||
const circles = element.parentElement.getElementsByClassName(
|
||||
|
|
|
@ -1,25 +1,13 @@
|
|||
import { AnyObject, Position, Size, ItemMeta } from "../lib/types";
|
||||
import {
|
||||
parseIntOr,
|
||||
notEmptyStringOr,
|
||||
debounce,
|
||||
addMovementListener
|
||||
} from "../lib";
|
||||
import Item, { ItemType, ItemProps, itemBasePropsDecoder } from "../Item";
|
||||
import TypedEvent, { Listener, Disposable } from "../lib/TypedEvent";
|
||||
import { AnyObject, Position, ItemMeta } from "../lib/types";
|
||||
import { debounce, addMovementListener } from "../lib";
|
||||
import { ItemType } from "../Item";
|
||||
import Line, { LineProps, linePropsDecoder } from "./Line";
|
||||
|
||||
interface NetworkLinkProps extends ItemProps {
|
||||
const svgNS = "http://www.w3.org/2000/svg";
|
||||
|
||||
export interface NetworkLinkProps extends LineProps {
|
||||
// Overrided properties.
|
||||
readonly type: ItemType.NETWORK_LINK;
|
||||
label: null;
|
||||
isLinkEnabled: false;
|
||||
parentId: null;
|
||||
aclGroupId: null;
|
||||
// Custom properties.
|
||||
startPosition: Position;
|
||||
endPosition: Position;
|
||||
lineWidth: number;
|
||||
color: string | null;
|
||||
type: number;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,186 +22,17 @@ interface NetworkLinkProps extends ItemProps {
|
|||
export function networkLinkPropsDecoder(
|
||||
data: AnyObject
|
||||
): NetworkLinkProps | never {
|
||||
const props: NetworkLinkProps = {
|
||||
...itemBasePropsDecoder({ ...data, width: 1, height: 1 }), // Object spread. It will merge the properties of the two objects.
|
||||
type: ItemType.NETWORK_LINK,
|
||||
label: null,
|
||||
isLinkEnabled: false,
|
||||
parentId: null,
|
||||
aclGroupId: null,
|
||||
// Initialize Position & Size.
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
// Custom properties.
|
||||
startPosition: {
|
||||
x: parseIntOr(data.startX, 0),
|
||||
y: parseIntOr(data.startY, 0)
|
||||
},
|
||||
endPosition: {
|
||||
x: parseIntOr(data.endX, 0),
|
||||
y: parseIntOr(data.endY, 0)
|
||||
},
|
||||
lineWidth: parseIntOr(data.lineWidth || data.borderWidth, 1),
|
||||
color: notEmptyStringOr(data.borderColor || data.color, null)
|
||||
};
|
||||
|
||||
/*
|
||||
* We need to enhance the props with the extracted size and position
|
||||
* of the box cause there are missing at the props update. A better
|
||||
* solution would be overriding the props setter to do it there, but
|
||||
* the language doesn't allow it while targetting ES5.
|
||||
* TODO: We need to figure out a more consistent solution.
|
||||
*/
|
||||
|
||||
return {
|
||||
...props,
|
||||
// Enhance the props extracting the box size and position.
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
...NetworkLink.extractBoxSizeAndPosition(
|
||||
props.startPosition,
|
||||
props.endPosition
|
||||
)
|
||||
...linePropsDecoder(data), // Object spread. It will merge the properties of the two objects.
|
||||
type: ItemType.NETWORK_LINK,
|
||||
viewportOffsetX: 300,
|
||||
viewportOffsetY: 300
|
||||
};
|
||||
}
|
||||
|
||||
const svgNS = "http://www.w3.org/2000/svg";
|
||||
|
||||
export interface NetworkLinkMovedEvent {
|
||||
item: NetworkLink;
|
||||
startPosition: NetworkLinkProps["startPosition"];
|
||||
endPosition: NetworkLinkProps["endPosition"];
|
||||
}
|
||||
|
||||
export default class NetworkLink extends Item<NetworkLinkProps> {
|
||||
private circleRadius = 8;
|
||||
// To control if the line movement is enabled.
|
||||
private moveMode: boolean = false;
|
||||
// To control if the line is moving.
|
||||
private isMoving: boolean = false;
|
||||
|
||||
// Event manager for moved events.
|
||||
private readonly lineMovedEventManager = new TypedEvent<
|
||||
NetworkLinkMovedEvent
|
||||
>();
|
||||
// List of references to clean the event listeners.
|
||||
private readonly lineMovedEventDisposables: Disposable[] = [];
|
||||
|
||||
// This function will only run the 2nd arg function after the time
|
||||
// of the first arg have passed after its last execution.
|
||||
private debouncedStartPositionMovementSave = debounce(
|
||||
500, // ms.
|
||||
(x: Position["x"], y: Position["y"]) => {
|
||||
this.isMoving = false;
|
||||
const startPosition = { x, y };
|
||||
// Emit the movement event.
|
||||
this.lineMovedEventManager.emit({
|
||||
item: this,
|
||||
startPosition,
|
||||
endPosition: this.props.endPosition
|
||||
});
|
||||
}
|
||||
);
|
||||
// This property will store the function
|
||||
// to clean the movement listener.
|
||||
private removeStartPositionMovement: Function | null = null;
|
||||
|
||||
/**
|
||||
* Start the movement funtionality for the start position.
|
||||
* @param element Element to move inside its container.
|
||||
*/
|
||||
private initStartPositionMovementListener(
|
||||
element: HTMLElement,
|
||||
container: HTMLElement
|
||||
): void {
|
||||
this.removeStartPositionMovement = addMovementListener(
|
||||
element,
|
||||
(x: Position["x"], y: Position["y"]) => {
|
||||
// Calculate the center of the circle.
|
||||
x += this.circleRadius;
|
||||
y += this.circleRadius;
|
||||
|
||||
const startPosition = { x, y };
|
||||
|
||||
this.isMoving = true;
|
||||
this.props = {
|
||||
...this.props,
|
||||
startPosition
|
||||
};
|
||||
|
||||
// Run the end function.
|
||||
this.debouncedStartPositionMovementSave(x, y);
|
||||
},
|
||||
container
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Stop the movement fun
|
||||
*/
|
||||
private stopStartPositionMovementListener(): void {
|
||||
if (this.removeStartPositionMovement) {
|
||||
this.removeStartPositionMovement();
|
||||
this.removeStartPositionMovement = null;
|
||||
}
|
||||
}
|
||||
|
||||
// This function will only run the 2nd arg function after the time
|
||||
// of the first arg have passed after its last execution.
|
||||
private debouncedEndPositionMovementSave = debounce(
|
||||
500, // ms.
|
||||
(x: Position["x"], y: Position["y"]) => {
|
||||
this.isMoving = false;
|
||||
const endPosition = { x, y };
|
||||
// Emit the movement event.
|
||||
this.lineMovedEventManager.emit({
|
||||
item: this,
|
||||
endPosition,
|
||||
startPosition: this.props.startPosition
|
||||
});
|
||||
}
|
||||
);
|
||||
// This property will store the function
|
||||
// to clean the movement listener.
|
||||
private removeEndPositionMovement: Function | null = null;
|
||||
|
||||
/**
|
||||
* End the movement funtionality for the end position.
|
||||
* @param element Element to move inside its container.
|
||||
*/
|
||||
private initEndPositionMovementListener(
|
||||
element: HTMLElement,
|
||||
container: HTMLElement
|
||||
): void {
|
||||
this.removeEndPositionMovement = addMovementListener(
|
||||
element,
|
||||
(x: Position["x"], y: Position["y"]) => {
|
||||
// Calculate the center of the circle.
|
||||
x += this.circleRadius;
|
||||
y += this.circleRadius;
|
||||
|
||||
this.isMoving = true;
|
||||
this.props = {
|
||||
...this.props,
|
||||
endPosition: { x, y }
|
||||
};
|
||||
|
||||
// Run the end function.
|
||||
this.debouncedEndPositionMovementSave(x, y);
|
||||
},
|
||||
container
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Stop the movement function.
|
||||
*/
|
||||
private stopEndPositionMovementListener(): void {
|
||||
if (this.removeEndPositionMovement) {
|
||||
this.removeEndPositionMovement();
|
||||
this.removeEndPositionMovement = null;
|
||||
}
|
||||
}
|
||||
|
||||
export default class NetworkLink extends Line {
|
||||
private labelStart: string;
|
||||
private labelEnd: string;
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
|
@ -224,112 +43,130 @@ export default class NetworkLink extends Item<NetworkLinkProps> {
|
|||
*/
|
||||
super(
|
||||
{
|
||||
...props,
|
||||
...NetworkLink.extractBoxSizeAndPosition(
|
||||
props.startPosition,
|
||||
props.endPosition
|
||||
)
|
||||
...props
|
||||
},
|
||||
{
|
||||
...meta
|
||||
},
|
||||
true
|
||||
}
|
||||
);
|
||||
|
||||
this.moveMode = meta.editMode;
|
||||
this.init();
|
||||
}
|
||||
const x1 = props.startPosition.x - props.x + props.lineWidth / 2;
|
||||
const y1 = props.startPosition.y - props.y + props.lineWidth / 2;
|
||||
const x2 = props.endPosition.x - props.x + props.lineWidth / 2;
|
||||
const y2 = props.endPosition.y - props.y + props.lineWidth / 2;
|
||||
|
||||
/**
|
||||
* Classic and protected version of the setter of the `props` property.
|
||||
* Useful to override it from children classes.
|
||||
* @param newProps
|
||||
* @override Item.setProps
|
||||
*/
|
||||
public setProps(newProps: NetworkLinkProps) {
|
||||
super.setProps({
|
||||
...newProps,
|
||||
...NetworkLink.extractBoxSizeAndPosition(
|
||||
newProps.startPosition,
|
||||
newProps.endPosition
|
||||
)
|
||||
});
|
||||
}
|
||||
this.labelStart = `start (${x1},${y1})`;
|
||||
this.labelEnd = `end (${x2},${y2})`;
|
||||
|
||||
/**
|
||||
* Classic and protected version of the setter of the `meta` property.
|
||||
* Useful to override it from children classes.
|
||||
* @param newMetadata
|
||||
* @override Item.setMeta
|
||||
*/
|
||||
public setMeta(newMetadata: ItemMeta) {
|
||||
this.moveMode = newMetadata.editMode;
|
||||
super.setMeta({
|
||||
...newMetadata,
|
||||
lineMode: true
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
* To create the item's DOM representation.
|
||||
* @return Item.
|
||||
*/
|
||||
protected createDomElement(): HTMLElement {
|
||||
const element: HTMLDivElement = document.createElement("div");
|
||||
element.className = "line";
|
||||
protected debouncedStartPositionMovementSave = debounce(
|
||||
500, // ms.
|
||||
(x: Position["x"], y: Position["y"]) => {
|
||||
this.isMoving = false;
|
||||
const startPosition = { x, y };
|
||||
|
||||
const {
|
||||
x, // Box x
|
||||
y, // Box y
|
||||
width, // Box width
|
||||
height, // Box height
|
||||
lineWidth, // NetworkLink thickness
|
||||
startPosition, // NetworkLink start position
|
||||
endPosition, // NetworkLink end position
|
||||
color // NetworkLink color
|
||||
} = this.props;
|
||||
this.labelStart = "start (" + x + "," + y + ")";
|
||||
|
||||
const x1 = startPosition.x - x + lineWidth / 2;
|
||||
const y1 = startPosition.y - y + lineWidth / 2;
|
||||
const x2 = endPosition.x - x + lineWidth / 2;
|
||||
const y2 = endPosition.y - y + lineWidth / 2;
|
||||
// Emit the movement event.
|
||||
this.lineMovedEventManager.emit({
|
||||
item: this,
|
||||
startPosition,
|
||||
endPosition: this.props.endPosition
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// SVG container.
|
||||
const svg = document.createElementNS(svgNS, "svg");
|
||||
// Set SVG size.
|
||||
svg.setAttribute("width", `${width + lineWidth}`);
|
||||
svg.setAttribute("height", `${height + lineWidth}`);
|
||||
const line = document.createElementNS(svgNS, "line");
|
||||
line.setAttribute("x1", `${x1}`);
|
||||
line.setAttribute("y1", `${y1}`);
|
||||
line.setAttribute("x2", `${x2}`);
|
||||
line.setAttribute("y2", `${y2}`);
|
||||
line.setAttribute("stroke", color || "black");
|
||||
line.setAttribute("stroke-width", `${lineWidth}`);
|
||||
protected debouncedEndPositionMovementSave = debounce(
|
||||
500, // ms.
|
||||
(x: Position["x"], y: Position["y"]) => {
|
||||
this.isMoving = false;
|
||||
const endPosition = { x, y };
|
||||
|
||||
svg.append(line);
|
||||
element.append(svg);
|
||||
this.labelEnd = "end (" + x + "," + y + ")";
|
||||
|
||||
return element;
|
||||
}
|
||||
// Emit the movement event.
|
||||
this.lineMovedEventManager.emit({
|
||||
item: this,
|
||||
endPosition,
|
||||
startPosition: this.props.startPosition
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
protected updateDomElement(element: HTMLElement): void {
|
||||
const {
|
||||
super.updateDomElement(element);
|
||||
let {
|
||||
x, // Box x
|
||||
y, // Box y
|
||||
width, // Box width
|
||||
height, // Box height
|
||||
lineWidth, // NetworkLink thickness
|
||||
startPosition, // NetworkLink start position
|
||||
endPosition, // NetworkLink end position
|
||||
color // NetworkLink color
|
||||
lineWidth, // Line thickness
|
||||
viewportOffsetX, // viewport width,
|
||||
viewportOffsetY, // viewport heigth,
|
||||
startPosition, // Line start position
|
||||
endPosition, // Line end position
|
||||
color // Line color
|
||||
} = this.props;
|
||||
|
||||
const x1 = startPosition.x - x + lineWidth / 2;
|
||||
const y1 = startPosition.y - y + lineWidth / 2;
|
||||
const x2 = endPosition.x - x + lineWidth / 2;
|
||||
const y2 = endPosition.y - y + lineWidth / 2;
|
||||
// Font size and text adjustments.
|
||||
const fontsize = 7.4;
|
||||
const adjustment = 50;
|
||||
|
||||
// console.log(`startPosition [${startPosition.x},${startPosition.y}]`);
|
||||
// console.log(`x.y [${x},${y}]`);
|
||||
|
||||
let x1 = startPosition.x - x + lineWidth / 2 + viewportOffsetX / 2;
|
||||
let y1 = startPosition.y - y + lineWidth / 2 + viewportOffsetY / 2;
|
||||
let x2 = endPosition.x - x + lineWidth / 2 + viewportOffsetX / 2;
|
||||
let y2 = endPosition.y - y + lineWidth / 2 + viewportOffsetY / 2;
|
||||
|
||||
// Calculate angle (rotation).
|
||||
let g = (Math.atan((y2 - y1) / (x2 - x1)) * 180) / Math.PI;
|
||||
|
||||
if (Math.abs(g) > 0) {
|
||||
g = 0;
|
||||
}
|
||||
|
||||
// Calculate effective 'text' box sizes.
|
||||
const fontheight = 23;
|
||||
let labelStartWidth = this.labelStart.length * fontsize;
|
||||
let labelEndWidth = this.labelEnd.length * fontsize;
|
||||
let labelStartHeight = fontheight;
|
||||
let labelEndHeight = fontheight;
|
||||
|
||||
if (x1 < x2) {
|
||||
// x1 on left of x2.
|
||||
x1 += adjustment;
|
||||
x2 -= adjustment + labelEndWidth;
|
||||
}
|
||||
|
||||
if (x1 > x2) {
|
||||
// x1 on right of x2.
|
||||
x1 -= adjustment + labelStartWidth;
|
||||
x2 += adjustment;
|
||||
}
|
||||
|
||||
if (y1 < y2) {
|
||||
// y1 on y2.
|
||||
y1 += adjustment;
|
||||
y2 -= adjustment + labelEndHeight;
|
||||
}
|
||||
|
||||
if (y1 > y2) {
|
||||
// y1 under y2.
|
||||
y1 -= adjustment + labelStartHeight;
|
||||
y2 += adjustment;
|
||||
}
|
||||
|
||||
if (typeof color == "undefined") {
|
||||
color = "#000";
|
||||
}
|
||||
|
||||
// console.log(`to : ${x1},${y1} -------- ${x2}, ${y2}`);
|
||||
// console.log(`inclinacion de ${g}`);
|
||||
|
||||
const svgs = element.getElementsByTagName("svg");
|
||||
|
||||
|
@ -338,193 +175,76 @@ export default class NetworkLink extends Item<NetworkLinkProps> {
|
|||
|
||||
if (svg != null) {
|
||||
// Set SVG size.
|
||||
svg.setAttribute("width", `${width + lineWidth}`);
|
||||
svg.setAttribute("height", `${height + lineWidth}`);
|
||||
|
||||
const lines = svg.getElementsByTagNameNS(svgNS, "line");
|
||||
let groups = svg.getElementsByTagNameNS(svgNS, "g");
|
||||
while (groups.length > 0) {
|
||||
groups[0].remove();
|
||||
}
|
||||
|
||||
if (lines.length > 0) {
|
||||
const line = lines.item(0);
|
||||
|
||||
if (line != null) {
|
||||
line.setAttribute("x1", `${x1}`);
|
||||
line.setAttribute("y1", `${y1}`);
|
||||
line.setAttribute("x2", `${x2}`);
|
||||
line.setAttribute("y2", `${y2}`);
|
||||
line.setAttribute("stroke", color || "black");
|
||||
line.setAttribute("stroke-width", `${lineWidth}`);
|
||||
// let rect = document.createElementNS(
|
||||
// "http://www.w3.org/2000/svg",
|
||||
// "rect"
|
||||
// );
|
||||
// rect.setAttribute("x", SVGRect.x);
|
||||
// rect.setAttribute("y", SVGRect.y);
|
||||
// rect.setAttribute("width", SVGRect.width);
|
||||
// rect.setAttribute("height", SVGRect.height);
|
||||
// rect.setAttribute("fill", "yellow");
|
||||
|
||||
let start = document.createElementNS(svgNS, "g");
|
||||
start.setAttribute("x", `${x1}`);
|
||||
start.setAttribute("y", `${y1}`);
|
||||
start.setAttribute("width", `${labelStartWidth + fontsize * 2}`);
|
||||
start.setAttribute("height", `${labelStartHeight}`);
|
||||
start.setAttribute("transform", `rotate(${g} ${x1} ${y1})`);
|
||||
|
||||
let sr = document.createElementNS(svgNS, "rect");
|
||||
sr.setAttribute("x", `${x1}`);
|
||||
sr.setAttribute("y", `${y1}`);
|
||||
sr.setAttribute("width", `${labelStartWidth}`);
|
||||
sr.setAttribute("height", `${labelStartHeight}`);
|
||||
sr.setAttribute("stroke", `${color}`);
|
||||
sr.setAttribute("stroke-width", "2");
|
||||
sr.setAttribute("fill", "#FFF");
|
||||
start.append(sr);
|
||||
|
||||
let st = document.createElementNS(svgNS, "text");
|
||||
st.setAttribute("x", `${x1 + fontsize}`);
|
||||
st.setAttribute("y", `${y1 + (fontheight * 2) / 3}`);
|
||||
st.setAttribute("fill", "#000");
|
||||
st.textContent = this.labelStart;
|
||||
st.setAttribute("transform", `rotate(${g} ${x1} ${y1})`);
|
||||
start.append(st);
|
||||
|
||||
let end = document.createElementNS(svgNS, "g");
|
||||
let er = document.createElementNS(svgNS, "rect");
|
||||
er.setAttribute("x", `${x2}`);
|
||||
er.setAttribute("y", `${y2}`);
|
||||
er.setAttribute("width", `${labelEndWidth + fontsize * 2}`);
|
||||
er.setAttribute("height", `${labelEndHeight}`);
|
||||
er.setAttribute("stroke", `${color}`);
|
||||
er.setAttribute("stroke-width", "2");
|
||||
er.setAttribute("fill", "#FFF");
|
||||
er.setAttribute("transform", `rotate(${g} ${x1} ${y1})`);
|
||||
end.append(er);
|
||||
|
||||
let et = document.createElementNS(svgNS, "text");
|
||||
et.setAttribute("x", `${x2 + fontsize}`);
|
||||
et.setAttribute("y", `${y2 + (fontheight * 2) / 3}`);
|
||||
et.setAttribute("fill", "#000");
|
||||
et.textContent = this.labelEnd;
|
||||
et.setAttribute("transform", `rotate(${g} ${x1} ${y1})`);
|
||||
end.append(et);
|
||||
|
||||
svg.append(start);
|
||||
svg.append(end);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.moveMode) {
|
||||
const startIsLeft = startPosition.x - endPosition.x <= 0;
|
||||
const startIsTop = startPosition.y - endPosition.y <= 0;
|
||||
|
||||
let startCircle: HTMLElement = document.createElement("div");
|
||||
let endCircle: HTMLElement = document.createElement("div");
|
||||
|
||||
if (this.isMoving) {
|
||||
const circlesStart = element.getElementsByClassName(
|
||||
"visual-console-item-line-circle-start"
|
||||
);
|
||||
if (circlesStart.length > 0) {
|
||||
const circle = circlesStart.item(0) as HTMLElement;
|
||||
if (circle) startCircle = circle;
|
||||
}
|
||||
const circlesEnd = element.getElementsByClassName(
|
||||
"visual-console-item-line-circle-end"
|
||||
);
|
||||
if (circlesEnd.length > 0) {
|
||||
const circle = circlesEnd.item(0) as HTMLElement;
|
||||
if (circle) endCircle = circle;
|
||||
}
|
||||
}
|
||||
|
||||
startCircle.classList.add(
|
||||
"visual-console-item-line-circle",
|
||||
"visual-console-item-line-circle-start"
|
||||
);
|
||||
startCircle.style.width = `${this.circleRadius * 2}px`;
|
||||
startCircle.style.height = `${this.circleRadius * 2}px`;
|
||||
startCircle.style.borderRadius = "50%";
|
||||
startCircle.style.backgroundColor = `${color}`;
|
||||
startCircle.style.position = "absolute";
|
||||
startCircle.style.left = startIsLeft
|
||||
? `-${this.circleRadius}px`
|
||||
: `${width + lineWidth - this.circleRadius}px`;
|
||||
startCircle.style.top = startIsTop
|
||||
? `-${this.circleRadius}px`
|
||||
: `${height + lineWidth - this.circleRadius}px`;
|
||||
|
||||
endCircle.classList.add(
|
||||
"visual-console-item-line-circle",
|
||||
"visual-console-item-line-circle-end"
|
||||
);
|
||||
endCircle.style.width = `${this.circleRadius * 2}px`;
|
||||
endCircle.style.height = `${this.circleRadius * 2}px`;
|
||||
endCircle.style.borderRadius = "50%";
|
||||
endCircle.style.backgroundColor = `${color}`;
|
||||
endCircle.style.position = "absolute";
|
||||
endCircle.style.left = startIsLeft
|
||||
? `${width + lineWidth - 8}px`
|
||||
: `-${this.circleRadius}px`;
|
||||
endCircle.style.top = startIsTop
|
||||
? `${height + lineWidth - this.circleRadius}px`
|
||||
: `-${this.circleRadius}px`;
|
||||
|
||||
if (element.parentElement !== null) {
|
||||
const circles = element.parentElement.getElementsByClassName(
|
||||
"visual-console-item-line-circle"
|
||||
);
|
||||
while (circles.length > 0) {
|
||||
const circle = circles.item(0);
|
||||
if (circle) circle.remove();
|
||||
}
|
||||
|
||||
element.parentElement.appendChild(startCircle);
|
||||
element.parentElement.appendChild(endCircle);
|
||||
}
|
||||
|
||||
// Init the movement listeners.
|
||||
this.initStartPositionMovementListener(startCircle, this.elementRef
|
||||
.parentElement as HTMLElement);
|
||||
this.initEndPositionMovementListener(endCircle, this.elementRef
|
||||
.parentElement as HTMLElement);
|
||||
} else if (!this.moveMode) {
|
||||
this.stopStartPositionMovementListener();
|
||||
// Remove circles.
|
||||
if (element.parentElement !== null) {
|
||||
const circles = element.parentElement.getElementsByClassName(
|
||||
"visual-console-item-line-circle"
|
||||
);
|
||||
|
||||
while (circles.length > 0) {
|
||||
const circle = circles.item(0);
|
||||
if (circle) circle.remove();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.stopStartPositionMovementListener();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the size and position of the box from
|
||||
* the start and the finish of the line.
|
||||
* @param props Item properties.
|
||||
*/
|
||||
public static extractBoxSizeAndPosition(
|
||||
startPosition: Position,
|
||||
endPosition: Position
|
||||
): Size & Position {
|
||||
return {
|
||||
width: Math.abs(startPosition.x - endPosition.x),
|
||||
height: Math.abs(startPosition.y - endPosition.y),
|
||||
x: Math.min(startPosition.x, endPosition.x),
|
||||
y: Math.min(startPosition.y, endPosition.y)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the position into the properties and move the DOM container.
|
||||
* @param x Horizontal axis position.
|
||||
* @param y Vertical axis position.
|
||||
* @override item function
|
||||
*/
|
||||
public move(x: number, y: number): void {
|
||||
super.moveElement(x, y);
|
||||
const startIsLeft =
|
||||
this.props.startPosition.x - this.props.endPosition.x <= 0;
|
||||
const startIsTop =
|
||||
this.props.startPosition.y - this.props.endPosition.y <= 0;
|
||||
|
||||
const start = {
|
||||
x: startIsLeft ? x : this.props.width + x,
|
||||
y: startIsTop ? y : this.props.height + y
|
||||
};
|
||||
|
||||
const end = {
|
||||
x: startIsLeft ? this.props.width + x : x,
|
||||
y: startIsTop ? this.props.height + y : y
|
||||
};
|
||||
|
||||
this.props = {
|
||||
...this.props,
|
||||
startPosition: start,
|
||||
endPosition: end
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* To remove the event listeners and the elements from the DOM.
|
||||
* @override Item.remove
|
||||
*/
|
||||
public remove(): void {
|
||||
// Clear the item's event listeners.
|
||||
this.stopStartPositionMovementListener();
|
||||
// Call the parent's .remove()
|
||||
super.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* To add an event handler to the movement of visual console elements.
|
||||
* @param listener Function which is going to be executed when a linked console is moved.
|
||||
*
|
||||
* @override Item.onMoved
|
||||
*/
|
||||
public onNetworkLinkMovementFinished(
|
||||
listener: Listener<NetworkLinkMovedEvent>
|
||||
): Disposable {
|
||||
/*
|
||||
* The '.on' function returns a function which will clean the event
|
||||
* listener when executed. We store all the 'dispose' functions to
|
||||
* call them when the item should be cleared.
|
||||
*/
|
||||
const disposable = this.lineMovedEventManager.on(listener);
|
||||
this.lineMovedEventDisposables.push(disposable);
|
||||
|
||||
return disposable;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue