WIP sticky lines

This commit is contained in:
fbsanchez 2020-11-06 20:37:37 +01:00
parent c59042c034
commit 067a19f69b
8 changed files with 263 additions and 20 deletions

View File

@ -365,6 +365,8 @@ function load_modal(settings) {
//$(".ui-dialog-titlebar-close").hide(); //$(".ui-dialog-titlebar-close").hide();
}, },
close: function() { close: function() {
$(this).dialog("destroy");
if (id_modal_target != undefined) { if (id_modal_target != undefined) {
$(id_modal_target).remove(); $(id_modal_target).remove();
} }
@ -372,14 +374,12 @@ function load_modal(settings) {
if (settings.cleanup != undefined) { if (settings.cleanup != undefined) {
settings.cleanup(); settings.cleanup();
} }
$(this).dialog("destroy");
}, },
beforeClose: settings.beforeClose() beforeClose: settings.beforeClose()
}); });
}, },
error: function(data) { error: function(data) {
// console.log(data); console.error(data);
} }
}); });
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -297,6 +297,14 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
* @param element Element to move inside its container. * @param element Element to move inside its container.
*/ */
private initMovementListener(element: HTMLElement): void { private initMovementListener(element: HTMLElement): void {
// Avoid line movement as 'block' force using circles.
if (
this.props.type == ItemType.LINE_ITEM ||
this.props.type == ItemType.NETWORK_LINK
) {
return;
}
this.removeMovement = addMovementListener( this.removeMovement = addMovementListener(
element, element,
(x: Position["x"], y: Position["y"]) => { (x: Position["x"], y: Position["y"]) => {
@ -376,6 +384,12 @@ abstract class VisualConsoleItem<Props extends ItemProps> {
* @param element Element to move inside its container. * @param element Element to move inside its container.
*/ */
protected initResizementListener(element: HTMLElement): void { protected initResizementListener(element: HTMLElement): void {
if (
this.props.type == ItemType.LINE_ITEM ||
this.props.type == ItemType.NETWORK_LINK
) {
return;
}
this.removeResizement = addResizementListener( this.removeResizement = addResizementListener(
element, element,
(width: Size["width"], height: Size["height"]) => { (width: Size["width"], height: Size["height"]) => {

View File

@ -36,7 +36,6 @@ import DonutGraph, { donutGraphPropsDecoder } from "./items/DonutGraph";
import BarsGraph, { barsGraphPropsDecoder } from "./items/BarsGraph"; import BarsGraph, { barsGraphPropsDecoder } from "./items/BarsGraph";
import ModuleGraph, { moduleGraphPropsDecoder } from "./items/ModuleGraph"; import ModuleGraph, { moduleGraphPropsDecoder } from "./items/ModuleGraph";
import Service, { servicePropsDecoder } from "./items/Service"; import Service, { servicePropsDecoder } from "./items/Service";
import { FormContainer } from "./Form";
// TODO: Document. // TODO: Document.
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
@ -212,9 +211,13 @@ export default class VisualConsole {
[key: string]: Line; [key: string]: Line;
} = {}; } = {};
// Dictionary which store the created links. // Dictionary which store the related items (by ID).
private lineLinks: { private lineLinks: {
[key: string]: Line; [key: number]: { [key: number]: { [key: string]: number } };
} = {};
private lines: {
[key: number]: { [key: string]: number };
} = {}; } = {};
// Event manager for click events. // Event manager for click events.
@ -277,6 +280,9 @@ export default class VisualConsole {
} }
}); });
// Move lines conneted with this item.
this.updateLinesConnected(e.item.props, e.newPosition, e.prevPosition);
// console.log(`Moved element #${e.item.props.id}`, e); // console.log(`Moved element #${e.item.props.id}`, e);
}; };
@ -289,6 +295,28 @@ export default class VisualConsole {
// console.log(`Movement finished for element #${e.item.props.id}`, e); // console.log(`Movement finished for element #${e.item.props.id}`, e);
}; };
/**
* Verifies if x,y are inside item coordinates.
* @param x Coordinate X
* @param y Coordinate Y
* @param item ItemProps instance.
*/
private coordinatesInItem(x: number, y: number, props: ItemProps) {
if (props.type == ItemType.LINE_ITEM) {
return false;
}
if (
x > props.x &&
x < props.x + props.width &&
y > props.y &&
y < props.y + props.height
) {
return true;
}
return false;
}
/** /**
* React to a line movement. * React to a line movement.
* @param e Event object. * @param e Event object.
@ -296,7 +324,12 @@ export default class VisualConsole {
private handleLineElementMovementFinished: ( private handleLineElementMovementFinished: (
e: LineMovedEvent e: LineMovedEvent
) => void = e => { ) => void = e => {
// Update links.
this.refreshLink(e.item);
// Build line relationships between items and lines.
this.lineMovedEventManager.emit(e); this.lineMovedEventManager.emit(e);
// console.log(`Movement finished for element #${e.item.props.id}`, e); // console.log(`Movement finished for element #${e.item.props.id}`, e);
}; };
@ -384,6 +417,196 @@ export default class VisualConsole {
this.unSelectItems(); this.unSelectItems();
}; };
/**
* Refresh link for given line.
*
* @param line Line.
*/
protected refreshLink(l: Line) {
let line: number = l.props.id;
let itemAtStart = 0;
let itemAtEnd = 0;
for (let i in this.elementsById) {
if (
this.coordinatesInItem(
l.props.startPosition.x,
l.props.startPosition.y,
this.elementsById[i].props
)
) {
// Start position at element i.
itemAtStart = parseInt(i);
}
if (
this.coordinatesInItem(
l.props.endPosition.x,
l.props.endPosition.y,
this.elementsById[i].props
)
) {
// Start position at element i.
itemAtEnd = parseInt(i);
}
}
if (this.lineLinks == null) {
this.lineLinks = {};
}
if (this.lines == null) {
this.lines = {};
}
console.log(`${line},${itemAtStart},${itemAtEnd}`);
if (itemAtStart == line) {
itemAtStart = 0;
}
if (itemAtEnd == line) {
itemAtEnd = 0;
}
console.log(`Agrego linea [${line}] de ${itemAtStart} a ${itemAtEnd}`);
// Initialize line if not registered.
if (this.lines[line] == null) {
this.lines[line] = {
start: itemAtStart,
end: itemAtEnd
};
}
console.log("inicio");
// Register 'start' side of the line.
if (itemAtStart > 0) {
// Initialize.
if (this.lineLinks[itemAtStart] == null) {
this.lineLinks[itemAtStart] = {};
}
// Assign.
this.lineLinks[itemAtStart][line] = {
start: itemAtStart,
end: itemAtEnd
};
// Register line if not exists prviously.
} else {
// Clean previous line relationship.
if (this.lines[line]["start"] > 0) {
console.log(`desconecto ${line} de ${this.lines[line]["start"]}`);
this.lineLinks[this.lines[line]["start"]][line]["start"] = 0;
this.lines[line]["start"] = 0;
}
}
console.log("final");
if (itemAtEnd > 0) {
if (this.lineLinks[itemAtEnd] == null) {
this.lineLinks[itemAtEnd] = {};
}
this.lineLinks[itemAtEnd][line] = {
start: itemAtStart,
end: itemAtEnd
};
} else {
console.log(this.lines[line]["end"]);
// Clean previous line relationship.
if (this.lines[line]["end"] > 0) {
console.log(`desconecto ${line} de ${this.lines[line]["end"]}`);
this.lineLinks[this.lines[line]["end"]][line]["end"] = 0;
this.lines[line]["end"] = 0;
}
}
console.log("limpiar");
this.lines[line] = {
start: itemAtStart,
end: itemAtEnd
};
// Cleanup.
for (let i in this.lineLinks) {
if (
this.lineLinks[i][line].start == 0 &&
this.lineLinks[i][line].end == 0
) {
// Object not connected to a line.
delete this.lineLinks[i][line];
if (Object.keys(this.lineLinks[i]).length === 0) {
delete this.lineLinks[i];
}
}
}
console.log("Enlaces:");
console.log(this.lineLinks);
console.log("lines:");
console.log(this.lines);
console.log("-------------------------");
}
/**
* Updates lines connected to this item.
*
* @param item Item moved.
* @param newPosition New location for item.
* @param oldPosition Old location for item.
*/
protected updateLinesConnected(
item: ItemProps,
to: Position,
from: Position
) {
let xDiff = from.x - to.x;
let yDiff = from.y - to.y;
console.log(`diff: ${xDiff}, ${yDiff}`);
Object.keys(this.lineLinks[item.id]).forEach(i => {
let lineId = parseInt(i);
let line = this.elementsById[lineId] as Line;
if (line.props) {
console.log(
`antes: (${line.props.startPosition.x},${
line.props.startPosition.y
}) (${line.props.endPosition.x},${line.props.endPosition.y})`
);
if (line.props.id == this.lineLinks[item.id][lineId]["start"]) {
line.props = {
...line.props,
x: line.props.startPosition.x + xDiff,
y: line.props.startPosition.y + yDiff
};
}
if (line.props.id == this.lineLinks[item.id][lineId]["end"]) {
line.props = {
...line.props,
x: line.props.endPosition.x + xDiff,
y: line.props.endPosition.y + yDiff
};
}
console.log("eem");
console.log(
`despues: (${line.props.startPosition.x},${
line.props.startPosition.y
}) (${line.props.endPosition.x},${line.props.endPosition.y})`
);
line.render();
}
//this.updateElement(
// ...line.props,
//);
});
}
public constructor( public constructor(
container: HTMLElement, container: HTMLElement,
props: AnyObject, props: AnyObject,
@ -435,17 +658,18 @@ export default class VisualConsole {
// Item event handlers. // Item event handlers.
itemInstance.onRemove(context.handleElementRemove); itemInstance.onRemove(context.handleElementRemove);
itemInstance.onSelectionChanged(context.handleElementSelectionChanged); itemInstance.onSelectionChanged(context.handleElementSelectionChanged);
// TODO:Continue
itemInstance.onClick(context.handleElementClick); itemInstance.onClick(context.handleElementClick);
itemInstance.onDblClick(context.handleElementDblClick); itemInstance.onDblClick(context.handleElementDblClick);
itemInstance.onMoved(context.handleElementMovement);
itemInstance.onMovementFinished(context.handleElementMovementFinished); // TODO:Continue
if (itemInstance instanceof Line) { if (itemInstance instanceof Line) {
itemInstance.onLineMovementFinished( itemInstance.onLineMovementFinished(
context.handleLineElementMovementFinished context.handleLineElementMovementFinished
); );
this.refreshLink(itemInstance);
} else { } else {
itemInstance.onMoved(context.handleElementMovement);
itemInstance.onMovementFinished(context.handleElementMovementFinished);
itemInstance.onResized(context.handleElementResizement); itemInstance.onResized(context.handleElementResizement);
itemInstance.onResizeFinished(context.handleElementResizementFinished); itemInstance.onResizeFinished(context.handleElementResizementFinished);
} }
@ -454,7 +678,7 @@ export default class VisualConsole {
context.containerRef.append(itemInstance.elementRef); context.containerRef.append(itemInstance.elementRef);
return itemInstance; return itemInstance;
} catch (error) { } catch (error) {
console.log("Error creating a new element:", error.message); console.error("Error creating a new element:", error.message);
} }
return; return;
} }
@ -491,7 +715,7 @@ export default class VisualConsole {
try { try {
this.elementsById[item.id].props = decodeProps(item); this.elementsById[item.id].props = decodeProps(item);
} catch (error) { } catch (error) {
console.log("Error updating an element:", error.message); console.error("Error updating an element:", error.message);
} }
} }
} }
@ -512,7 +736,7 @@ export default class VisualConsole {
...decodeProps(item) ...decodeProps(item)
}; };
} catch (error) { } catch (error) {
console.log("Error updating element:", error.message); console.error("Error updating element:", error.message);
} }
// Re-build relations. // Re-build relations.

