WIP NetworkLink

This commit is contained in:
fbsanchez 2020-10-30 14:07:44 +01:00
parent 326d1dac49
commit 90f199c5ad
7 changed files with 308 additions and 145 deletions

View File

@ -195,7 +195,13 @@ function createVisualConsole(
); );
} else if (meta.lineMode && item.props.type == 21) { } else if (meta.lineMode && item.props.type == 21) {
confirmDialog({ confirmDialog({
title: "todo" title: "todo",
message:
"<pre>" +
item.props.labelStart +
"</pre><br><pre>" +
item.props.labelEnd +
"</pre>"
}); });
} }
}); });

View File

@ -2257,7 +2257,7 @@ class Item extends CachedModel
} }
} }
if ($result === false && $result === '') { if ($result === false || $result === '') {
$result = []; $result = [];
} }

View File

@ -56,15 +56,21 @@ final class NetworkLink extends Model
protected function decode(array $data): array protected function decode(array $data): array
{ {
return [ return [
'id' => (int) $data['id'], 'id' => (int) $data['id'],
'type' => NETWORK_LINK, 'type' => NETWORK_LINK,
'startX' => static::extractStartX($data), 'startX' => static::extractStartX($data),
'startY' => static::extractStartY($data), 'startY' => static::extractStartY($data),
'endX' => static::extractEndX($data), 'endX' => static::extractEndX($data),
'endY' => static::extractEndY($data), 'endY' => static::extractEndY($data),
'isOnTop' => static::extractIsOnTop($data), 'isOnTop' => static::extractIsOnTop($data),
'borderWidth' => static::extractBorderWidth($data), 'borderWidth' => static::extractBorderWidth($data),
'borderColor' => static::extractBorderColor($data), 'borderColor' => static::extractBorderColor($data),
'labelStart' => static::extractLabelStart($data),
'labelEnd' => static::extractLabelEnd($data),
'labelStartWidth' => static::extractlabelStartWidth($data),
'labelEndWidth' => static::extractlabelEndWidth($data),
'labelStartHeight' => static::extractlabelStartHeight($data),
'labelEndHeight' => static::extractlabelEndHeight($data),
]; ];
} }
@ -182,6 +188,130 @@ final class NetworkLink extends Model
} }
/**
* Extract information to fullfil labels in NetworkLinks.
*
* @param string $ref Sub-data to extract from "label".
* @param array $data Unknown input data structure.
*
* @return mixed Reference from json encoded data stored in db.
*/
private static function extractExtra(?string $ref, array $data)
{
if ($data['label'] === null) {
return null;
}
$return = json_decode($data['label'], true);
if (json_last_error() === JSON_ERROR_NONE) {
if ($ref !== null) {
return $return[$ref];
}
return $return;
}
return null;
}
/**
* Extract label Start.
*
* @param array $data Unknown input data structure.
*
* @return mixed String representing label Start or null.
*/
private static function extractLabelStart(array $data)
{
return static::extractExtra(
'labelStart',
$data
);
}
/**
* Extract label End.
*
* @param array $data Unknown input data structure.
*
* @return mixed String representing label End or null.
*/
private static function extractLabelEnd(array $data)
{
return static::extractExtra(
'labelEnd',
$data
);
}
/**
* Extract label StartWidth.
*
* @param array $data Unknown input data structure.
*
* @return mixed Float representing label StartWidth or null.
*/
private static function extractlabelStartWidth(array $data)
{
return static::extractExtra(
'labelStartWidth',
$data
);
}
/**
* Extract label EndWidth.
*
* @param array $data Unknown input data structure.
*
* @return mixed Float representing label EndWidth or null.
*/
private static function extractlabelEndWidth(array $data)
{
return static::extractExtra(
'labelEndWidth',
$data
);
}
/**
* Extract label StartHeight.
*
* @param array $data Unknown input data structure.
*
* @return mixed Float representing label StartHeight or null.
*/
private static function extractlabelStartHeight(array $data)
{
return static::extractExtra(
'labelStartHeight',
$data
);
}
/**
* Extract label EndHeight.
*
* @param array $data Unknown input data structure.
*
* @return mixed Float representing label EndHeight or null.
*/
private static function extractlabelEndHeight(array $data)
{
return static::extractExtra(
'labelEndHeight',
$data
);
}
/** /**
* Obtain a vc item data structure from the database using a filter. * Obtain a vc item data structure from the database using a filter.
* *
@ -216,6 +346,26 @@ final class NetworkLink extends Model
} }
/**
* Builds a label depending on the information available.
*
* @return string JSON encoded results to be stored in DB.
*/
private function buildLabels()
{
return json_encode(
[
'labelStart' => 'cadena inicio',
'labelEnd' => 'cadena fin',
'labelStartWidth' => 105,
'labelStartHeight' => 105,
'labelEndWidth' => 105,
'labelEndHeight' => 105,
]
);
}
/** /**
* Return a valid representation of a record in database. * Return a valid representation of a record in database.
* *
@ -286,6 +436,9 @@ final class NetworkLink extends Model
$result['border_color'] = $borderColor; $result['border_color'] = $borderColor;
} }
// Build labels.
$result['label'] = $this->buildLabels();
$showOnTop = static::issetInArray( $showOnTop = static::issetInArray(
$data, $data,
[ [
@ -334,38 +487,6 @@ final class NetworkLink extends Model
} }
/**
* Extract item width.
*
* @param array $data Unknown input data structure.
*
* @return integer Item width. 0 by default.
*/
private static function getWidth(array $data)
{
return static::parseIntOr(
static::issetInArray($data, ['width', 'endX']),
null
);
}
/**
* Extract item height.
*
* @param array $data Unknown input data structure.
*
* @return integer Item height. 0 by default.
*/
private static function getHeight(array $data)
{
return static::parseIntOr(
static::issetInArray($data, ['height', 'endY']),
null
);
}
/** /**
* Extract a border width value. * Extract a border width value.
* *

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -22,6 +22,12 @@ export interface LineProps extends ItemProps {
color: string | null; color: string | null;
viewportOffsetX: number; viewportOffsetX: number;
viewportOffsetY: number; viewportOffsetY: number;
labelEnd: string;
labelStart: string;
labelEndWidth: number;
labelEndHeight: number;
labelStartWidth: number;
labelStartHeight: number;
} }
/** /**
@ -58,7 +64,13 @@ export function linePropsDecoder(data: AnyObject): LineProps | never {
lineWidth: parseIntOr(data.lineWidth || data.borderWidth, 1), lineWidth: parseIntOr(data.lineWidth || data.borderWidth, 1),
color: notEmptyStringOr(data.borderColor || data.color, null), color: notEmptyStringOr(data.borderColor || data.color, null),
viewportOffsetX: 0, viewportOffsetX: 0,
viewportOffsetY: 0 viewportOffsetY: 0,
labelEnd: notEmptyStringOr(data.labelEnd, ""),
labelEndWidth: parseIntOr(data.labelEndWidth, 0),
labelEndHeight: parseIntOr(data.labelEndHeight, 0),
labelStart: notEmptyStringOr(data.labelStart, ""),
labelStartWidth: parseIntOr(data.labelStartWidth, 0),
labelStartHeight: parseIntOr(data.labelStartHeight, 0)
}; };
/* /*

View File

@ -1,5 +1,10 @@
import { AnyObject, Position, ItemMeta } from "../lib/types"; import { AnyObject, Position, ItemMeta } from "../lib/types";
import { debounce, addMovementListener } from "../lib"; import {
debounce,
addMovementListener,
notEmptyStringOr,
parseIntOr
} from "../lib";
import { ItemType } from "../Item"; import { ItemType } from "../Item";
import Line, { LineProps, linePropsDecoder } from "./Line"; import Line, { LineProps, linePropsDecoder } from "./Line";
@ -8,6 +13,8 @@ const svgNS = "http://www.w3.org/2000/svg";
export interface NetworkLinkProps extends LineProps { export interface NetworkLinkProps extends LineProps {
// Overrided properties. // Overrided properties.
type: number; type: number;
labelStart: string;
labelEnd: string;
} }
/** /**
@ -26,13 +33,17 @@ export function networkLinkPropsDecoder(
...linePropsDecoder(data), // Object spread. It will merge the properties of the two objects. ...linePropsDecoder(data), // Object spread. It will merge the properties of the two objects.
type: ItemType.NETWORK_LINK, type: ItemType.NETWORK_LINK,
viewportOffsetX: 300, viewportOffsetX: 300,
viewportOffsetY: 300 viewportOffsetY: 300,
labelEnd: notEmptyStringOr(data.labelEnd, ""),
labelEndWidth: parseIntOr(data.labelEndWidth, 0),
labelEndHeight: parseIntOr(data.labelEndHeight, 0),
labelStart: notEmptyStringOr(data.labelStart, ""),
labelStartWidth: parseIntOr(data.labelStartWidth, 0),
labelStartHeight: parseIntOr(data.labelStartHeight, 0)
}; };
} }
export default class NetworkLink extends Line { export default class NetworkLink extends Line {
private labelStart: string;
private labelEnd: string;
/** /**
* @override * @override
*/ */
@ -50,14 +61,6 @@ export default class NetworkLink extends Line {
} }
); );
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;
this.labelStart = `start (${x1},${y1})`;
this.labelEnd = `end (${x2},${y2})`;
this.render(); this.render();
} }
@ -65,12 +68,13 @@ export default class NetworkLink extends Line {
* @override * @override
*/ */
protected debouncedStartPositionMovementSave = debounce( protected debouncedStartPositionMovementSave = debounce(
500, // ms. 50, // ms.
(x: Position["x"], y: Position["y"]) => { (x: Position["x"], y: Position["y"]) => {
this.isMoving = false; this.isMoving = false;
const startPosition = { x, y }; const startPosition = { x, y };
this.labelStart = "start (" + x + "," + y + ")"; // Re-Paint after move.
this.render();
// Emit the movement event. // Emit the movement event.
this.lineMovedEventManager.emit({ this.lineMovedEventManager.emit({
@ -82,12 +86,16 @@ export default class NetworkLink extends Line {
); );
protected debouncedEndPositionMovementSave = debounce( protected debouncedEndPositionMovementSave = debounce(
500, // ms. 50, // ms.
(x: Position["x"], y: Position["y"]) => { (x: Position["x"], y: Position["y"]) => {
this.isMoving = false; this.isMoving = false;
const endPosition = { x, y }; const endPosition = {
x,
y
};
this.labelEnd = "end (" + x + "," + y + ")"; // Re-Paint after move.
this.render();
// Emit the movement event. // Emit the movement event.
this.lineMovedEventManager.emit({ this.lineMovedEventManager.emit({
@ -100,6 +108,7 @@ export default class NetworkLink extends Line {
protected updateDomElement(element: HTMLElement): void { protected updateDomElement(element: HTMLElement): void {
super.updateDomElement(element); super.updateDomElement(element);
let { let {
x, // Box x x, // Box x
y, // Box y y, // Box y
@ -108,16 +117,52 @@ export default class NetworkLink extends Line {
viewportOffsetY, // viewport heigth, viewportOffsetY, // viewport heigth,
startPosition, // Line start position startPosition, // Line start position
endPosition, // Line end position endPosition, // Line end position
color // Line color color, // Line color
labelEnd,
labelStart,
labelEndWidth,
labelEndHeight,
labelStartWidth,
labelStartHeight
} = this.props; } = this.props;
if (labelStart == "" && labelEnd == "") {
// No more actions are required.
return;
}
const svgs = element.getElementsByTagName("svg");
let line;
let svg;
if (svgs.length > 0) {
svg = svgs.item(0);
if (svg != null) {
// Set SVG size.
const lines = svg.getElementsByTagNameNS(svgNS, "line");
let groups = svg.getElementsByTagNameNS(svgNS, "g");
while (groups.length > 0) {
groups[0].remove();
}
if (lines.length > 0) {
line = lines.item(0);
}
}
} else {
// No line or svg, no more actions are required.
return;
}
if (svg == null || line == null) {
// No more actionas are required.
return;
}
// Font size and text adjustments. // Font size and text adjustments.
const fontsize = 7.4; const fontsize = 7.4;
const adjustment = 50; 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 x1 = startPosition.x - x + lineWidth / 2 + viewportOffsetX / 2;
let y1 = startPosition.y - y + lineWidth / 2 + viewportOffsetY / 2; let y1 = startPosition.y - y + lineWidth / 2 + viewportOffsetY / 2;
let x2 = endPosition.x - x + lineWidth / 2 + viewportOffsetX / 2; let x2 = endPosition.x - x + lineWidth / 2 + viewportOffsetX / 2;
@ -132,10 +177,18 @@ export default class NetworkLink extends Line {
// Calculate effective 'text' box sizes. // Calculate effective 'text' box sizes.
const fontheight = 23; const fontheight = 23;
let labelStartWidth = this.labelStart.length * fontsize; if (labelStartWidth <= 0) {
let labelEndWidth = this.labelEnd.length * fontsize; labelStartWidth = labelStart.length * fontsize;
let labelStartHeight = fontheight; }
let labelEndHeight = fontheight; if (labelEndWidth <= 0) {
labelEndWidth = labelEnd.length * fontsize;
}
if (labelStartHeight <= 0) {
labelStartHeight = fontheight;
}
if (labelEndHeight <= 0) {
labelEndHeight = fontheight;
}
if (x1 < x2) { if (x1 < x2) {
// x1 on left of x2. // x1 on left of x2.
@ -165,86 +218,57 @@ export default class NetworkLink extends Line {
color = "#000"; color = "#000";
} }
// console.log(`to : ${x1},${y1} -------- ${x2}, ${y2}`); if (labelStart != "") {
// console.log(`inclinacion de ${g}`); 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})`);
const svgs = element.getElementsByTagName("svg"); 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);
if (svgs.length > 0) { let st = document.createElementNS(svgNS, "text");
const svg = svgs.item(0); st.setAttribute("x", `${x1 + fontsize}`);
st.setAttribute("y", `${y1 + (fontheight * 2) / 3}`);
st.setAttribute("fill", "#000");
st.textContent = labelStart;
st.setAttribute("transform", `rotate(${g} ${x1} ${y1})`);
start.append(st);
if (svg != null) { svg.append(start);
// Set SVG size. }
const lines = svg.getElementsByTagNameNS(svgNS, "line");
let groups = svg.getElementsByTagNameNS(svgNS, "g");
while (groups.length > 0) {
groups[0].remove();
}
if (lines.length > 0) { if (labelEnd != "") {
const line = lines.item(0); 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);
if (line != null) { let et = document.createElementNS(svgNS, "text");
// let rect = document.createElementNS( et.setAttribute("x", `${x2 + fontsize}`);
// "http://www.w3.org/2000/svg", et.setAttribute("y", `${y2 + (fontheight * 2) / 3}`);
// "rect" et.setAttribute("fill", "#000");
// ); et.textContent = labelEnd;
// rect.setAttribute("x", SVGRect.x); et.setAttribute("transform", `rotate(${g} ${x1} ${y1})`);
// rect.setAttribute("y", SVGRect.y); end.append(et);
// rect.setAttribute("width", SVGRect.width);
// rect.setAttribute("height", SVGRect.height);
// rect.setAttribute("fill", "yellow");
let start = document.createElementNS(svgNS, "g"); svg.append(end);
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);
}
}
}
} }
} }
} }