View File

@ -90,10 +90,7 @@ export default class NetworkLink extends Line {
50, // ms. 50, // ms.
(x: Position["x"], y: Position["y"]) => { (x: Position["x"], y: Position["y"]) => {
this.isMoving = false; this.isMoving = false;
const endPosition = { const endPosition = { x, y };
x,
y
};
// Re-Paint after move. // Re-Paint after move.
this.render(); this.render();
@ -127,6 +124,8 @@ export default class NetworkLink extends Line {
labelStartHeight labelStartHeight
} = this.props; } = this.props;
console.log("a pintar");
const svgs = element.getElementsByTagName("svg"); const svgs = element.getElementsByTagName("svg");
let line; let line;
let svg; let svg;
@ -178,7 +177,7 @@ export default class NetworkLink extends Line {
} }
// Calculate effective 'text' box sizes. // Calculate effective 'text' box sizes.
const fontheight = 23; const fontheight = 25;
if (labelStartWidth <= 0) { if (labelStartWidth <= 0) {
labelStartWidth = labelStart.length * fontsize; labelStartWidth = labelStart.length * fontsize;
} }

View File

@ -71,6 +71,8 @@ export default class StaticGraph extends Item<StaticGraphProps> {
const imgSrc = this.props.statusImageSrc || this.props.imageSrc; const imgSrc = this.props.statusImageSrc || this.props.imageSrc;
const element = document.createElement("div"); const element = document.createElement("div");
element.className = "static-graph"; element.className = "static-graph";
element.setAttribute("ondragstart", "return false;");
element.setAttribute("draggable", "false");
element.style.backgroundImage = `url(${imgSrc})`; element.style.backgroundImage = `url(${imgSrc})`;
element.style.backgroundRepeat = "no-repeat"; element.style.backgroundRepeat = "no-repeat";
element.style.backgroundSize = "contain"; element.style.backgroundSize = "contain";

View File

@ -553,6 +553,10 @@ export function addMovementListener(
// Disable the drag temporarily. // Disable the drag temporarily.
element.draggable = false; element.draggable = false;
// Fix for Firefox browser.
element.setAttribute("ondragstart", "return false;");
element.setAttribute("draggable", "false");
// Store the difference between the cursor and // Store the difference between the cursor and
// the initial coordinates of the element. // the initial coordinates of the element.
const elementOffset = getOffset(element, container); const elementOffset = getOffset(element, container);