From 0cf8ad6908e889f210689d73988d92d42673ecee Mon Sep 17 00:00:00 2001 From: Massimo Ferraro Date: Wed, 7 Aug 2024 16:41:30 +0200 Subject: [PATCH 1/9] Update text nodes metadata when moving text nodes in network area diagram (#92) Signed-off-by: massimo.ferraro --- .../data/nad-eurostag-tutorial-example1.svg | 34 +++--- .../data/nad-four-substations.svg | 19 ++-- .../data/nad-ieee14cdf-solved.svg | 105 ++++++++++-------- .../data/nad-ieee300cdf-VL9006.svg | 102 +++++++++-------- .../data/nad-ieee9-zeroimpedance-cdf.svg | 55 ++++----- demo/src/diagram-viewers/data/nad-scada.svg | 37 +++--- .../diagram-utils.ts | 36 ++++-- .../network-area-diagram-viewer.ts | 53 ++++----- 8 files changed, 241 insertions(+), 200 deletions(-) diff --git a/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1.svg b/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1.svg index 7b6671e6..f999774b 100644 --- a/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1.svg +++ b/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1.svg @@ -10,19 +10,17 @@ .nad-hvdc-edge polyline.nad-hvdc {stroke: grey; stroke-width: 40} .nad-branch-edges .nad-tie-line-edge .nad-edge-path {stroke-width: 7} .nad-pst-arrow {stroke: #6a6a6a; stroke-width: 4; stroke-linecap: round; fill: none} -.nad-state-out .nad-arrow-in {visibility: hidden} -.nad-state-in .nad-arrow-out {visibility: hidden} -.nad-active path {stroke: none; fill: #546e7a} -.nad-reactive path {stroke: none; fill: #0277bd} -.nad-current path {stroke: none; fill: #bd4802} +path.nad-arrow-out:not(.nad-state-out .nad-arrow-out) {visibility: hidden} +path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} +.nad-active {fill: #546e7a} +.nad-reactive {fill: #0277bd} +.nad-current {fill: #bd4802} .nad-text-background {flood-color: #90a4aeaa} .nad-text-nodes {font: 25px serif; fill: black; dominant-baseline: central} .nad-text-nodes foreignObject {overflow: visible; color: black} .nad-label-box {background-color: #6c6c6c20; width: max-content; padding: 10px; border-radius: 10px;} .nad-legend-square {width: 20px; height: 20px; background: var(--nad-vl-color, black);} .nad-edge-infos text, .nad-edge-label text {font: 20px serif; dominant-baseline:middle; stroke: #FFFFFFAA; stroke-width: 10; stroke-linejoin:round; paint-order: stroke} -.nad-edge-infos .nad-state-in text {fill: #b71c1c} -.nad-edge-infos .nad-state-out text {fill: #2e7d32} .nad-disconnected {--nad-vl-color: #808080} .nad-vl0to30-line {--nad-vl-color: #afb42b} .nad-vl0to30-0 {--nad-vl-color: #827717} @@ -131,6 +129,12 @@ + + + + + + @@ -153,7 +157,7 @@ - + @@ -165,7 +169,7 @@ - + @@ -186,7 +190,7 @@ - + @@ -198,7 +202,7 @@ - + @@ -217,7 +221,7 @@ - + @@ -229,7 +233,7 @@ - + @@ -248,7 +252,7 @@ - + @@ -260,7 +264,7 @@ - + diff --git a/demo/src/diagram-viewers/data/nad-four-substations.svg b/demo/src/diagram-viewers/data/nad-four-substations.svg index 89afbb38..e4e65449 100644 --- a/demo/src/diagram-viewers/data/nad-four-substations.svg +++ b/demo/src/diagram-viewers/data/nad-four-substations.svg @@ -10,19 +10,17 @@ .nad-hvdc-edge polyline.nad-hvdc {stroke: grey; stroke-width: 40} .nad-branch-edges .nad-tie-line-edge .nad-edge-path {stroke-width: 7} .nad-pst-arrow {stroke: #6a6a6a; stroke-width: 4; stroke-linecap: round; fill: none} -.nad-state-out .nad-arrow-in {visibility: hidden} -.nad-state-in .nad-arrow-out {visibility: hidden} -.nad-active path {stroke: none; fill: #546e7a} -.nad-reactive path {stroke: none; fill: #0277bd} -.nad-current path {stroke: none; fill: #bd4802} +path.nad-arrow-out:not(.nad-state-out .nad-arrow-out) {visibility: hidden} +path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} +.nad-active {fill: #546e7a} +.nad-reactive {fill: #0277bd} +.nad-current {fill: #bd4802} .nad-text-background {flood-color: #90a4aeaa} .nad-text-nodes {font: 25px serif; fill: black; dominant-baseline: central} .nad-text-nodes foreignObject {overflow: visible; color: black} .nad-label-box {background-color: #6c6c6c20; width: max-content; padding: 10px; border-radius: 10px;} .nad-legend-square {width: 20px; height: 20px; background: var(--nad-vl-color, black);} .nad-edge-infos text, .nad-edge-label text {font: 20px serif; dominant-baseline:middle; stroke: #FFFFFFAA; stroke-width: 10; stroke-linejoin:round; paint-order: stroke} -.nad-edge-infos .nad-state-in text {fill: #b71c1c} -.nad-edge-infos .nad-state-out text {fill: #2e7d32} .nad-disconnected {--nad-vl-color: #808080} .nad-vl0to30-line {--nad-vl-color: #afb42b} .nad-vl0to30-0 {--nad-vl-color: #827717} @@ -134,6 +132,13 @@ + + + + + + + diff --git a/demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg b/demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg index 07b9c9ce..1ffd8450 100644 --- a/demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg +++ b/demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg @@ -10,19 +10,17 @@ .nad-hvdc-edge polyline.nad-hvdc {stroke: grey; stroke-width: 40} .nad-branch-edges .nad-tie-line-edge .nad-edge-path {stroke-width: 7} .nad-pst-arrow {stroke: #6a6a6a; stroke-width: 4; stroke-linecap: round; fill: none} -.nad-state-out .nad-arrow-in {visibility: hidden} -.nad-state-in .nad-arrow-out {visibility: hidden} -.nad-active path {stroke: none; fill: #546e7a} -.nad-reactive path {stroke: none; fill: #0277bd} -.nad-current path {stroke: none; fill: #bd4802} +path.nad-arrow-out:not(.nad-state-out .nad-arrow-out) {visibility: hidden} +path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} +.nad-active {fill: #546e7a} +.nad-reactive {fill: #0277bd} +.nad-current {fill: #bd4802} .nad-text-background {flood-color: #90a4aeaa} .nad-text-nodes {font: 25px serif; fill: black; dominant-baseline: central} .nad-text-nodes foreignObject {overflow: visible; color: black} .nad-label-box {background-color: #6c6c6c20; width: max-content; padding: 10px; border-radius: 10px;} .nad-legend-square {width: 20px; height: 20px; background: var(--nad-vl-color, black);} .nad-edge-infos text, .nad-edge-label text {font: 20px serif; dominant-baseline:middle; stroke: #FFFFFFAA; stroke-width: 10; stroke-linejoin:round; paint-order: stroke} -.nad-edge-infos .nad-state-in text {fill: #b71c1c} -.nad-edge-infos .nad-state-out text {fill: #2e7d32} .nad-disconnected {--nad-vl-color: #808080} .nad-vl0to30-line {--nad-vl-color: #afb42b} .nad-vl0to30-0 {--nad-vl-color: #827717} @@ -164,6 +162,19 @@ + + + + + + + + + + + + + @@ -210,7 +221,7 @@ - + @@ -222,7 +233,7 @@ - + @@ -236,7 +247,7 @@ - + @@ -248,7 +259,7 @@ - + @@ -262,7 +273,7 @@ - + @@ -274,7 +285,7 @@ - + @@ -288,7 +299,7 @@ - + @@ -300,7 +311,7 @@ - + @@ -314,7 +325,7 @@ - + @@ -326,7 +337,7 @@ - + @@ -340,7 +351,7 @@ - + @@ -352,7 +363,7 @@ - + @@ -366,7 +377,7 @@ - + @@ -378,7 +389,7 @@ - + @@ -392,7 +403,7 @@ - + @@ -404,7 +415,7 @@ - + @@ -418,7 +429,7 @@ - + @@ -430,7 +441,7 @@ - + @@ -444,7 +455,7 @@ - + @@ -456,7 +467,7 @@ - + @@ -470,7 +481,7 @@ - + @@ -482,7 +493,7 @@ - + @@ -496,7 +507,7 @@ - + @@ -508,7 +519,7 @@ - + @@ -522,7 +533,7 @@ - + @@ -534,7 +545,7 @@ - + @@ -548,7 +559,7 @@ - + @@ -560,7 +571,7 @@ - + @@ -574,7 +585,7 @@ - + @@ -586,7 +597,7 @@ - + @@ -600,7 +611,7 @@ - + @@ -612,7 +623,7 @@ - + @@ -626,7 +637,7 @@ - + @@ -638,7 +649,7 @@ - + @@ -652,7 +663,7 @@ - + @@ -664,7 +675,7 @@ - + @@ -682,7 +693,7 @@ - + @@ -694,7 +705,7 @@ - + @@ -712,7 +723,7 @@ - + @@ -724,7 +735,7 @@ - + diff --git a/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg b/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg index 822c685e..ed9c314e 100644 --- a/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg +++ b/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg @@ -10,19 +10,17 @@ .nad-hvdc-edge polyline.nad-hvdc {stroke: grey; stroke-width: 40} .nad-branch-edges .nad-tie-line-edge .nad-edge-path {stroke-width: 7} .nad-pst-arrow {stroke: #6a6a6a; stroke-width: 4; stroke-linecap: round; fill: none} -.nad-state-out .nad-arrow-in {visibility: hidden} -.nad-state-in .nad-arrow-out {visibility: hidden} -.nad-active path {stroke: none; fill: #546e7a} -.nad-reactive path {stroke: none; fill: #0277bd} -.nad-current path {stroke: none; fill: #bd4802} +path.nad-arrow-out:not(.nad-state-out .nad-arrow-out) {visibility: hidden} +path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} +.nad-active {fill: #546e7a} +.nad-reactive {fill: #0277bd} +.nad-current {fill: #bd4802} .nad-text-background {flood-color: #90a4aeaa} .nad-text-nodes {font: 25px serif; fill: black; dominant-baseline: central} .nad-text-nodes foreignObject {overflow: visible; color: black} .nad-label-box {background-color: #6c6c6c20; width: max-content; padding: 10px; border-radius: 10px;} .nad-legend-square {width: 20px; height: 20px; background: var(--nad-vl-color, black);} .nad-edge-infos text, .nad-edge-label text {font: 20px serif; dominant-baseline:middle; stroke: #FFFFFFAA; stroke-width: 10; stroke-linejoin:round; paint-order: stroke} -.nad-edge-infos .nad-state-in text {fill: #b71c1c} -.nad-edge-infos .nad-state-out text {fill: #2e7d32} .nad-disconnected {--nad-vl-color: #808080} .nad-vl0to30-line {--nad-vl-color: #afb42b} .nad-vl0to30-0 {--nad-vl-color: #827717} @@ -200,6 +198,14 @@ + + + + + + + + @@ -230,7 +236,7 @@ - + @@ -244,7 +250,7 @@ - + @@ -258,7 +264,7 @@ - + @@ -272,7 +278,7 @@ - + @@ -286,7 +292,7 @@ - + @@ -300,7 +306,7 @@ - + @@ -314,7 +320,7 @@ - + @@ -328,7 +334,7 @@ - + @@ -342,7 +348,7 @@ - + @@ -354,7 +360,7 @@ - + @@ -372,7 +378,7 @@ - + @@ -384,7 +390,7 @@ - + @@ -402,7 +408,7 @@ - + @@ -414,7 +420,7 @@ - + @@ -432,7 +438,7 @@ - + @@ -444,7 +450,7 @@ - + @@ -458,7 +464,7 @@ - + @@ -470,7 +476,7 @@ - + @@ -484,7 +490,7 @@ - + @@ -498,7 +504,7 @@ - + @@ -517,7 +523,7 @@ - + @@ -529,7 +535,7 @@ - + @@ -543,7 +549,7 @@ - + @@ -555,7 +561,7 @@ - + @@ -569,7 +575,7 @@ - + @@ -581,7 +587,7 @@ - + @@ -595,7 +601,7 @@ - + @@ -609,7 +615,7 @@ - + @@ -628,7 +634,7 @@ - + @@ -647,7 +653,7 @@ - + @@ -666,7 +672,7 @@ - + @@ -685,7 +691,7 @@ - + @@ -704,7 +710,7 @@ - + @@ -723,7 +729,7 @@ - + @@ -742,7 +748,7 @@ - + @@ -761,7 +767,7 @@ - + @@ -773,7 +779,7 @@ - + @@ -787,7 +793,7 @@ - + @@ -799,7 +805,7 @@ - + @@ -813,7 +819,7 @@ - + @@ -832,7 +838,7 @@ - + diff --git a/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg b/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg index 13fe0b99..03a3e4a9 100644 --- a/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg +++ b/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg @@ -10,19 +10,17 @@ .nad-hvdc-edge polyline.nad-hvdc {stroke: grey; stroke-width: 40} .nad-branch-edges .nad-tie-line-edge .nad-edge-path {stroke-width: 7} .nad-pst-arrow {stroke: #6a6a6a; stroke-width: 4; stroke-linecap: round; fill: none} -.nad-state-out .nad-arrow-in {visibility: hidden} -.nad-state-in .nad-arrow-out {visibility: hidden} -.nad-active path {stroke: none; fill: #546e7a} -.nad-reactive path {stroke: none; fill: #0277bd} -.nad-current path {stroke: none; fill: #bd4802} +path.nad-arrow-out:not(.nad-state-out .nad-arrow-out) {visibility: hidden} +path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} +.nad-active {fill: #546e7a} +.nad-reactive {fill: #0277bd} +.nad-current {fill: #bd4802} .nad-text-background {flood-color: #90a4aeaa} .nad-text-nodes {font: 25px serif; fill: black; dominant-baseline: central} .nad-text-nodes foreignObject {overflow: visible; color: black} .nad-label-box {background-color: #6c6c6c20; width: max-content; padding: 10px; border-radius: 10px;} .nad-legend-square {width: 20px; height: 20px; background: var(--nad-vl-color, black);} .nad-edge-infos text, .nad-edge-label text {font: 20px serif; dominant-baseline:middle; stroke: #FFFFFFAA; stroke-width: 10; stroke-linejoin:round; paint-order: stroke} -.nad-edge-infos .nad-state-in text {fill: #b71c1c} -.nad-edge-infos .nad-state-out text {fill: #2e7d32} .nad-disconnected {--nad-vl-color: #808080} .nad-vl0to30-line {--nad-vl-color: #afb42b} .nad-vl0to30-0 {--nad-vl-color: #827717} @@ -142,6 +140,13 @@ + + + + + + + @@ -171,7 +176,7 @@ - + @@ -183,7 +188,7 @@ - + @@ -197,7 +202,7 @@ - + @@ -209,7 +214,7 @@ - + @@ -223,7 +228,7 @@ - + @@ -235,7 +240,7 @@ - + @@ -253,7 +258,7 @@ - + @@ -265,7 +270,7 @@ - + @@ -279,7 +284,7 @@ - + @@ -291,7 +296,7 @@ - + @@ -305,7 +310,7 @@ - + @@ -317,7 +322,7 @@ - + @@ -331,7 +336,7 @@ - + @@ -343,7 +348,7 @@ - + @@ -361,7 +366,7 @@ - + @@ -373,7 +378,7 @@ - + @@ -387,7 +392,7 @@ - + @@ -399,7 +404,7 @@ - + diff --git a/demo/src/diagram-viewers/data/nad-scada.svg b/demo/src/diagram-viewers/data/nad-scada.svg index 73368f24..113c0271 100644 --- a/demo/src/diagram-viewers/data/nad-scada.svg +++ b/demo/src/diagram-viewers/data/nad-scada.svg @@ -10,19 +10,17 @@ .nad-hvdc-edge polyline.nad-hvdc {stroke: grey; stroke-width: 40} .nad-branch-edges .nad-tie-line-edge .nad-edge-path {stroke-width: 7} .nad-pst-arrow {stroke: #6a6a6a; stroke-width: 4; stroke-linecap: round; fill: none} -.nad-state-out .nad-arrow-in {visibility: hidden} -.nad-state-in .nad-arrow-out {visibility: hidden} -.nad-active path {stroke: none; fill: #546e7a} -.nad-reactive path {stroke: none; fill: #0277bd} -.nad-current path {stroke: none; fill: #bd4802} +path.nad-arrow-out:not(.nad-state-out .nad-arrow-out) {visibility: hidden} +path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} +.nad-active {fill: #546e7a} +.nad-reactive {fill: #0277bd} +.nad-current {fill: #bd4802} .nad-text-background {flood-color: #90a4aeaa} .nad-text-nodes {font: 25px serif; fill: black; dominant-baseline: central} .nad-text-nodes foreignObject {overflow: visible; color: black} .nad-label-box {background-color: #6c6c6c20; width: max-content; padding: 10px; border-radius: 10px;} .nad-legend-square {width: 20px; height: 20px; background: var(--nad-vl-color, black);} .nad-edge-infos text, .nad-edge-label text {font: 20px serif; dominant-baseline:middle; stroke: #FFFFFFAA; stroke-width: 10; stroke-linejoin:round; paint-order: stroke} -.nad-edge-infos .nad-state-in text {fill: #b71c1c} -.nad-edge-infos .nad-state-out text {fill: #2e7d32} .nad-disconnected {--nad-vl-color: #808080} .nad-vl0to30-line {--nad-vl-color: #afb42b} .nad-vl0to30-0 {--nad-vl-color: #827717} @@ -134,6 +132,11 @@ + + + + + @@ -156,7 +159,7 @@ - + @@ -168,7 +171,7 @@ - + @@ -187,7 +190,7 @@ - + @@ -199,7 +202,7 @@ - + @@ -221,7 +224,7 @@ - + @@ -238,7 +241,7 @@ - + @@ -250,7 +253,7 @@ - + @@ -271,7 +274,7 @@ - + @@ -283,7 +286,7 @@ - + @@ -295,7 +298,7 @@ - + diff --git a/src/components/network-area-diagram-viewer/diagram-utils.ts b/src/components/network-area-diagram-viewer/diagram-utils.ts index 7bbf8627..0d7dca40 100644 --- a/src/components/network-area-diagram-viewer/diagram-utils.ts +++ b/src/components/network-area-diagram-viewer/diagram-utils.ts @@ -440,7 +440,7 @@ export function getTextNodeAngleFromCentre(textNode: SVGGraphicsElement | null, } // get the position of a translated text box -export function getTextNodeTranslatedPosition(textNode: SVGGraphicsElement | null, translation: Point) { +export function getTextNodeTranslatedPosition(textNode: SVGGraphicsElement | null, translation: Point): Point { const textNodeX = textNode?.getAttribute('x') ?? '0'; const textNodeY = textNode?.getAttribute('y') ?? '0'; return new Point(+textNodeX + translation.x, +textNodeY + translation.y); @@ -453,17 +453,6 @@ export function getTextNodePosition(textNode: SVGGraphicsElement | null): Point return new Point(+textNodeX, +textNodeY); } -// get text node move (original and new shift of position) -export function getTextNodeMove(initialTextPosition: Point, textPosition: Point, vlNode: SVGGraphicsElement): NODEMOVE { - const xNode = vlNode.getAttribute('x') ?? '0'; - const yNode = vlNode.getAttribute('y') ?? '0'; - const xOrig = getFormattedValue(initialTextPosition.x - +xNode); - const yOrig = getFormattedValue(initialTextPosition.y - +yNode); - const xNew = getFormattedValue(textPosition.x - +xNode); - const yNew = getFormattedValue(textPosition.y - +yNode); - return { xOrig: xOrig, yOrig: yOrig, xNew: xNew, yNew: yNew }; -} - // get node move (original and new position) export function getNodeMove(node: SVGGraphicsElement, nodePosition: Point): NODEMOVE { const xOrig = node.getAttribute('x') ?? '0'; @@ -472,3 +461,26 @@ export function getNodeMove(node: SVGGraphicsElement, nodePosition: Point): NODE const yNew = getFormattedValue(nodePosition.y); return { xOrig: xOrig, yOrig: yOrig, xNew: xNew, yNew: yNew }; } + +// get moves (original and new position) of position and connetion of text node +export function getTextNodeMoves( + textNode: SVGGraphicsElement, + vlNode: SVGGraphicsElement, + textPosition: Point, + connectionPosition: Point +): [NODEMOVE, NODEMOVE] { + const xNode = vlNode.getAttribute('x') ?? '0'; + const yNode = vlNode.getAttribute('y') ?? '0'; + const xOrig = textNode.getAttribute('shiftx') ?? '0'; + const yOrig = textNode.getAttribute('shifty') ?? '0'; + const xNew = getFormattedValue(textPosition.x - +xNode); + const yNew = getFormattedValue(textPosition.y - +yNode); + const connXOrig = textNode.getAttribute('connectionshiftx') ?? '0'; + const connYOrig = textNode.getAttribute('connectionshifty') ?? '0'; + const connXNew = getFormattedValue(connectionPosition.x - +xNode); + const connYNew = getFormattedValue(connectionPosition.y - +yNode); + return [ + { xOrig: xOrig, yOrig: yOrig, xNew: xNew, yNew: yNew }, + { xOrig: connXOrig, yOrig: connYOrig, xNew: connXNew, yNew: connYNew }, + ]; +} diff --git a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts index 91e50c1d..01fd8df9 100644 --- a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts +++ b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts @@ -54,8 +54,6 @@ export class NetworkAreaDiagramViewer { svgParameters: SvgParameters; edgeAngles: Map = new Map(); textNodeSelected: boolean = false; - initialTextNodePosition: Point = new Point(0, 0); - initialEndTextEdge: Point = new Point(0, 0); endTextEdge: Point = new Point(0, 0); onMoveNodeCallback: OnMoveNodeCallbackType | null; onMoveTextNodeCallback: OnMoveTextNodeCallbackType | null; @@ -285,7 +283,6 @@ export class NetworkAreaDiagramViewer { // check if I'm moving a text node if (DiagramUtils.isTextNode(this.selectedElement)) { this.textNodeSelected = true; - this.initialTextNodePosition = DiagramUtils.getTextNodePosition(this.selectedElement); } } else { // selecting node @@ -313,14 +310,12 @@ export class NetworkAreaDiagramViewer { const mousePosition = this.getMousePosition(event as MouseEvent); this.updateGraph(mousePosition); if (this.textNodeSelected) { - this.callMoveTextNodeCallback(mousePosition); + this.updateTextNodeMetadataCallCallback(mousePosition); } else { this.updateNodeMetadataCallCallback(mousePosition); } this.initialPosition = new Point(0, 0); this.textNodeSelected = false; - this.initialTextNodePosition = new Point(0, 0); - this.initialEndTextEdge = new Point(0, 0); this.endTextEdge = new Point(0, 0); } else { // selecting node @@ -333,6 +328,9 @@ export class NetworkAreaDiagramViewer { svg.style.removeProperty('cursor'); } this.selectedElement = null; + this.initialPosition = new Point(0, 0); + this.textNodeSelected = false; + this.endTextEdge = new Point(0, 0); this.enablePanzoom(); } } @@ -440,12 +438,6 @@ export class NetworkAreaDiagramViewer { this.endTextEdge, voltageLevelCircleRadius ); - if (this.initialEndTextEdge.x == 0 && this.initialEndTextEdge.y == 0) { - const points = DiagramUtils.getPolylinePoints(textEdge as unknown as HTMLElement); - if (points != null) { - this.initialEndTextEdge = points[points.length - 1]; - } - } // update text edge polyline const polyline = DiagramUtils.getFormattedPolyline(startTextEdge, null, this.endTextEdge); textEdge.setAttribute('points', polyline); @@ -1153,34 +1145,37 @@ export class NetworkAreaDiagramViewer { } } - private callMoveTextNodeCallback(mousePosition: Point) { + private updateTextNodeMetadataCallCallback(mousePosition: Point) { if (this.onMoveTextNodeCallback != null) { // get from metadata node connected to moved text node const node: SVGGraphicsElement | null = this.container.querySelector( 'nad\\:node[svgid="' + DiagramUtils.getVoltageLevelNodeId(this.selectedElement?.id) + '"]' ); - if (node != null) { + const textNode: SVGGraphicsElement | null = this.container.querySelector( + 'nad\\:textnode[svgid="' + this.selectedElement?.id + '"]' + ); + if (node != null && textNode != null) { // get new text node position const textPosition = DiagramUtils.getTextNodeAngleFromCentre(this.selectedElement, mousePosition); - const textNodeMove = DiagramUtils.getTextNodeMove(this.initialTextNodePosition, textPosition, node); - const textConnectionMove = DiagramUtils.getTextNodeMove( - this.initialEndTextEdge, - this.endTextEdge, - node - ); + const textNodeMoves = DiagramUtils.getTextNodeMoves(textNode, node, textPosition, this.endTextEdge); + // update text node position in metadata + textNode.setAttribute('shiftx', textNodeMoves[0].xNew); + textNode.setAttribute('shifty', textNodeMoves[0].yNew); + textNode.setAttribute('connectionshiftx', textNodeMoves[1].xNew); + textNode.setAttribute('connectionshifty', textNodeMoves[1].yNew); // call the node move callback, if defined this.onMoveTextNodeCallback( node.getAttribute('equipmentid') ?? '', node.getAttribute('svgid') ?? '', - this.selectedElement?.id ?? '', - +textNodeMove.xNew, - +textNodeMove.yNew, - +textNodeMove.xOrig, - +textNodeMove.yOrig, - +textConnectionMove.xNew, - +textConnectionMove.yNew, - +textConnectionMove.xOrig, - +textConnectionMove.yOrig + textNode.getAttribute('svgid') ?? '', + +textNodeMoves[0].xNew, + +textNodeMoves[0].yNew, + +textNodeMoves[0].xOrig, + +textNodeMoves[0].yOrig, + +textNodeMoves[1].xNew, + +textNodeMoves[1].yNew, + +textNodeMoves[1].xOrig, + +textNodeMoves[1].yOrig ); } } From 5f528a5a4f1307e60ff24d614afcce176eebcd9b Mon Sep 17 00:00:00 2001 From: Massimo Ferraro Date: Wed, 7 Aug 2024 16:46:04 +0200 Subject: [PATCH 2/9] Do not read SVG parameter from metadata in network area diagram (#93) Signed-off-by: massimo.ferraro --- .../data/nad-eurostag-tutorial-example1.svg | 2 +- demo/src/diagram-viewers/data/nad-four-substations.svg | 2 +- demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg | 2 +- demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg | 2 +- .../diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg | 2 +- demo/src/diagram-viewers/data/nad-scada.svg | 2 +- .../network-area-diagram-viewer/svg-parameters.ts | 8 +++----- 7 files changed, 9 insertions(+), 11 deletions(-) diff --git a/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1.svg b/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1.svg index f999774b..d5e3a7bc 100644 --- a/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1.svg +++ b/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1.svg @@ -135,7 +135,7 @@ path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} - + diff --git a/demo/src/diagram-viewers/data/nad-four-substations.svg b/demo/src/diagram-viewers/data/nad-four-substations.svg index e4e65449..3a539bd0 100644 --- a/demo/src/diagram-viewers/data/nad-four-substations.svg +++ b/demo/src/diagram-viewers/data/nad-four-substations.svg @@ -139,7 +139,7 @@ path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} - + diff --git a/demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg b/demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg index 1ffd8450..4ff176cf 100644 --- a/demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg +++ b/demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg @@ -175,7 +175,7 @@ path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} - + diff --git a/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg b/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg index ed9c314e..c54bac34 100644 --- a/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg +++ b/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg @@ -206,7 +206,7 @@ path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} - + diff --git a/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg b/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg index 03a3e4a9..64116416 100644 --- a/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg +++ b/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg @@ -147,7 +147,7 @@ path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} - + diff --git a/demo/src/diagram-viewers/data/nad-scada.svg b/demo/src/diagram-viewers/data/nad-scada.svg index 113c0271..e0adcd63 100644 --- a/demo/src/diagram-viewers/data/nad-scada.svg +++ b/demo/src/diagram-viewers/data/nad-scada.svg @@ -137,7 +137,7 @@ path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} - + diff --git a/src/components/network-area-diagram-viewer/svg-parameters.ts b/src/components/network-area-diagram-viewer/svg-parameters.ts index 8422e391..9c0de691 100644 --- a/src/components/network-area-diagram-viewer/svg-parameters.ts +++ b/src/components/network-area-diagram-viewer/svg-parameters.ts @@ -101,11 +101,9 @@ export class SvgParameters { SvgParameters.EDGE_NAME_DISPLAYED_PARAMETER_NAME, SvgParameters.EDGE_NAME_DISPLAYED_DEFAULT ); - this.detailedTextNodeYShift = this.getNumberParameter( - svgParametersElement, - SvgParameters.DETAILED_TEXT_NODE_Y_SHIFT_PARAMETER_NAME, - SvgParameters.DETAILED_TEXT_NODE_Y_SHIFT_DEFAULT - ); + // parameter moved from svg parameters to layout parameters + // value hardcoded, waiting for the layout parameter in metadata + this.detailedTextNodeYShift = SvgParameters.DETAILED_TEXT_NODE_Y_SHIFT_DEFAULT; } private getNumberParameter( From 770f55684eaeb35edff5bd4ff4f23847e58b8499 Mon Sep 17 00:00:00 2001 From: Massimo Ferraro Date: Wed, 7 Aug 2024 17:07:57 +0200 Subject: [PATCH 3/9] Read layout parameters from metadata in network area diagram viewer (#95) Signed-off-by: massimo.ferraro --- .../data/nad-eurostag-tutorial-example1.svg | 3 +- .../data/nad-four-substations.svg | 3 +- .../data/nad-ieee14cdf-solved.svg | 3 +- .../data/nad-ieee300cdf-VL9006.svg | 1 + .../data/nad-ieee9-zeroimpedance-cdf.svg | 3 +- demo/src/diagram-viewers/data/nad-scada.svg | 3 +- .../diagram-utils.ts | 20 +++++++ .../layout-parameters.ts | 28 ++++++++++ .../network-area-diagram-viewer.ts | 11 +++- .../svg-parameters.ts | 52 +++++-------------- 10 files changed, 82 insertions(+), 45 deletions(-) create mode 100644 src/components/network-area-diagram-viewer/layout-parameters.ts diff --git a/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1.svg b/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1.svg index d5e3a7bc..852f4c08 100644 --- a/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1.svg +++ b/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1.svg @@ -1,5 +1,5 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1_metadata.json b/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1_metadata.json new file mode 100644 index 00000000..db2ee45b --- /dev/null +++ b/demo/src/diagram-viewers/data/nad-eurostag-tutorial-example1_metadata.json @@ -0,0 +1,170 @@ +{ + "layoutParameters" : { + "textNodesForceLayout" : false, + "springRepulsionFactorForceLayout" : 0.0, + "textNodeFixedShift" : { + "x" : 100.0, + "y" : -40.0 + }, + "maxSteps" : 1000, + "textNodeEdgeConnectionYShift" : 25.0 + }, + "svgParameters" : { + "diagramPadding" : { + "left" : 200.0, + "top" : 200.0, + "right" : 200.0, + "bottom" : 200.0 + }, + "insertNameDesc" : false, + "svgWidthAndHeightAdded" : false, + "cssLocation" : "INSERTED_IN_SVG", + "sizeConstraint" : "FIXED_SCALE", + "fixedWidth" : -1, + "fixedHeight" : -1, + "fixedScale" : 0.2, + "arrowShift" : 30.0, + "arrowLabelShift" : 19.0, + "converterStationWidth" : 70.0, + "voltageLevelCircleRadius" : 30.0, + "fictitiousVoltageLevelCircleRadius" : 15.0, + "transformerCircleRadius" : 20.0, + "nodeHollowWidth" : 15.0, + "edgesForkLength" : 80.0, + "edgesForkAperture" : 60.0, + "edgeStartShift" : 0.0, + "unknownBusNodeExtraRadius" : 10.0, + "loopDistance" : 120.0, + "loopEdgesAperture" : 60.0, + "loopControlDistance" : 40.0, + "edgeInfoAlongEdge" : true, + "edgeNameDisplayed" : true, + "interAnnulusSpace" : 5.0, + "svgPrefix" : "", + "idDisplayed" : false, + "substationDescriptionDisplayed" : false, + "arrowHeight" : 10.0, + "busLegend" : true, + "voltageLevelDetails" : false, + "languageTag" : "en", + "voltageValuePrecision" : 1, + "powerValuePrecision" : 0, + "angleValuePrecision" : 1, + "currentValuePrecision" : 0, + "edgeInfoDisplayed" : "ACTIVE_POWER", + "pstArrowHeadSize" : 8.0, + "undefinedValueSymbol" : "" + }, + "busNodes" : [ { + "svgId" : "1", + "equipmentId" : "VLGEN_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "0" + }, { + "svgId" : "3", + "equipmentId" : "VLHV1_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "2" + }, { + "svgId" : "5", + "equipmentId" : "VLHV2_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "4" + }, { + "svgId" : "7", + "equipmentId" : "VLLOAD_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "6" + } ], + "nodes" : [ { + "svgId" : "0", + "equipmentId" : "VLGEN", + "x" : -452.59, + "y" : -274.01 + }, { + "svgId" : "2", + "equipmentId" : "VLHV1", + "x" : -245.26, + "y" : 34.3 + }, { + "svgId" : "4", + "equipmentId" : "VLHV2", + "x" : 140.33, + "y" : 58.61 + }, { + "svgId" : "6", + "equipmentId" : "VLLOAD", + "x" : 430.9, + "y" : -174.05 + } ], + "edges" : [ { + "svgId" : "8", + "equipmentId" : "NGEN_NHV1", + "node1" : "0", + "node2" : "2", + "busNode1" : "1", + "busNode2" : "3", + "type" : "TwoWtEdge" + }, { + "svgId" : "9", + "equipmentId" : "NHV1_NHV2_1", + "node1" : "2", + "node2" : "4", + "busNode1" : "3", + "busNode2" : "5", + "type" : "LineEdge" + }, { + "svgId" : "10", + "equipmentId" : "NHV1_NHV2_2", + "node1" : "2", + "node2" : "4", + "busNode1" : "3", + "busNode2" : "5", + "type" : "LineEdge" + }, { + "svgId" : "11", + "equipmentId" : "NHV2_NLOAD", + "node1" : "4", + "node2" : "6", + "busNode1" : "5", + "busNode2" : "7", + "type" : "TwoWtEdge" + } ], + "textNodes" : [ { + "svgId" : "0-textnode", + "equipmentId" : "VLGEN", + "vlNode" : "0", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "2-textnode", + "equipmentId" : "VLHV1", + "vlNode" : "2", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "4-textnode", + "equipmentId" : "VLHV2", + "vlNode" : "4", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "6-textnode", + "equipmentId" : "VLLOAD", + "vlNode" : "6", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + } ] +} diff --git a/demo/src/diagram-viewers/data/nad-four-substations.svg b/demo/src/diagram-viewers/data/nad-four-substations.svg index c8d7b583..fb82ec4f 100644 --- a/demo/src/diagram-viewers/data/nad-four-substations.svg +++ b/demo/src/diagram-viewers/data/nad-four-substations.svg @@ -109,40 +109,6 @@ path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} 40% {stroke: #00BCD4; stroke-width: 15} } ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demo/src/diagram-viewers/data/nad-four-substations_metadata.json b/demo/src/diagram-viewers/data/nad-four-substations_metadata.json new file mode 100644 index 00000000..e12e45c9 --- /dev/null +++ b/demo/src/diagram-viewers/data/nad-four-substations_metadata.json @@ -0,0 +1,197 @@ +{ + "layoutParameters" : { + "textNodesForceLayout" : false, + "springRepulsionFactorForceLayout" : 0.0, + "textNodeFixedShift" : { + "x" : 100.0, + "y" : -40.0 + }, + "maxSteps" : 1000, + "textNodeEdgeConnectionYShift" : 25.0 + }, + "svgParameters" : { + "diagramPadding" : { + "left" : 200.0, + "top" : 200.0, + "right" : 200.0, + "bottom" : 200.0 + }, + "insertNameDesc" : false, + "svgWidthAndHeightAdded" : false, + "cssLocation" : "INSERTED_IN_SVG", + "sizeConstraint" : "FIXED_SCALE", + "fixedWidth" : -1, + "fixedHeight" : -1, + "fixedScale" : 0.2, + "arrowShift" : 30.0, + "arrowLabelShift" : 19.0, + "converterStationWidth" : 70.0, + "voltageLevelCircleRadius" : 30.0, + "fictitiousVoltageLevelCircleRadius" : 15.0, + "transformerCircleRadius" : 20.0, + "nodeHollowWidth" : 15.0, + "edgesForkLength" : 80.0, + "edgesForkAperture" : 60.0, + "edgeStartShift" : 0.0, + "unknownBusNodeExtraRadius" : 10.0, + "loopDistance" : 120.0, + "loopEdgesAperture" : 60.0, + "loopControlDistance" : 40.0, + "edgeInfoAlongEdge" : true, + "edgeNameDisplayed" : false, + "interAnnulusSpace" : 5.0, + "svgPrefix" : "", + "idDisplayed" : false, + "substationDescriptionDisplayed" : false, + "arrowHeight" : 10.0, + "busLegend" : true, + "voltageLevelDetails" : false, + "languageTag" : "en", + "voltageValuePrecision" : 1, + "powerValuePrecision" : 0, + "angleValuePrecision" : 1, + "currentValuePrecision" : 0, + "edgeInfoDisplayed" : "ACTIVE_POWER", + "pstArrowHeadSize" : 8.0, + "undefinedValueSymbol" : "" + }, + "busNodes" : [ { + "svgId" : "1", + "equipmentId" : "S1VL1_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "0" + }, { + "svgId" : "3", + "equipmentId" : "S1VL2_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "2" + }, { + "svgId" : "5", + "equipmentId" : "S2VL1_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "4" + }, { + "svgId" : "7", + "equipmentId" : "S3VL1_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "6" + }, { + "svgId" : "9", + "equipmentId" : "S4VL1_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "8" + } ], + "nodes" : [ { + "svgId" : "0", + "equipmentId" : "S1VL1", + "x" : -220.4, + "y" : -515.14 + }, { + "svgId" : "2", + "equipmentId" : "S1VL2", + "x" : -152.34, + "y" : -133.8 + }, { + "svgId" : "4", + "equipmentId" : "S2VL1", + "x" : -162.93, + "y" : 231.51 + }, { + "svgId" : "6", + "equipmentId" : "S3VL1", + "x" : 171.13, + "y" : 91.69 + }, { + "svgId" : "8", + "equipmentId" : "S4VL1", + "x" : 497.34, + "y" : 302.31 + } ], + "edges" : [ { + "svgId" : "10", + "equipmentId" : "TWT", + "node1" : "0", + "node2" : "2", + "busNode1" : "1", + "busNode2" : "3", + "type" : "PstEdge" + }, { + "svgId" : "11", + "equipmentId" : "HVDC1", + "node1" : "2", + "node2" : "4", + "busNode1" : "3", + "busNode2" : "5", + "type" : "HvdcLineEdge" + }, { + "svgId" : "12", + "equipmentId" : "HVDC2", + "node1" : "2", + "node2" : "6", + "busNode1" : "3", + "busNode2" : "7", + "type" : "HvdcLineEdge" + }, { + "svgId" : "13", + "equipmentId" : "LINE_S2S3", + "node1" : "4", + "node2" : "6", + "busNode1" : "5", + "busNode2" : "7", + "type" : "LineEdge" + }, { + "svgId" : "14", + "equipmentId" : "LINE_S3S4", + "node1" : "6", + "node2" : "8", + "busNode1" : "7", + "busNode2" : "9", + "type" : "LineEdge" + } ], + "textNodes" : [ { + "svgId" : "0-textnode", + "equipmentId" : "S1VL1", + "vlNode" : "0", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "2-textnode", + "equipmentId" : "S1VL2", + "vlNode" : "2", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "4-textnode", + "equipmentId" : "S2VL1", + "vlNode" : "4", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "6-textnode", + "equipmentId" : "S3VL1", + "vlNode" : "6", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "8-textnode", + "equipmentId" : "S4VL1", + "vlNode" : "8", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + } ] +} diff --git a/demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg b/demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg index 41a964fc..dc731adb 100644 --- a/demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg +++ b/demo/src/diagram-viewers/data/nad-ieee14cdf-solved.svg @@ -109,76 +109,6 @@ path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} 40% {stroke: #00BCD4; stroke-width: 15} } ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demo/src/diagram-viewers/data/nad-ieee14cdf-solved_metadata.json b/demo/src/diagram-viewers/data/nad-ieee14cdf-solved_metadata.json new file mode 100644 index 00000000..1c35fabb --- /dev/null +++ b/demo/src/diagram-viewers/data/nad-ieee14cdf-solved_metadata.json @@ -0,0 +1,449 @@ +{ + "layoutParameters" : { + "textNodesForceLayout" : false, + "springRepulsionFactorForceLayout" : 0.0, + "textNodeFixedShift" : { + "x" : 100.0, + "y" : -40.0 + }, + "maxSteps" : 1000, + "textNodeEdgeConnectionYShift" : 25.0 + }, + "svgParameters" : { + "diagramPadding" : { + "left" : 200.0, + "top" : 200.0, + "right" : 200.0, + "bottom" : 200.0 + }, + "insertNameDesc" : false, + "svgWidthAndHeightAdded" : false, + "cssLocation" : "INSERTED_IN_SVG", + "sizeConstraint" : "FIXED_SCALE", + "fixedWidth" : -1, + "fixedHeight" : -1, + "fixedScale" : 0.2, + "arrowShift" : 30.0, + "arrowLabelShift" : 19.0, + "converterStationWidth" : 70.0, + "voltageLevelCircleRadius" : 30.0, + "fictitiousVoltageLevelCircleRadius" : 15.0, + "transformerCircleRadius" : 20.0, + "nodeHollowWidth" : 15.0, + "edgesForkLength" : 80.0, + "edgesForkAperture" : 60.0, + "edgeStartShift" : 0.0, + "unknownBusNodeExtraRadius" : 10.0, + "loopDistance" : 120.0, + "loopEdgesAperture" : 60.0, + "loopControlDistance" : 40.0, + "edgeInfoAlongEdge" : true, + "edgeNameDisplayed" : false, + "interAnnulusSpace" : 5.0, + "svgPrefix" : "", + "idDisplayed" : false, + "substationDescriptionDisplayed" : false, + "arrowHeight" : 10.0, + "busLegend" : true, + "voltageLevelDetails" : false, + "languageTag" : "en", + "voltageValuePrecision" : 1, + "powerValuePrecision" : 0, + "angleValuePrecision" : 1, + "currentValuePrecision" : 0, + "edgeInfoDisplayed" : "ACTIVE_POWER", + "pstArrowHeadSize" : 8.0, + "undefinedValueSymbol" : "" + }, + "busNodes" : [ { + "svgId" : "1", + "equipmentId" : "VL1_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "0" + }, { + "svgId" : "3", + "equipmentId" : "VL10_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "2" + }, { + "svgId" : "5", + "equipmentId" : "VL11_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "4" + }, { + "svgId" : "7", + "equipmentId" : "VL12_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "6" + }, { + "svgId" : "9", + "equipmentId" : "VL13_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "8" + }, { + "svgId" : "11", + "equipmentId" : "VL14_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "10" + }, { + "svgId" : "13", + "equipmentId" : "VL2_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "12" + }, { + "svgId" : "15", + "equipmentId" : "VL3_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "14" + }, { + "svgId" : "18", + "equipmentId" : "VL4_1", + "nbNeighbours" : 2, + "index" : 0, + "vlNode" : "16" + }, { + "svgId" : "19", + "equipmentId" : "VL4_2", + "nbNeighbours" : 2, + "index" : 1, + "vlNode" : "16" + }, { + "svgId" : "17", + "equipmentId" : "VL4_0", + "nbNeighbours" : 2, + "index" : 2, + "vlNode" : "16" + }, { + "svgId" : "21", + "equipmentId" : "VL5_0", + "nbNeighbours" : 1, + "index" : 0, + "vlNode" : "20" + }, { + "svgId" : "22", + "equipmentId" : "VL5_1", + "nbNeighbours" : 1, + "index" : 1, + "vlNode" : "20" + }, { + "svgId" : "24", + "equipmentId" : "VL8_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "23" + } ], + "nodes" : [ { + "svgId" : "0", + "equipmentId" : "VL1", + "x" : 182.16, + "y" : -669.23 + }, { + "svgId" : "2", + "equipmentId" : "VL10", + "x" : -573.57, + "y" : 100.52 + }, { + "svgId" : "4", + "equipmentId" : "VL11", + "x" : -295.68, + "y" : 308.31 + }, { + "svgId" : "6", + "equipmentId" : "VL12", + "x" : 694.18, + "y" : 76.12 + }, { + "svgId" : "8", + "equipmentId" : "VL13", + "x" : 468.4, + "y" : 333.92 + }, { + "svgId" : "10", + "equipmentId" : "VL14", + "x" : 112.11, + "y" : 419.24 + }, { + "svgId" : "12", + "equipmentId" : "VL2", + "x" : 62.4, + "y" : -384.58 + }, { + "svgId" : "14", + "equipmentId" : "VL3", + "x" : 379.01, + "y" : -360.27 + }, { + "svgId" : "16", + "equipmentId" : "VL4", + "x" : -140.21, + "y" : -108.15 + }, { + "svgId" : "20", + "equipmentId" : "VL5", + "x" : 202.16, + "y" : -30.06 + }, { + "svgId" : "23", + "equipmentId" : "VL8", + "x" : -520.85, + "y" : -451.48 + } ], + "edges" : [ { + "svgId" : "25", + "equipmentId" : "L1-2-1", + "node1" : "0", + "node2" : "12", + "busNode1" : "1", + "busNode2" : "13", + "type" : "LineEdge" + }, { + "svgId" : "26", + "equipmentId" : "L1-5-1", + "node1" : "0", + "node2" : "20", + "busNode1" : "1", + "busNode2" : "21", + "type" : "LineEdge" + }, { + "svgId" : "27", + "equipmentId" : "L9-10-1", + "node1" : "16", + "node2" : "2", + "busNode1" : "19", + "busNode2" : "3", + "type" : "LineEdge" + }, { + "svgId" : "28", + "equipmentId" : "L10-11-1", + "node1" : "2", + "node2" : "4", + "busNode1" : "3", + "busNode2" : "5", + "type" : "LineEdge" + }, { + "svgId" : "29", + "equipmentId" : "L6-11-1", + "node1" : "20", + "node2" : "4", + "busNode1" : "22", + "busNode2" : "5", + "type" : "LineEdge" + }, { + "svgId" : "30", + "equipmentId" : "L6-12-1", + "node1" : "20", + "node2" : "6", + "busNode1" : "22", + "busNode2" : "7", + "type" : "LineEdge" + }, { + "svgId" : "31", + "equipmentId" : "L12-13-1", + "node1" : "6", + "node2" : "8", + "busNode1" : "7", + "busNode2" : "9", + "type" : "LineEdge" + }, { + "svgId" : "32", + "equipmentId" : "L6-13-1", + "node1" : "20", + "node2" : "8", + "busNode1" : "22", + "busNode2" : "9", + "type" : "LineEdge" + }, { + "svgId" : "33", + "equipmentId" : "L13-14-1", + "node1" : "8", + "node2" : "10", + "busNode1" : "9", + "busNode2" : "11", + "type" : "LineEdge" + }, { + "svgId" : "34", + "equipmentId" : "L9-14-1", + "node1" : "16", + "node2" : "10", + "busNode1" : "19", + "busNode2" : "11", + "type" : "LineEdge" + }, { + "svgId" : "35", + "equipmentId" : "L2-3-1", + "node1" : "12", + "node2" : "14", + "busNode1" : "13", + "busNode2" : "15", + "type" : "LineEdge" + }, { + "svgId" : "36", + "equipmentId" : "L2-4-1", + "node1" : "12", + "node2" : "16", + "busNode1" : "13", + "busNode2" : "17", + "type" : "LineEdge" + }, { + "svgId" : "37", + "equipmentId" : "L2-5-1", + "node1" : "12", + "node2" : "20", + "busNode1" : "13", + "busNode2" : "21", + "type" : "LineEdge" + }, { + "svgId" : "38", + "equipmentId" : "L3-4-1", + "node1" : "14", + "node2" : "16", + "busNode1" : "15", + "busNode2" : "17", + "type" : "LineEdge" + }, { + "svgId" : "39", + "equipmentId" : "L4-5-1", + "node1" : "16", + "node2" : "20", + "busNode1" : "17", + "busNode2" : "21", + "type" : "LineEdge" + }, { + "svgId" : "40", + "equipmentId" : "L7-8-1", + "node1" : "16", + "node2" : "23", + "busNode1" : "18", + "busNode2" : "24", + "type" : "LineEdge" + }, { + "svgId" : "41", + "equipmentId" : "L7-9-1", + "node1" : "16", + "node2" : "16", + "busNode1" : "18", + "busNode2" : "19", + "type" : "LineEdge" + }, { + "svgId" : "42", + "equipmentId" : "T4-7-1", + "node1" : "16", + "node2" : "16", + "busNode1" : "17", + "busNode2" : "18", + "type" : "TwoWtEdge" + }, { + "svgId" : "43", + "equipmentId" : "T4-9-1", + "node1" : "16", + "node2" : "16", + "busNode1" : "17", + "busNode2" : "19", + "type" : "TwoWtEdge" + }, { + "svgId" : "44", + "equipmentId" : "T5-6-1", + "node1" : "20", + "node2" : "20", + "busNode1" : "21", + "busNode2" : "22", + "type" : "TwoWtEdge" + } ], + "textNodes" : [ { + "svgId" : "0-textnode", + "equipmentId" : "VL1", + "vlNode" : "0", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "2-textnode", + "equipmentId" : "VL10", + "vlNode" : "2", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "4-textnode", + "equipmentId" : "VL11", + "vlNode" : "4", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "6-textnode", + "equipmentId" : "VL12", + "vlNode" : "6", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "8-textnode", + "equipmentId" : "VL13", + "vlNode" : "8", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "10-textnode", + "equipmentId" : "VL14", + "vlNode" : "10", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "12-textnode", + "equipmentId" : "VL2", + "vlNode" : "12", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "14-textnode", + "equipmentId" : "VL3", + "vlNode" : "14", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "16-textnode", + "equipmentId" : "VL4", + "vlNode" : "16", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "20-textnode", + "equipmentId" : "VL5", + "vlNode" : "20", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "23-textnode", + "equipmentId" : "VL8", + "vlNode" : "23", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + } ] +} diff --git a/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg b/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg index 0626c24f..ec126bd8 100644 --- a/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg +++ b/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006.svg @@ -109,107 +109,6 @@ path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} 40% {stroke: #00BCD4; stroke-width: 15} } ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006_metadata.json b/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006_metadata.json new file mode 100644 index 00000000..30b59c06 --- /dev/null +++ b/demo/src/diagram-viewers/data/nad-ieee300cdf-VL9006_metadata.json @@ -0,0 +1,638 @@ +{ + "layoutParameters" : { + "textNodesForceLayout" : false, + "springRepulsionFactorForceLayout" : 0.0, + "textNodeFixedShift" : { + "x" : 100.0, + "y" : -40.0 + }, + "maxSteps" : 1000, + "textNodeEdgeConnectionYShift" : 25.0 + }, + "svgParameters" : { + "diagramPadding" : { + "left" : 200.0, + "top" : 200.0, + "right" : 200.0, + "bottom" : 200.0 + }, + "insertNameDesc" : false, + "svgWidthAndHeightAdded" : false, + "cssLocation" : "INSERTED_IN_SVG", + "sizeConstraint" : "FIXED_SCALE", + "fixedWidth" : -1, + "fixedHeight" : -1, + "fixedScale" : 0.2, + "arrowShift" : 30.0, + "arrowLabelShift" : 19.0, + "converterStationWidth" : 70.0, + "voltageLevelCircleRadius" : 30.0, + "fictitiousVoltageLevelCircleRadius" : 15.0, + "transformerCircleRadius" : 20.0, + "nodeHollowWidth" : 15.0, + "edgesForkLength" : 80.0, + "edgesForkAperture" : 60.0, + "edgeStartShift" : 0.0, + "unknownBusNodeExtraRadius" : 10.0, + "loopDistance" : 120.0, + "loopEdgesAperture" : 60.0, + "loopControlDistance" : 40.0, + "edgeInfoAlongEdge" : true, + "edgeNameDisplayed" : false, + "interAnnulusSpace" : 5.0, + "svgPrefix" : "", + "idDisplayed" : false, + "substationDescriptionDisplayed" : false, + "arrowHeight" : 10.0, + "busLegend" : true, + "voltageLevelDetails" : false, + "languageTag" : "en", + "voltageValuePrecision" : 1, + "powerValuePrecision" : 0, + "angleValuePrecision" : 1, + "currentValuePrecision" : 0, + "edgeInfoDisplayed" : "ACTIVE_POWER", + "pstArrowHeadSize" : 8.0, + "undefinedValueSymbol" : "" + }, + "busNodes" : [ { + "svgId" : "2", + "equipmentId" : "VL37_1", + "nbNeighbours" : 1, + "index" : 0, + "vlNode" : "0" + }, { + "svgId" : "1", + "equipmentId" : "VL37_0", + "nbNeighbours" : 1, + "index" : 1, + "vlNode" : "0" + }, { + "svgId" : "4", + "equipmentId" : "VL9002_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "3" + }, { + "svgId" : "6", + "equipmentId" : "VL9003_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "5" + }, { + "svgId" : "8", + "equipmentId" : "VL9006_0", + "nbNeighbours" : 1, + "index" : 0, + "vlNode" : "7" + }, { + "svgId" : "9", + "equipmentId" : "VL9006_1", + "nbNeighbours" : 1, + "index" : 1, + "vlNode" : "7" + }, { + "svgId" : "11", + "equipmentId" : "VL9007_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "10" + }, { + "svgId" : "13", + "equipmentId" : "VL9121_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "12" + }, { + "svgId" : "16", + "equipmentId" : "VL15_1", + "nbNeighbours" : 1, + "index" : 0, + "vlNode" : "14" + }, { + "svgId" : "15", + "equipmentId" : "VL15_0", + "nbNeighbours" : 1, + "index" : 1, + "vlNode" : "14" + }, { + "svgId" : "18", + "equipmentId" : "VL38_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "17" + }, { + "svgId" : "20", + "equipmentId" : "VL40_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "19" + }, { + "svgId" : "22", + "equipmentId" : "VL41_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "21" + }, { + "svgId" : "24", + "equipmentId" : "VL49_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "23" + }, { + "svgId" : "26", + "equipmentId" : "VL89_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "25" + }, { + "svgId" : "28", + "equipmentId" : "VL90_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "27" + }, { + "svgId" : "30", + "equipmentId" : "VL9005_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "29" + }, { + "svgId" : "32", + "equipmentId" : "VL9021_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "31" + }, { + "svgId" : "34", + "equipmentId" : "VL9024_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "33" + }, { + "svgId" : "36", + "equipmentId" : "VL9031_0", + "nbNeighbours" : 6, + "index" : 0, + "vlNode" : "35" + }, { + "svgId" : "37", + "equipmentId" : "VL9031_1", + "nbNeighbours" : 6, + "index" : 1, + "vlNode" : "35" + }, { + "svgId" : "38", + "equipmentId" : "VL9031_2", + "nbNeighbours" : 6, + "index" : 2, + "vlNode" : "35" + }, { + "svgId" : "39", + "equipmentId" : "VL9031_3", + "nbNeighbours" : 6, + "index" : 3, + "vlNode" : "35" + }, { + "svgId" : "40", + "equipmentId" : "VL9031_4", + "nbNeighbours" : 6, + "index" : 4, + "vlNode" : "35" + }, { + "svgId" : "41", + "equipmentId" : "VL9031_5", + "nbNeighbours" : 6, + "index" : 5, + "vlNode" : "35" + }, { + "svgId" : "42", + "equipmentId" : "VL9031_6", + "nbNeighbours" : 6, + "index" : 6, + "vlNode" : "35" + }, { + "svgId" : "44", + "equipmentId" : "VL9036_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "43" + }, { + "svgId" : "46", + "equipmentId" : "VL9044_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "45" + }, { + "svgId" : "48", + "equipmentId" : "VL9071_0", + "nbNeighbours" : 1, + "index" : 0, + "vlNode" : "47" + }, { + "svgId" : "49", + "equipmentId" : "VL9071_1", + "nbNeighbours" : 1, + "index" : 1, + "vlNode" : "47" + } ], + "nodes" : [ { + "svgId" : "0", + "equipmentId" : "VL37", + "x" : 640.93, + "y" : -338.93 + }, { + "svgId" : "3", + "equipmentId" : "VL9002", + "x" : -234.64, + "y" : 877.48 + }, { + "svgId" : "5", + "equipmentId" : "VL9003", + "x" : -694.48, + "y" : -222.95 + }, { + "svgId" : "7", + "equipmentId" : "VL9006", + "x" : -181.31, + "y" : 169.17 + }, { + "svgId" : "10", + "equipmentId" : "VL9007", + "x" : -665.51, + "y" : 200.12 + }, { + "svgId" : "12", + "equipmentId" : "VL9121", + "x" : 32.67, + "y" : 479.2 + }, { + "svgId" : "14", + "equipmentId" : "VL15", + "x" : 1174.06, + "y" : -237.85 + }, { + "svgId" : "17", + "equipmentId" : "VL38", + "x" : 1172.11, + "y" : -655.15 + }, { + "svgId" : "19", + "equipmentId" : "VL40", + "x" : 650.79, + "y" : -994.74 + }, { + "svgId" : "21", + "equipmentId" : "VL41", + "x" : 262.66, + "y" : -288.42 + }, { + "svgId" : "23", + "equipmentId" : "VL49", + "x" : 290.91, + "y" : -733.98 + }, { + "svgId" : "25", + "equipmentId" : "VL89", + "x" : 588.59, + "y" : 109.54 + }, { + "svgId" : "27", + "equipmentId" : "VL90", + "x" : 983.96, + "y" : 103.34 + }, { + "svgId" : "29", + "equipmentId" : "VL9005", + "x" : 800.81, + "y" : -657.26 + }, { + "svgId" : "31", + "equipmentId" : "VL9021", + "x" : 19.76, + "y" : 1247.29 + }, { + "svgId" : "33", + "equipmentId" : "VL9024", + "x" : -529.95, + "y" : 1193.31 + }, { + "svgId" : "35", + "equipmentId" : "VL9031", + "x" : -956.12, + "y" : -644.58 + }, { + "svgId" : "43", + "equipmentId" : "VL9036", + "x" : -510.41, + "y" : -604.32 + }, { + "svgId" : "45", + "equipmentId" : "VL9044", + "x" : -1158.33, + "y" : -213.76 + }, { + "svgId" : "47", + "equipmentId" : "VL9071", + "x" : -1026.69, + "y" : 455.81 + } ], + "edges" : [ { + "svgId" : "50", + "equipmentId" : "L15-37-1", + "node1" : "14", + "node2" : "0", + "busNode1" : "15", + "busNode2" : "1", + "type" : "LineEdge" + }, { + "svgId" : "51", + "equipmentId" : "L37-38-1", + "node1" : "0", + "node2" : "17", + "busNode1" : "1", + "busNode2" : "18", + "type" : "LineEdge" + }, { + "svgId" : "52", + "equipmentId" : "L37-40-1", + "node1" : "0", + "node2" : "19", + "busNode1" : "1", + "busNode2" : "20", + "type" : "LineEdge" + }, { + "svgId" : "53", + "equipmentId" : "L37-41-1", + "node1" : "0", + "node2" : "21", + "busNode1" : "1", + "busNode2" : "22", + "type" : "LineEdge" + }, { + "svgId" : "54", + "equipmentId" : "L37-49-1", + "node1" : "0", + "node2" : "23", + "busNode1" : "1", + "busNode2" : "24", + "type" : "LineEdge" + }, { + "svgId" : "55", + "equipmentId" : "L37-89-1", + "node1" : "0", + "node2" : "25", + "busNode1" : "1", + "busNode2" : "26", + "type" : "LineEdge" + }, { + "svgId" : "56", + "equipmentId" : "L37-90-1", + "node1" : "0", + "node2" : "27", + "busNode1" : "1", + "busNode2" : "28", + "type" : "LineEdge" + }, { + "svgId" : "57", + "equipmentId" : "L9001-9005-1", + "node1" : "0", + "node2" : "29", + "busNode1" : "2", + "busNode2" : "30", + "type" : "LineEdge" + }, { + "svgId" : "58", + "equipmentId" : "T37-9001-1", + "node1" : "0", + "node2" : "0", + "busNode1" : "1", + "busNode2" : "2", + "type" : "TwoWtEdge" + }, { + "svgId" : "59", + "equipmentId" : "T9001-9006-1", + "node1" : "0", + "node2" : "7", + "busNode1" : "2", + "busNode2" : "8", + "type" : "TwoWtEdge" + }, { + "svgId" : "60", + "equipmentId" : "T9001-9012-1", + "node1" : "0", + "node2" : "7", + "busNode1" : "2", + "busNode2" : "9", + "type" : "TwoWtEdge" + }, { + "svgId" : "61", + "equipmentId" : "L9012-9002-1", + "node1" : "7", + "node2" : "3", + "busNode1" : "9", + "busNode2" : "4", + "type" : "LineEdge" + }, { + "svgId" : "62", + "equipmentId" : "L9012-9002-2", + "node1" : "7", + "node2" : "3", + "busNode1" : "9", + "busNode2" : "4", + "type" : "LineEdge" + }, { + "svgId" : "63", + "equipmentId" : "L9002-9021-1", + "node1" : "3", + "node2" : "31", + "busNode1" : "4", + "busNode2" : "32", + "type" : "LineEdge" + }, { + "svgId" : "64", + "equipmentId" : "T9002-9024-1", + "node1" : "3", + "node2" : "33", + "busNode1" : "4", + "busNode2" : "34", + "type" : "TwoWtEdge" + }, { + "svgId" : "65", + "equipmentId" : "L9006-9003-1", + "node1" : "7", + "node2" : "5", + "busNode1" : "8", + "busNode2" : "6", + "type" : "LineEdge" + }, { + "svgId" : "66", + "equipmentId" : "L9006-9003-2", + "node1" : "7", + "node2" : "5", + "busNode1" : "8", + "busNode2" : "6", + "type" : "LineEdge" + }, { + "svgId" : "67", + "equipmentId" : "L9007-9003-1", + "node1" : "10", + "node2" : "5", + "busNode1" : "11", + "busNode2" : "6", + "type" : "LineEdge" + }, { + "svgId" : "68", + "equipmentId" : "L9003-9044-1", + "node1" : "5", + "node2" : "45", + "busNode1" : "6", + "busNode2" : "46", + "type" : "LineEdge" + }, { + "svgId" : "69", + "equipmentId" : "T9003-9031-1", + "node1" : "5", + "node2" : "35", + "busNode1" : "6", + "busNode2" : "36", + "type" : "TwoWtEdge" + }, { + "svgId" : "70", + "equipmentId" : "T9003-9032-1", + "node1" : "5", + "node2" : "35", + "busNode1" : "6", + "busNode2" : "37", + "type" : "TwoWtEdge" + }, { + "svgId" : "71", + "equipmentId" : "T9003-9033-1", + "node1" : "5", + "node2" : "35", + "busNode1" : "6", + "busNode2" : "38", + "type" : "TwoWtEdge" + }, { + "svgId" : "72", + "equipmentId" : "T9003-9034-1", + "node1" : "5", + "node2" : "35", + "busNode1" : "6", + "busNode2" : "39", + "type" : "TwoWtEdge" + }, { + "svgId" : "73", + "equipmentId" : "T9003-9035-1", + "node1" : "5", + "node2" : "35", + "busNode1" : "6", + "busNode2" : "40", + "type" : "TwoWtEdge" + }, { + "svgId" : "74", + "equipmentId" : "T9003-9036-1", + "node1" : "5", + "node2" : "43", + "busNode1" : "6", + "busNode2" : "44", + "type" : "TwoWtEdge" + }, { + "svgId" : "75", + "equipmentId" : "T9003-9037-1", + "node1" : "5", + "node2" : "35", + "busNode1" : "6", + "busNode2" : "41", + "type" : "TwoWtEdge" + }, { + "svgId" : "76", + "equipmentId" : "T9003-9038-1", + "node1" : "5", + "node2" : "35", + "busNode1" : "6", + "busNode2" : "42", + "type" : "TwoWtEdge" + }, { + "svgId" : "77", + "equipmentId" : "L9006-9007-1", + "node1" : "7", + "node2" : "10", + "busNode1" : "8", + "busNode2" : "11", + "type" : "LineEdge" + }, { + "svgId" : "78", + "equipmentId" : "L9012-9121-1", + "node1" : "7", + "node2" : "12", + "busNode1" : "9", + "busNode2" : "13", + "type" : "LineEdge" + }, { + "svgId" : "79", + "equipmentId" : "T9007-9071-1", + "node1" : "10", + "node2" : "47", + "busNode1" : "11", + "busNode2" : "48", + "type" : "TwoWtEdge" + }, { + "svgId" : "80", + "equipmentId" : "T9007-9072-1", + "node1" : "10", + "node2" : "47", + "busNode1" : "11", + "busNode2" : "49", + "type" : "TwoWtEdge" + } ], + "textNodes" : [ { + "svgId" : "0-textnode", + "equipmentId" : "VL37", + "vlNode" : "0", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "3-textnode", + "equipmentId" : "VL9002", + "vlNode" : "3", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "5-textnode", + "equipmentId" : "VL9003", + "vlNode" : "5", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "7-textnode", + "equipmentId" : "VL9006", + "vlNode" : "7", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "10-textnode", + "equipmentId" : "VL9007", + "vlNode" : "10", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "12-textnode", + "equipmentId" : "VL9121", + "vlNode" : "12", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + } ] +} diff --git a/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg b/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg index df4f2b6e..a1ba9533 100644 --- a/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg +++ b/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf.svg @@ -109,48 +109,6 @@ path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} 40% {stroke: #00BCD4; stroke-width: 15} } ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf_metadata.json b/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf_metadata.json new file mode 100644 index 00000000..1cf31344 --- /dev/null +++ b/demo/src/diagram-viewers/data/nad-ieee9-zeroimpedance-cdf_metadata.json @@ -0,0 +1,253 @@ +{ + "layoutParameters" : { + "textNodesForceLayout" : false, + "springRepulsionFactorForceLayout" : 0.0, + "textNodeFixedShift" : { + "x" : 100.0, + "y" : -40.0 + }, + "maxSteps" : 1000, + "textNodeEdgeConnectionYShift" : 25.0 + }, + "svgParameters" : { + "diagramPadding" : { + "left" : 200.0, + "top" : 200.0, + "right" : 200.0, + "bottom" : 200.0 + }, + "insertNameDesc" : false, + "svgWidthAndHeightAdded" : false, + "cssLocation" : "INSERTED_IN_SVG", + "sizeConstraint" : "FIXED_SCALE", + "fixedWidth" : -1, + "fixedHeight" : -1, + "fixedScale" : 0.2, + "arrowShift" : 30.0, + "arrowLabelShift" : 19.0, + "converterStationWidth" : 70.0, + "voltageLevelCircleRadius" : 30.0, + "fictitiousVoltageLevelCircleRadius" : 15.0, + "transformerCircleRadius" : 20.0, + "nodeHollowWidth" : 15.0, + "edgesForkLength" : 80.0, + "edgesForkAperture" : 60.0, + "edgeStartShift" : 0.0, + "unknownBusNodeExtraRadius" : 10.0, + "loopDistance" : 120.0, + "loopEdgesAperture" : 60.0, + "loopControlDistance" : 40.0, + "edgeInfoAlongEdge" : true, + "edgeNameDisplayed" : false, + "interAnnulusSpace" : 5.0, + "svgPrefix" : "", + "idDisplayed" : false, + "substationDescriptionDisplayed" : false, + "arrowHeight" : 10.0, + "busLegend" : true, + "voltageLevelDetails" : false, + "languageTag" : "en", + "voltageValuePrecision" : 1, + "powerValuePrecision" : 0, + "angleValuePrecision" : 1, + "currentValuePrecision" : 0, + "edgeInfoDisplayed" : "ACTIVE_POWER", + "pstArrowHeadSize" : 8.0, + "undefinedValueSymbol" : "" + }, + "busNodes" : [ { + "svgId" : "1", + "equipmentId" : "VL1_0", + "nbNeighbours" : 1, + "index" : 0, + "vlNode" : "0" + }, { + "svgId" : "2", + "equipmentId" : "VL1_1", + "nbNeighbours" : 1, + "index" : 1, + "vlNode" : "0" + }, { + "svgId" : "4", + "equipmentId" : "VL2_0", + "nbNeighbours" : 2, + "index" : 0, + "vlNode" : "3" + }, { + "svgId" : "6", + "equipmentId" : "VL2_2", + "nbNeighbours" : 2, + "index" : 1, + "vlNode" : "3" + }, { + "svgId" : "5", + "equipmentId" : "VL2_1", + "nbNeighbours" : 2, + "index" : 2, + "vlNode" : "3" + }, { + "svgId" : "8", + "equipmentId" : "VL3_0", + "nbNeighbours" : 1, + "index" : 0, + "vlNode" : "7" + }, { + "svgId" : "9", + "equipmentId" : "VL3_1", + "nbNeighbours" : 1, + "index" : 1, + "vlNode" : "7" + }, { + "svgId" : "11", + "equipmentId" : "VL5_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "10" + }, { + "svgId" : "13", + "equipmentId" : "VL6_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "12" + } ], + "nodes" : [ { + "svgId" : "0", + "equipmentId" : "VL1", + "x" : 313.79, + "y" : -123.09 + }, { + "svgId" : "3", + "equipmentId" : "VL2", + "x" : -283.06, + "y" : -90.04 + }, { + "svgId" : "7", + "equipmentId" : "VL3", + "x" : -145.81, + "y" : 290.39 + }, { + "svgId" : "10", + "equipmentId" : "VL5", + "x" : 10.63, + "y" : -371.47 + }, { + "svgId" : "12", + "equipmentId" : "VL6", + "x" : 247.51, + "y" : 268.96 + } ], + "edges" : [ { + "svgId" : "14", + "equipmentId" : "L5-4-0", + "node1" : "10", + "node2" : "0", + "busNode1" : "11", + "busNode2" : "2", + "type" : "LineEdge" + }, { + "svgId" : "15", + "equipmentId" : "L6-4-0", + "node1" : "12", + "node2" : "0", + "busNode1" : "13", + "busNode2" : "2", + "type" : "LineEdge" + }, { + "svgId" : "16", + "equipmentId" : "T4-1-0", + "node1" : "0", + "node2" : "0", + "busNode1" : "2", + "busNode2" : "1", + "type" : "TwoWtEdge" + }, { + "svgId" : "17", + "equipmentId" : "L7-8-0", + "node1" : "3", + "node2" : "3", + "busNode1" : "5", + "busNode2" : "6", + "type" : "LineEdge" + }, { + "svgId" : "18", + "equipmentId" : "L7-5-0", + "node1" : "3", + "node2" : "10", + "busNode1" : "5", + "busNode2" : "11", + "type" : "LineEdge" + }, { + "svgId" : "19", + "equipmentId" : "L9-8-0", + "node1" : "7", + "node2" : "3", + "busNode1" : "9", + "busNode2" : "6", + "type" : "LineEdge" + }, { + "svgId" : "20", + "equipmentId" : "T7-2-0", + "node1" : "3", + "node2" : "3", + "busNode1" : "5", + "busNode2" : "4", + "type" : "TwoWtEdge" + }, { + "svgId" : "21", + "equipmentId" : "L9-6-0", + "node1" : "7", + "node2" : "12", + "busNode1" : "9", + "busNode2" : "13", + "type" : "LineEdge" + }, { + "svgId" : "22", + "equipmentId" : "T9-3-0", + "node1" : "7", + "node2" : "7", + "busNode1" : "9", + "busNode2" : "8", + "type" : "TwoWtEdge" + } ], + "textNodes" : [ { + "svgId" : "0-textnode", + "equipmentId" : "VL1", + "vlNode" : "0", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "3-textnode", + "equipmentId" : "VL2", + "vlNode" : "3", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "7-textnode", + "equipmentId" : "VL3", + "vlNode" : "7", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "10-textnode", + "equipmentId" : "VL5", + "vlNode" : "10", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "12-textnode", + "equipmentId" : "VL6", + "vlNode" : "12", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + } ] +} diff --git a/demo/src/diagram-viewers/data/nad-scada.svg b/demo/src/diagram-viewers/data/nad-scada.svg index 959f6ef0..e201526b 100644 --- a/demo/src/diagram-viewers/data/nad-scada.svg +++ b/demo/src/diagram-viewers/data/nad-scada.svg @@ -109,38 +109,6 @@ path.nad-arrow-in:not(.nad-state-in .nad-arrow-in) {visibility: hidden} 40% {stroke: #00BCD4; stroke-width: 15} } ]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demo/src/diagram-viewers/data/nad-scada_metadata.json b/demo/src/diagram-viewers/data/nad-scada_metadata.json new file mode 100644 index 00000000..e1c508ff --- /dev/null +++ b/demo/src/diagram-viewers/data/nad-scada_metadata.json @@ -0,0 +1,185 @@ +{ + "layoutParameters" : { + "textNodesForceLayout" : false, + "springRepulsionFactorForceLayout" : 0.0, + "textNodeFixedShift" : { + "x" : 100.0, + "y" : -40.0 + }, + "maxSteps" : 1000, + "textNodeEdgeConnectionYShift" : 25.0 + }, + "svgParameters" : { + "diagramPadding" : { + "left" : 200.0, + "top" : 200.0, + "right" : 200.0, + "bottom" : 200.0 + }, + "insertNameDesc" : false, + "svgWidthAndHeightAdded" : false, + "cssLocation" : "INSERTED_IN_SVG", + "sizeConstraint" : "FIXED_SCALE", + "fixedWidth" : -1, + "fixedHeight" : -1, + "fixedScale" : 0.2, + "arrowShift" : 30.0, + "arrowLabelShift" : 19.0, + "converterStationWidth" : 70.0, + "voltageLevelCircleRadius" : 30.0, + "fictitiousVoltageLevelCircleRadius" : 15.0, + "transformerCircleRadius" : 20.0, + "nodeHollowWidth" : 15.0, + "edgesForkLength" : 80.0, + "edgesForkAperture" : 60.0, + "edgeStartShift" : 0.0, + "unknownBusNodeExtraRadius" : 10.0, + "loopDistance" : 120.0, + "loopEdgesAperture" : 60.0, + "loopControlDistance" : 40.0, + "edgeInfoAlongEdge" : true, + "edgeNameDisplayed" : true, + "interAnnulusSpace" : 5.0, + "svgPrefix" : "", + "idDisplayed" : false, + "substationDescriptionDisplayed" : false, + "arrowHeight" : 10.0, + "busLegend" : true, + "voltageLevelDetails" : false, + "languageTag" : "en", + "voltageValuePrecision" : 1, + "powerValuePrecision" : 0, + "angleValuePrecision" : 1, + "currentValuePrecision" : 0, + "edgeInfoDisplayed" : "ACTIVE_POWER", + "pstArrowHeadSize" : 8.0, + "undefinedValueSymbol" : "" + }, + "busNodes" : [ { + "svgId" : "1", + "equipmentId" : "vl_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "0" + }, { + "svgId" : "3", + "equipmentId" : "vl2_0", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "2" + }, { + "svgId" : "12", + "equipmentId" : "dl", + "nbNeighbours" : 0, + "index" : 0, + "vlNode" : "11" + } ], + "nodes" : [ { + "svgId" : "0", + "equipmentId" : "vl", + "x" : 189.53, + "y" : 123.47 + }, { + "svgId" : "2", + "equipmentId" : "vl2", + "x" : -171.8, + "y" : 131.88 + }, { + "svgId" : "4", + "equipmentId" : "vl3", + "x" : -312.98, + "y" : -477.87 + }, { + "svgId" : "7", + "equipmentId" : "t3wt", + "x" : -39.15, + "y" : -202.32 + }, { + "svgId" : "11", + "equipmentId" : "dl", + "x" : 459.36, + "y" : 402.78 + } ], + "edges" : [ { + "svgId" : "5", + "equipmentId" : "line", + "node1" : "0", + "node2" : "2", + "busNode1" : "1", + "busNode2" : "3", + "type" : "LineEdge" + }, { + "svgId" : "6", + "equipmentId" : "tw2t", + "node1" : "0", + "node2" : "2", + "busNode1" : "1", + "busNode2" : "3", + "type" : "PstEdge" + }, { + "svgId" : "13", + "equipmentId" : "dl", + "node1" : "0", + "node2" : "11", + "busNode1" : "1", + "busNode2" : "12", + "type" : "DanglingLineEdge" + }, { + "svgId" : "14", + "equipmentId" : "hvdcline", + "node1" : "0", + "node2" : "2", + "busNode1" : "1", + "busNode2" : "3", + "type" : "HvdcLineEdge" + }, { + "svgId" : "8", + "equipmentId" : "t3wt", + "node1" : "0", + "node2" : "7", + "busNode1" : "1", + "busNode2" : "7", + "type" : "ThreeWtEdge" + }, { + "svgId" : "9", + "equipmentId" : "t3wt", + "node1" : "2", + "node2" : "7", + "busNode1" : "3", + "busNode2" : "7", + "type" : "ThreeWtEdge" + }, { + "svgId" : "10", + "equipmentId" : "t3wt", + "node1" : "4", + "node2" : "7", + "busNode1" : "", + "busNode2" : "7", + "type" : "ThreeWtEdge" + } ], + "textNodes" : [ { + "svgId" : "0-textnode", + "equipmentId" : "vl", + "vlNode" : "0", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "2-textnode", + "equipmentId" : "vl2", + "vlNode" : "2", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + }, { + "svgId" : "4-textnode", + "equipmentId" : "vl3", + "vlNode" : "4", + "shiftX" : 100.0, + "shiftY" : -40.0, + "connectionShiftX" : 100.0, + "connectionShiftY" : -15.0 + } ] +} diff --git a/src/components/network-area-diagram-viewer/diagram-metadata.ts b/src/components/network-area-diagram-viewer/diagram-metadata.ts new file mode 100644 index 00000000..1725af08 --- /dev/null +++ b/src/components/network-area-diagram-viewer/diagram-metadata.ts @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2024, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ + +export interface DiagramMetadata { + layoutParameters: LayoutParametersMetadata; + svgParameters: SvgParametersMetadata; + busNodes: BusNodeMetadata[]; + nodes: NodeMetadata[]; + edges: EdgeMetadata[]; + textNodes: TextNodeMetadata[]; +} + +export interface LayoutParametersMetadata { + textNodeEdgeConnectionYShift: number; +} + +export interface SvgParametersMetadata { + voltageLevelCircleRadius: number; + interAnnulusSpace: number; + transformerCircleRadius: number; + edgesForkAperture: number; + edgesForkLength: number; + arrowShift: number; + arrowLabelShift: number; + converterStationWidth: number; + nodeHollowWidth: number; + unknownBusNodeExtraRadius: number; + edgeNameDisplayed: boolean; +} + +export interface BusNodeMetadata { + svgId: string; + equipmentId: string; + nbNeighbours: number; + index: number; + vlNode: string; +} + +export interface NodeMetadata { + svgId: string; + equipmentId: string; + x: number; + y: number; +} + +export interface EdgeMetadata { + svgId: string; + equipmentId: string; + node1: string; + node2: string; + busNode1: string; + busNode2: string; + type: string; +} + +export interface TextNodeMetadata { + svgId: string; + equipmentId: string; + vlNode: string; + shiftX: number; + shiftY: number; + connectionShiftX: number; + connectionShiftY: number; +} diff --git a/src/components/network-area-diagram-viewer/diagram-utils.ts b/src/components/network-area-diagram-viewer/diagram-utils.ts index 5a420e78..950c8280 100644 --- a/src/components/network-area-diagram-viewer/diagram-utils.ts +++ b/src/components/network-area-diagram-viewer/diagram-utils.ts @@ -6,13 +6,14 @@ */ import { Point } from '@svgdotjs/svg.js'; +import { EdgeMetadata, BusNodeMetadata, NodeMetadata, TextNodeMetadata } from './diagram-metadata'; // node move: original and new position export type NODEMOVE = { - xOrig: string; - yOrig: string; - xNew: string; - yNew: string; + xOrig: number; + yOrig: number; + xNew: number; + yNew: number; }; export enum EdgeType { @@ -65,6 +66,11 @@ export function radToDeg(rad: number): number { return (rad * 180.0) / Math.PI; } +// round number to 2 decimals, for storing positions in metadata +export function round(num: number): number { + return Math.round(num * 100) / 100; +} + // get the transform element of an SVG graphic element export function getTransform(element: SVGGraphicsElement | null): SVGTransform | undefined { let transforms = element?.transform.baseVal; @@ -124,12 +130,11 @@ export function getEdgeFork(point: Point, edgeForkLength: number, angleFork: num } // get the type of edge -export function getEdgeType(edge: SVGGraphicsElement): EdgeType | null { - const edgeType = edge.getAttribute('type'); - if (edgeType == null) { +export function getEdgeType(edge: EdgeMetadata): EdgeType | null { + if (edge.type == null) { return null; } - return EdgeTypeMapping[edgeType]; + return EdgeTypeMapping[edge.type]; } // get the matrix used for the position of the arrow drawn in a PS transformer @@ -366,12 +371,11 @@ export function getPathAngle(path: HTMLElement): number | null { } // sort list of bus nodes by index -export function getSortedBusNodes(busNodes: NodeListOf): SVGGraphicsElement[] { - const sortedBusNodes: SVGGraphicsElement[] = []; - busNodes.forEach((busNode) => { - const index = busNode.getAttribute('index') ?? '-1'; - if (+index >= 0) { - sortedBusNodes[+index] = busNode; +export function getSortedBusNodes(busNodes: BusNodeMetadata[] | undefined): BusNodeMetadata[] { + const sortedBusNodes: BusNodeMetadata[] = []; + busNodes?.forEach((busNode) => { + if (busNode.index >= 0) { + sortedBusNodes[busNode.index] = busNode; } }); return sortedBusNodes; @@ -454,53 +458,25 @@ export function getTextNodePosition(textNode: SVGGraphicsElement | null): Point } // get node move (original and new position) -export function getNodeMove(node: SVGGraphicsElement, nodePosition: Point): NODEMOVE { - const xOrig = node.getAttribute('x') ?? '0'; - const yOrig = node.getAttribute('y') ?? '0'; - const xNew = getFormattedValue(nodePosition.x); - const yNew = getFormattedValue(nodePosition.y); - return { xOrig: xOrig, yOrig: yOrig, xNew: xNew, yNew: yNew }; +export function getNodeMove(node: NodeMetadata, nodePosition: Point): NODEMOVE { + const xNew = round(nodePosition.x); + const yNew = round(nodePosition.y); + return { xOrig: node.x, yOrig: node.y, xNew: xNew, yNew: yNew }; } // get moves (original and new position) of position and connetion of text node export function getTextNodeMoves( - textNode: SVGGraphicsElement, - vlNode: SVGGraphicsElement, + textNode: TextNodeMetadata, + vlNode: NodeMetadata, textPosition: Point, connectionPosition: Point ): [NODEMOVE, NODEMOVE] { - const xNode = vlNode.getAttribute('x') ?? '0'; - const yNode = vlNode.getAttribute('y') ?? '0'; - const xOrig = textNode.getAttribute('shiftx') ?? '0'; - const yOrig = textNode.getAttribute('shifty') ?? '0'; - const xNew = getFormattedValue(textPosition.x - +xNode); - const yNew = getFormattedValue(textPosition.y - +yNode); - const connXOrig = textNode.getAttribute('connectionshiftx') ?? '0'; - const connYOrig = textNode.getAttribute('connectionshifty') ?? '0'; - const connXNew = getFormattedValue(connectionPosition.x - +xNode); - const connYNew = getFormattedValue(connectionPosition.y - +yNode); + const xNew = round(textPosition.x - vlNode.x); + const yNew = round(textPosition.y - vlNode.y); + const connXNew = round(connectionPosition.x - vlNode.x); + const connYNew = round(connectionPosition.y - vlNode.y); return [ - { xOrig: xOrig, yOrig: yOrig, xNew: xNew, yNew: yNew }, - { xOrig: connXOrig, yOrig: connYOrig, xNew: connXNew, yNew: connYNew }, + { xOrig: textNode.shiftX, yOrig: textNode.shiftY, xNew: xNew, yNew: yNew }, + { xOrig: textNode.connectionShiftX, yOrig: textNode.connectionShiftY, xNew: connXNew, yNew: connYNew }, ]; } - -// get number parameter from metadata element -export function getNumberParameter( - parametersMetadataElement: SVGGraphicsElement | null, - parameterName: string, - parameterDefault: number -): number { - const parameter = parametersMetadataElement?.getAttribute(parameterName); - return parameter !== undefined && parameter !== null ? +parameter : parameterDefault; -} - -// get boolean parameter from metadata element -export function getBooleanParameter( - parametersMetadataElement: SVGGraphicsElement | null, - parameterName: string, - parameterDefault: boolean -): boolean { - const parameter = parametersMetadataElement?.getAttribute(parameterName); - return parameter !== undefined && parameter !== null ? parameter === 'true' : parameterDefault; -} diff --git a/src/components/network-area-diagram-viewer/layout-parameters.ts b/src/components/network-area-diagram-viewer/layout-parameters.ts index 354765ec..fd198ce6 100644 --- a/src/components/network-area-diagram-viewer/layout-parameters.ts +++ b/src/components/network-area-diagram-viewer/layout-parameters.ts @@ -5,24 +5,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { getNumberParameter } from './diagram-utils'; +import { LayoutParametersMetadata } from './diagram-metadata'; export class LayoutParameters { - static readonly TEXT_NODE_EDGE_CONNECTION_Y_SHIFT_PARAMETER_NAME = 'textnodeedgeconnectionyshift'; - static readonly TEXT_NODE_EDGE_CONNECTION_Y_SHIFT_DEFAULT = 25.0; - textNodeEdgeConnectionYShift: number; + layoutParametersMetadata: LayoutParametersMetadata | undefined; - constructor(layoutParametersElement: SVGGraphicsElement | null) { - this.textNodeEdgeConnectionYShift = getNumberParameter( - layoutParametersElement, - LayoutParameters.TEXT_NODE_EDGE_CONNECTION_Y_SHIFT_PARAMETER_NAME, - LayoutParameters.TEXT_NODE_EDGE_CONNECTION_Y_SHIFT_DEFAULT - ); + constructor(layoutParametersMetadata: LayoutParametersMetadata | undefined) { + this.layoutParametersMetadata = layoutParametersMetadata; } public getTextNodeEdgeConnectionYShift(): number { - return this.textNodeEdgeConnectionYShift; + return ( + this.layoutParametersMetadata?.textNodeEdgeConnectionYShift ?? + LayoutParameters.TEXT_NODE_EDGE_CONNECTION_Y_SHIFT_DEFAULT + ); } } diff --git a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.test.ts b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.test.ts index 9362b362..b5e1ed7c 100644 --- a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.test.ts +++ b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.test.ts @@ -15,6 +15,7 @@ describe('Test network-area-diagram-viewer', () => { const nad: NetworkAreaDiagramViewer = new NetworkAreaDiagramViewer( container, '', + null, 0, 0, 0, diff --git a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts index fbc42984..f773c026 100644 --- a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts +++ b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts @@ -10,6 +10,7 @@ import '@svgdotjs/svg.panzoom.js'; import * as DiagramUtils from './diagram-utils'; import { SvgParameters } from './svg-parameters'; import { LayoutParameters } from './layout-parameters'; +import { DiagramMetadata, EdgeMetadata, BusNodeMetadata, NodeMetadata, TextNodeMetadata } from './diagram-metadata'; import { CSS_DECLARATION, CSS_RULE, THRESHOLD_STATUS, DEFAULT_DYNAMIC_CSS_RULES } from './dynamic-css-utils'; type DIMENSIONS = { width: number; height: number; viewbox: VIEWBOX }; @@ -43,6 +44,7 @@ export type OnSelectNodeCallbackType = (equipmentId: string, nodeId: string) => export class NetworkAreaDiagramViewer { container: HTMLElement; svgContent: string; + diagramMetadata: DiagramMetadata | null; width: number; height: number; originalWidth: number; @@ -67,6 +69,7 @@ export class NetworkAreaDiagramViewer { constructor( container: HTMLElement, svgContent: string, + diagramMetadata: DiagramMetadata | null, minWidth: number, minHeight: number, maxWidth: number, @@ -80,14 +83,15 @@ export class NetworkAreaDiagramViewer { ) { this.container = container; this.svgContent = svgContent; + this.diagramMetadata = diagramMetadata; this.width = 0; this.height = 0; this.originalWidth = 0; this.originalHeight = 0; this.dynamicCssRules = customDynamicCssRules ?? DEFAULT_DYNAMIC_CSS_RULES; this.init(minWidth, minHeight, maxWidth, maxHeight, enableNodeMoving, enableLevelOfDetail); - this.svgParameters = this.getSvgParameters(); - this.layoutParameters = this.getLayoutParameters(); + this.svgParameters = new SvgParameters(diagramMetadata?.svgParameters); + this.layoutParameters = new LayoutParameters(diagramMetadata?.layoutParameters); this.onMoveNodeCallback = onMoveNodeCallback; this.onMoveTextNodeCallback = onMoveTextNodeCallback; this.onSelectNodeCallback = onSelectNodeCallback; @@ -154,10 +158,10 @@ export class NetworkAreaDiagramViewer { } private getNodeIdFromEquipmentId(equipmentId: string) { - const node: SVGGraphicsElement | null = this.container.querySelector( - 'nad\\:node[equipmentid="' + equipmentId + '"]' + const node: NodeMetadata | undefined = this.diagramMetadata?.nodes.find( + (node) => node.equipmentId == equipmentId ); - return node?.getAttribute('svgid') || null; + return node?.svgId || null; } public moveNodeToCoordinates(equipmentId: string, x: number, y: number) { @@ -308,17 +312,6 @@ export class NetworkAreaDiagramViewer { }); } - private getSvgParameters(): SvgParameters { - const svgParametersElement: SVGGraphicsElement | null = this.container.querySelector('nad\\:svgparameters'); - return new SvgParameters(svgParametersElement); - } - - private getLayoutParameters(): LayoutParameters { - const layoutParametersElement: SVGGraphicsElement | null = - this.container.querySelector('nad\\:layoutparameters'); - return new LayoutParameters(layoutParametersElement); - } - private handleStartDrag(event: Event) { const draggableElem = DiagramUtils.getDraggableFrom(event.target as SVGElement); if (!draggableElem) { @@ -484,10 +477,10 @@ export class NetworkAreaDiagramViewer { const textEdge: SVGGraphicsElement | null = this.container.querySelector("[id='" + textEdgeId + "']"); if (textEdge != null) { // compute voltage level circle radius - const busNodes: NodeListOf = this.container.querySelectorAll( - 'nad\\:busnode[vlnode="' + vlNode.id + '"]' + const busNodes: BusNodeMetadata[] | undefined = this.diagramMetadata?.busNodes.filter( + (busNode) => busNode.vlNode == vlNode.id ); - const nbNeighbours = busNodes.length > 1 ? busNodes.length - 1 : 0; + const nbNeighbours = busNodes !== undefined && busNodes.length > 1 ? busNodes.length - 1 : 0; const voltageLevelCircleRadius = DiagramUtils.getVoltageLevelCircleRadius( nbNeighbours, this.svgParameters.getVoltageLevelCircleRadius() @@ -529,43 +522,32 @@ export class NetworkAreaDiagramViewer { private moveEdges(mousePosition: Point) { // get edges connected to the the node we are moving - const edges: NodeListOf = this.container.querySelectorAll( - 'nad\\:edge[node1="' + - (this.selectedElement?.id ?? -1) + - '"], nad\\:edge[node2="' + - (this.selectedElement?.id ?? -1) + - '"]' + const edges: EdgeMetadata[] | undefined = this.diagramMetadata?.edges.filter( + (edge) => edge.node1 == this.selectedElement?.id || edge.node2 == this.selectedElement?.id ); // group edges, to have multibranches - branches connecting the same nodes - together - const groupedEdges: Map = new Map(); - const loopEdges: Map = new Map(); - const busNodeEdges: Map = new Map(); - edges.forEach((edge) => { - const node1 = edge.getAttribute('node1') ?? '-1'; - const node2 = edge.getAttribute('node2') ?? '-1'; - let edgeGroup: SVGGraphicsElement[] = []; - if (node1 == node2) { + const groupedEdges: Map = new Map(); + const loopEdges: Map = new Map(); + const busNodeEdges: Map = new Map(); + edges?.forEach((edge) => { + let edgeGroup: EdgeMetadata[] = []; + if (edge.node1 == edge.node2) { // loop edge - if (loopEdges.has(node1)) { - edgeGroup = loopEdges.get(node1) ?? []; + if (loopEdges.has(edge.node1)) { + edgeGroup = loopEdges.get(edge.node1) ?? []; } edgeGroup.push(edge); - loopEdges.set(node1, edgeGroup); - const busNodeId1 = edge.getAttribute('busnode1'); - this.addBusNodeEdge(busNodeId1, edge, busNodeEdges); - const busNodeId2 = edge.getAttribute('busnode2'); - this.addBusNodeEdge(busNodeId2, edge, busNodeEdges); + loopEdges.set(edge.node1, edgeGroup); + this.addBusNodeEdge(edge.busNode1, edge, busNodeEdges); + this.addBusNodeEdge(edge.busNode2, edge, busNodeEdges); } else { - const edgeGroupId = node1.concat('_', node2); + const edgeGroupId = edge.node1.concat('_', edge.node2); if (groupedEdges.has(edgeGroupId)) { edgeGroup = groupedEdges.get(edgeGroupId) ?? []; } edgeGroup.push(edge); groupedEdges.set(edgeGroupId, edgeGroup); - const busNodeId = - edge.getAttribute('node1') == this.selectedElement?.id - ? edge.getAttribute('busnode1') - : edge.getAttribute('busnode2'); + const busNodeId = edge.node1 == this.selectedElement?.id ? edge.busNode1 : edge.busNode2; this.addBusNodeEdge(busNodeId, edge, busNodeEdges); } }); @@ -581,12 +563,8 @@ export class NetworkAreaDiagramViewer { this.redrawVoltageLevelNode(this.selectedElement, busNodeEdges, null); } - private addBusNodeEdge( - busNodeId: string | null, - edge: SVGGraphicsElement, - busNodeEdges: Map - ) { - let busEdgeGroup: SVGGraphicsElement[] = []; + private addBusNodeEdge(busNodeId: string | null, edge: EdgeMetadata, busNodeEdges: Map) { + let busEdgeGroup: EdgeMetadata[] = []; if (busNodeId != null) { if (busNodeEdges.has(busNodeId)) { busEdgeGroup = busNodeEdges.get(busNodeId) ?? []; @@ -597,14 +575,11 @@ export class NetworkAreaDiagramViewer { } // get the nodes at the sides of an edge - private getEdgeNodes(edge: SVGGraphicsElement): [SVGGraphicsElement | null, SVGGraphicsElement | null] { - const otherNodeId = - this.selectedElement?.id === edge.getAttribute('node1') - ? edge.getAttribute('node2') - : edge.getAttribute('node1'); + private getEdgeNodes(edge: EdgeMetadata): [SVGGraphicsElement | null, SVGGraphicsElement | null] { + const otherNodeId = this.selectedElement?.id === edge.node1 ? edge.node2 : edge.node1; const otherNode: SVGGraphicsElement | null = this.container.querySelector("[id='" + otherNodeId + "']"); - const node1 = this.selectedElement?.id === edge.getAttribute('node1') ? this.selectedElement : otherNode; - const node2 = otherNode?.id === edge.getAttribute('node1') ? this.selectedElement : otherNode; + const node1 = this.selectedElement?.id === edge.node1 ? this.selectedElement : otherNode; + const node2 = otherNode?.id === edge.node1 ? this.selectedElement : otherNode; return [node1, node2]; } @@ -612,21 +587,19 @@ export class NetworkAreaDiagramViewer { return edgeNodes[0]?.id == this.selectedElement?.id ? edgeNodes[1] : edgeNodes[0]; } - private getNodeRadius(busNodeId: number): [number, number, number] { - const busNode: SVGGraphicsElement | null = this.container.querySelector( - 'nad\\:busnode[svgid="' + busNodeId + '"]' + private getNodeRadius(busNodeId: string): [number, number, number] { + const busNode: BusNodeMetadata | undefined = this.diagramMetadata?.busNodes.find( + (busNode) => busNode.svgId == busNodeId ); - const nbNeighbours = busNode?.getAttribute('nbneighbours'); - const busIndex = busNode?.getAttribute('index'); return DiagramUtils.getNodeRadius( - nbNeighbours == null ? 0 : +nbNeighbours, + busNode?.nbNeighbours == null ? 0 : busNode?.nbNeighbours, this.svgParameters.getVoltageLevelCircleRadius(), - busIndex == null ? 0 : +busIndex, + busNode?.index == null ? 0 : busNode?.index, this.svgParameters.getInterAnnulusSpace() ); } - private moveEdgeGroup(edges: SVGGraphicsElement[], mousePosition: Point) { + private moveEdgeGroup(edges: EdgeMetadata[], mousePosition: Point) { if (edges.length == 1) { this.moveStraightEdge(edges[0], mousePosition); // 1 edge in the group -> straight line } else { @@ -648,12 +621,12 @@ export class NetworkAreaDiagramViewer { } if (edgeNodes[0] == null || edgeNodes[1] == null) { // only 1 side of the edge is in the SVG - this.moveSvgElement(edge.getAttribute('svgid') ?? '-1', this.getTranslation(mousePosition)); + this.moveSvgElement(edge.svgId, this.getTranslation(mousePosition)); return; } // get edge element const edgeNode: SVGGraphicsElement | null = this.container.querySelector( - "[id='" + edge.getAttribute('svgid') + "']" + "[id='" + edge.svgId + "']" ); if (!edgeNode) { return; @@ -672,9 +645,8 @@ export class NetworkAreaDiagramViewer { this.svgParameters.getEdgesForkLength(), angleFork2 ); - const busNodeId1 = edge.getAttribute('busnode1'); - const unknownBusNode1 = busNodeId1 != null && busNodeId1.length == 0; - const nodeRadius1 = this.getNodeRadius(busNodeId1 != null ? +busNodeId1 : -1); + const unknownBusNode1 = edge.busNode1 != null && edge.busNode1.length == 0; + const nodeRadius1 = this.getNodeRadius(edge.busNode1 != null ? edge.busNode1 : '-1'); const edgeStart1 = DiagramUtils.getPointAtDistance( DiagramUtils.getPosition(edgeNodes[0]), edgeFork1, @@ -682,9 +654,8 @@ export class NetworkAreaDiagramViewer { ? nodeRadius1[1] + this.svgParameters.getUnknownBusNodeExtraRadius() : nodeRadius1[1] ); - const busNodeId2 = edge.getAttribute('busnode2'); - const unknownBusNode2 = busNodeId2 != null && busNodeId2.length == 0; - const nodeRadius2 = this.getNodeRadius(busNodeId2 != null ? +busNodeId2 : -1); + const unknownBusNode2 = edge.busNode2 != null && edge.busNode2.length == 0; + const nodeRadius2 = this.getNodeRadius(edge.busNode2 != null ? edge.busNode2 : '-1'); const edgeStart2 = DiagramUtils.getPointAtDistance( DiagramUtils.getPosition(edgeNodes[1]), edgeFork2, @@ -714,7 +685,7 @@ export class NetworkAreaDiagramViewer { } } - private moveStraightEdge(edge: SVGGraphicsElement, mousePosition: Point) { + private moveStraightEdge(edge: EdgeMetadata, mousePosition: Point) { // get edge type const edgeType = DiagramUtils.getEdgeType(edge); if (edgeType == null) { @@ -723,13 +694,11 @@ export class NetworkAreaDiagramViewer { const edgeNodes = this.getEdgeNodes(edge); if (edgeNodes[0] == null || edgeNodes[1] == null) { // only 1 side of the edge is in the SVG - this.moveSvgElement(edge.getAttribute('svgid') ?? '-1', this.getTranslation(mousePosition)); + this.moveSvgElement(edge.svgId, this.getTranslation(mousePosition)); return; } // get edge element - const edgeNode: SVGGraphicsElement | null = this.container.querySelector( - "[id='" + edge.getAttribute('svgid') + "']" - ); + const edgeNode: SVGGraphicsElement | null = this.container.querySelector("[id='" + edge.svgId + "']"); if (!edgeNode) { return; } @@ -738,12 +707,10 @@ export class NetworkAreaDiagramViewer { return; } // compute moved edge data: polyline points - const busNodeId1 = edge.getAttribute('busnode1'); - const nodeRadius1 = this.getNodeRadius(busNodeId1 != null ? +busNodeId1 : -1); - const edgeStart1 = this.getEdgeStart(busNodeId1, nodeRadius1[1], edgeNodes[0], edgeNodes[1]); - const busNodeId2 = edge.getAttribute('busnode2'); - const nodeRadius2 = this.getNodeRadius(busNodeId2 != null ? +busNodeId2 : -1); - const edgeStart2 = this.getEdgeStart(busNodeId2, nodeRadius2[1], edgeNodes[1], edgeNodes[0]); + const nodeRadius1 = this.getNodeRadius(edge.busNode1 != null ? edge.busNode1 : '-1'); + const edgeStart1 = this.getEdgeStart(edge.busNode1, nodeRadius1[1], edgeNodes[0], edgeNodes[1]); + const nodeRadius2 = this.getNodeRadius(edge.busNode2 != null ? edge.busNode2 : '-1'); + const edgeStart2 = this.getEdgeStart(edge.busNode2, nodeRadius2[1], edgeNodes[1], edgeNodes[0]); const edgeMiddle = DiagramUtils.getMidPosition(edgeStart1, edgeStart2); // move edge this.moveEdge(edgeNode, edgeStart1, null, edgeStart2, null, edgeMiddle, nodeRadius1, nodeRadius2, edgeType); @@ -979,14 +946,13 @@ export class NetworkAreaDiagramViewer { polyline?.setAttribute('points', polylinePoints); } - private moveLoopEdgeGroup(edges: SVGGraphicsElement[], mousePosition: Point) { + private moveLoopEdgeGroup(edges: EdgeMetadata[], mousePosition: Point) { edges.forEach((edge) => { // get edge element - const edgeId = edge.getAttribute('svgid'); - if (!edgeId) { + if (!edge.svgId) { return; } - this.moveSvgElement(edgeId, this.getTranslation(mousePosition)); + this.moveSvgElement(edge.svgId, this.getTranslation(mousePosition)); }); } @@ -1008,20 +974,20 @@ export class NetworkAreaDiagramViewer { private redrawVoltageLevelNode( node: SVGGraphicsElement | null, - busNodeEdges: Map, - movedEdges: SVGGraphicsElement[] | null // list of moved edges, null = all edges + busNodeEdges: Map, + movedEdges: EdgeMetadata[] | null // list of moved edges, null = all edges ) { if (node != null) { // get buses belonging to voltage level - const busNodes: NodeListOf = this.container.querySelectorAll( - 'nad\\:busnode[vlnode="' + node.id + '"]' + const busNodes: BusNodeMetadata[] | undefined = this.diagramMetadata?.busNodes.filter( + (busNode) => busNode.vlNode == node.id ); // if single bus voltage level -> do not redraw anything - if (busNodes.length <= 1) { + if (busNodes !== undefined && busNodes.length <= 1) { return; } // sort buses by index - const sortedBusNodes: SVGGraphicsElement[] = DiagramUtils.getSortedBusNodes(busNodes); + const sortedBusNodes: BusNodeMetadata[] = DiagramUtils.getSortedBusNodes(busNodes); const traversingBusEdgesAngles: number[] = []; let redraw = false; for (let index = 0; index < sortedBusNodes.length; index++) { @@ -1031,22 +997,18 @@ export class NetworkAreaDiagramViewer { this.redrawBusNode(node, busNode, index, traversingBusEdgesAngles); } // add angles of edges starting from bus to traversing edges angles - const busEdges = busNodeEdges.get(busNode.getAttribute('svgid') ?? '-1') ?? []; + const busEdges = busNodeEdges.get(busNode.svgId) ?? []; busEdges.forEach((edge) => { - const edgeId = edge.getAttribute('svgid') ?? '-1'; - const node1 = edge.getAttribute('node1') ?? '-1'; - const node2 = edge.getAttribute('node2') ?? '-1'; - const edgeAngle = this.getEdgeAngle(busNode, edge, edgeId, node1 == node2); + const edgeAngle = this.getEdgeAngle(busNode, edge, edge.svgId, edge.node1 == edge.node2); if (typeof edgeAngle !== 'undefined') { traversingBusEdgesAngles.push(edgeAngle); } // redraw only if there is an edge going to another voltage level - if (node1 != node2) { + if (edge.node1 != edge.node2) { // redraw only if the edge has been moved if (movedEdges != null) { movedEdges.forEach((movedEdge) => { - const movedEdgeId = movedEdge.getAttribute('svgid'); - if (edgeId == movedEdgeId) { + if (edge.svgId == movedEdge.svgId) { redraw = true; } }); @@ -1060,15 +1022,13 @@ export class NetworkAreaDiagramViewer { } } - private getEdgeAngle(busNode: SVGGraphicsElement, edge: SVGGraphicsElement, edgeId: string, isLoopEdge: boolean) { - const busId = busNode.getAttribute('svgid') ?? '-2'; - const busNode1 = edge.getAttribute('busnode1') ?? '-1'; - const angleId = busId == busNode1 ? edgeId + '.1' : edgeId + '.2'; + private getEdgeAngle(busNode: BusNodeMetadata, edge: EdgeMetadata, edgeId: string, isLoopEdge: boolean) { + const angleId = busNode.svgId == edge.busNode1 ? edgeId + '.1' : edgeId + '.2'; if (!this.edgeAngles.has(angleId)) { // if not yet stored in angle map -> compute and store it const edgeNode: SVGGraphicsElement | null = this.container.querySelector("[id='" + edgeId + "']"); if (edgeNode) { - const side = busId == busNode1 ? 0 : 1; + const side = busNode.svgId == edge.busNode1 ? 0 : 1; const halfEdge: HTMLElement = edgeNode.children.item(side)?.firstElementChild; if (halfEdge != null) { const angle = isLoopEdge @@ -1085,13 +1045,12 @@ export class NetworkAreaDiagramViewer { private redrawBusNode( node: SVGGraphicsElement, - busNode: SVGGraphicsElement, + busNode: BusNodeMetadata, busIndex: number, traversingBusEdgesAngles: number[] ) { - const nbNeighbours = busNode.getAttribute('nbneighbours'); const busNodeRadius = DiagramUtils.getNodeRadius( - nbNeighbours == null ? 0 : +nbNeighbours, + busNode.nbNeighbours == null ? 0 : busNode.nbNeighbours, this.svgParameters.getVoltageLevelCircleRadius(), busIndex, this.svgParameters.getInterAnnulusSpace() @@ -1114,28 +1073,21 @@ export class NetworkAreaDiagramViewer { } } - private redrawOtherVoltageLevelNode(otherNode: SVGGraphicsElement | null, movedEdges: SVGGraphicsElement[]) { + private redrawOtherVoltageLevelNode(otherNode: SVGGraphicsElement | null, movedEdges: EdgeMetadata[]) { if (otherNode != null) { // get other voltage level node edges - const edges: NodeListOf = this.container.querySelectorAll( - 'nad\\:edge[node1="' + (otherNode?.id ?? -1) + '"], nad\\:edge[node2="' + (otherNode?.id ?? -1) + '"]' + const edges: EdgeMetadata[] | undefined = this.diagramMetadata?.edges.filter( + (edge) => edge.node1 == (otherNode?.id ?? -1) || edge.node2 == (otherNode?.id ?? -1) ); // group other voltage level node edges by bus node - const busNodeEdges: Map = new Map(); - edges.forEach((edge) => { - const node1 = edge.getAttribute('node1') ?? '-1'; - const node2 = edge.getAttribute('node2') ?? '-1'; - if (node1 == node2) { + const busNodeEdges: Map = new Map(); + edges?.forEach((edge) => { + if (edge.node1 == edge.node2) { // loop edge - const busNodeId1 = edge.getAttribute('busnode1'); - this.addBusNodeEdge(busNodeId1, edge, busNodeEdges); - const busNodeId2 = edge.getAttribute('busnode2'); - this.addBusNodeEdge(busNodeId2, edge, busNodeEdges); + this.addBusNodeEdge(edge.busNode1, edge, busNodeEdges); + this.addBusNodeEdge(edge.busNode2, edge, busNodeEdges); } else { - const busNodeId = - edge.getAttribute('node1') == otherNode?.id - ? edge.getAttribute('busnode1') - : edge.getAttribute('busnode2'); + const busNodeId = edge.node1 == otherNode?.id ? edge.busNode1 : edge.busNode2; this.addBusNodeEdge(busNodeId, edge, busNodeEdges); } }); @@ -1144,7 +1096,7 @@ export class NetworkAreaDiagramViewer { } } - private moveThreeWtEdge(edge: SVGGraphicsElement, edgeNode: SVGGraphicsElement, mousePosition: Point) { + private moveThreeWtEdge(edge: EdgeMetadata, edgeNode: SVGGraphicsElement, mousePosition: Point) { const twtEdge: HTMLElement = edgeNode.firstElementChild; if (twtEdge != null) { const points = DiagramUtils.getPolylinePoints(twtEdge); @@ -1152,9 +1104,8 @@ export class NetworkAreaDiagramViewer { // compute polyline points const edgeNodes = this.getEdgeNodes(edge); const threeWtMoved = edgeNodes[1]?.id == this.selectedElement?.id; - const busNodeId1 = edge.getAttribute('busnode1'); - const nodeRadius1 = this.getNodeRadius(busNodeId1 != null ? +busNodeId1 : -1); - const edgeStart = this.getEdgeStart(busNodeId1, nodeRadius1[1], edgeNodes[0], edgeNodes[1]); + const nodeRadius1 = this.getNodeRadius(edge.busNode1 != null ? edge.busNode1 : '-1'); + const edgeStart = this.getEdgeStart(edge.busNode1, nodeRadius1[1], edgeNodes[0], edgeNodes[1]); const translation = this.getTranslation(mousePosition); const edgeEnd = threeWtMoved ? new Point( @@ -1191,23 +1142,23 @@ export class NetworkAreaDiagramViewer { private updateNodeMetadataCallCallback(mousePosition: Point, callMoveNodeCallback: boolean) { // get moved node from metadata - const node: SVGGraphicsElement | null = this.container.querySelector( - 'nad\\:node[svgid="' + this.selectedElement?.id + '"]' + const node: NodeMetadata | undefined = this.diagramMetadata?.nodes.find( + (node) => node.svgId == this.selectedElement?.id ); if (node != null) { const nodeMove = DiagramUtils.getNodeMove(node, mousePosition); // update node position in metadata - node.setAttribute('x', nodeMove.xNew); - node.setAttribute('y', nodeMove.yNew); + node.x = nodeMove.xNew; + node.y = nodeMove.yNew; // call the node move callback, if defined if (this.onMoveNodeCallback != null && callMoveNodeCallback) { this.onMoveNodeCallback( - node.getAttribute('equipmentid') ?? '', - node.getAttribute('svgid') ?? '', - +nodeMove.xNew, - +nodeMove.yNew, - +nodeMove.xOrig, - +nodeMove.yOrig + node.equipmentId, + node.svgId, + nodeMove.xNew, + nodeMove.yNew, + nodeMove.xOrig, + nodeMove.yOrig ); } } @@ -1216,34 +1167,34 @@ export class NetworkAreaDiagramViewer { private updateTextNodeMetadataCallCallback(mousePosition: Point) { if (this.onMoveTextNodeCallback != null) { // get from metadata node connected to moved text node - const node: SVGGraphicsElement | null = this.container.querySelector( - 'nad\\:node[svgid="' + DiagramUtils.getVoltageLevelNodeId(this.selectedElement?.id) + '"]' + const node: NodeMetadata | undefined = this.diagramMetadata?.nodes.find( + (node) => node.svgId == DiagramUtils.getVoltageLevelNodeId(this.selectedElement?.id) ); - const textNode: SVGGraphicsElement | null = this.container.querySelector( - 'nad\\:textnode[svgid="' + this.selectedElement?.id + '"]' + const textNode: TextNodeMetadata | undefined = this.diagramMetadata?.textNodes.find( + (textNode) => textNode.svgId == this.selectedElement?.id ); if (node != null && textNode != null) { // get new text node position const textPosition = DiagramUtils.getTextNodeAngleFromCentre(this.selectedElement, mousePosition); const textNodeMoves = DiagramUtils.getTextNodeMoves(textNode, node, textPosition, this.endTextEdge); // update text node position in metadata - textNode.setAttribute('shiftx', textNodeMoves[0].xNew); - textNode.setAttribute('shifty', textNodeMoves[0].yNew); - textNode.setAttribute('connectionshiftx', textNodeMoves[1].xNew); - textNode.setAttribute('connectionshifty', textNodeMoves[1].yNew); + textNode.shiftX = textNodeMoves[0].xNew; + textNode.shiftY = textNodeMoves[0].yNew; + textNode.connectionShiftX = textNodeMoves[1].xNew; + textNode.connectionShiftY = textNodeMoves[1].yNew; // call the node move callback, if defined this.onMoveTextNodeCallback( - node.getAttribute('equipmentid') ?? '', - node.getAttribute('svgid') ?? '', - textNode.getAttribute('svgid') ?? '', - +textNodeMoves[0].xNew, - +textNodeMoves[0].yNew, - +textNodeMoves[0].xOrig, - +textNodeMoves[0].yOrig, - +textNodeMoves[1].xNew, - +textNodeMoves[1].yNew, - +textNodeMoves[1].xOrig, - +textNodeMoves[1].yOrig + node.equipmentId, + node.svgId, + textNode.svgId, + textNodeMoves[0].xNew, + textNodeMoves[0].yNew, + textNodeMoves[0].xOrig, + textNodeMoves[0].yOrig, + textNodeMoves[1].xNew, + textNodeMoves[1].yNew, + textNodeMoves[1].xOrig, + textNodeMoves[1].yOrig ); } } @@ -1253,11 +1204,11 @@ export class NetworkAreaDiagramViewer { // call the select node callback, if defined if (this.onSelectNodeCallback != null) { // get selected node from metadata - const node: SVGGraphicsElement | null = this.container.querySelector( - 'nad\\:node[svgid="' + this.selectedElement?.id + '"]' + const node: NodeMetadata | undefined = this.diagramMetadata?.nodes.find( + (node) => node.svgId == this.selectedElement?.id ); if (node != null) { - this.onSelectNodeCallback(node.getAttribute('equipmentid') ?? '', node.getAttribute('svgid') ?? ''); + this.onSelectNodeCallback(node.equipmentId, node.svgId); } } } diff --git a/src/components/network-area-diagram-viewer/svg-parameters.ts b/src/components/network-area-diagram-viewer/svg-parameters.ts index c5be54b2..e904d1b9 100644 --- a/src/components/network-area-diagram-viewer/svg-parameters.ts +++ b/src/components/network-area-diagram-viewer/svg-parameters.ts @@ -5,25 +5,14 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { getNumberParameter, getBooleanParameter } from './diagram-utils'; +import { SvgParametersMetadata } from './diagram-metadata'; +import { degToRad } from './diagram-utils'; export class SvgParameters { - static readonly VOLTAGE_LEVEL_CIRCLE_RADIUS_PARAMETER_NAME = 'voltagelevelcircleradius'; - static readonly INTER_ANNULUS_SPACE_PARAMETER_NAME = 'interannulusspace'; - static readonly TRANSFORMER_CIRCLE_RADIUS_PARAMETER_NAME = 'transformercircleradius'; - static readonly EDGES_FORK_APERTURE_PARAMETER_NAME = 'edgesforkaperture'; - static readonly EDGES_FORK_LENGTH_PARAMETER_NAME = 'edgesforklength'; - static readonly ARROW_SHIFT_PARAMETER_NAME = 'arrowshift'; - static readonly ARROW_LABEL_SHIFT_PARAMETER_NAME = 'arrowlabelshift'; - static readonly CONVERTER_STATION_WIDTH_PARAMETER_NAME = 'converterstationwidth'; - static readonly NODE_HOLLOW_WIDTH_PARAMETER_NAME = 'nodehollowwidth'; - static readonly UNKNOWN_BUS_NODE_EXTRA_RADIUS_PARAMETER_NAME = 'unknownbusnodeextraradius'; - static readonly EDGE_NAME_DISPLAYED_PARAMETER_NAME = 'edgenamedisplayed'; - static readonly VOLTAGE_LEVEL_CIRCLE_RADIUS_DEFAULT = 30.0; static readonly INTER_ANNULUS_SPACE_DEFAULT = 5.0; static readonly TRANSFORMER_CIRCLE_RADIUS_DEFAULT = 20.0; - static readonly EDGES_FORK_APERTURE_DEFAULT = 1.05; + static readonly EDGES_FORK_APERTURE_DEFAULT = 60; static readonly EDGES_FORK_LENGTH_DEFAULT = 80.0; static readonly ARROW_SHIFT_DEFAULT = 30.0; static readonly ARROW_LABEL_SHIFT_DEFAULT = 19.0; @@ -32,117 +21,57 @@ export class SvgParameters { static readonly UNKNOWN_BUS_NODE_EXTRA_RADIUS_DEFAULT = 10.0; static readonly EDGE_NAME_DISPLAYED_DEFAULT = true; - voltageLevelCircleRadius: number; - interAnnulusSpace: number; - transformerCircleRadius: number; - edgesForkAperture: number; - edgesForkLength: number; - arrowShift: number; - arrowLabelShift: number; - converterStationWidth: number; - nodeHollowWidth: number; - unknownBusNodeExtraRadius: number; - edgeNameDisplayed: boolean; + svgParametersMetadata: SvgParametersMetadata | undefined; - constructor(svgParametersElement: SVGGraphicsElement | null) { - this.voltageLevelCircleRadius = getNumberParameter( - svgParametersElement, - SvgParameters.VOLTAGE_LEVEL_CIRCLE_RADIUS_PARAMETER_NAME, - SvgParameters.VOLTAGE_LEVEL_CIRCLE_RADIUS_DEFAULT - ); - this.interAnnulusSpace = getNumberParameter( - svgParametersElement, - SvgParameters.INTER_ANNULUS_SPACE_PARAMETER_NAME, - SvgParameters.INTER_ANNULUS_SPACE_DEFAULT - ); - this.transformerCircleRadius = getNumberParameter( - svgParametersElement, - SvgParameters.TRANSFORMER_CIRCLE_RADIUS_PARAMETER_NAME, - SvgParameters.TRANSFORMER_CIRCLE_RADIUS_DEFAULT - ); - this.edgesForkAperture = getNumberParameter( - svgParametersElement, - SvgParameters.EDGES_FORK_APERTURE_PARAMETER_NAME, - SvgParameters.EDGES_FORK_APERTURE_DEFAULT - ); - this.edgesForkLength = getNumberParameter( - svgParametersElement, - SvgParameters.EDGES_FORK_LENGTH_PARAMETER_NAME, - SvgParameters.EDGES_FORK_LENGTH_DEFAULT - ); - this.arrowShift = getNumberParameter( - svgParametersElement, - SvgParameters.ARROW_SHIFT_PARAMETER_NAME, - SvgParameters.ARROW_SHIFT_DEFAULT - ); - this.arrowLabelShift = getNumberParameter( - svgParametersElement, - SvgParameters.ARROW_LABEL_SHIFT_PARAMETER_NAME, - SvgParameters.ARROW_LABEL_SHIFT_DEFAULT - ); - this.converterStationWidth = getNumberParameter( - svgParametersElement, - SvgParameters.CONVERTER_STATION_WIDTH_PARAMETER_NAME, - SvgParameters.CONVERTER_STATION_WIDTH_DEFAULT - ); - this.nodeHollowWidth = getNumberParameter( - svgParametersElement, - SvgParameters.NODE_HOLLOW_WIDTH_PARAMETER_NAME, - SvgParameters.NODE_HOLLOW_WIDTH_DEFAULT - ); - this.unknownBusNodeExtraRadius = getNumberParameter( - svgParametersElement, - SvgParameters.UNKNOWN_BUS_NODE_EXTRA_RADIUS_PARAMETER_NAME, - SvgParameters.UNKNOWN_BUS_NODE_EXTRA_RADIUS_DEFAULT - ); - this.edgeNameDisplayed = getBooleanParameter( - svgParametersElement, - SvgParameters.EDGE_NAME_DISPLAYED_PARAMETER_NAME, - SvgParameters.EDGE_NAME_DISPLAYED_DEFAULT - ); + constructor(svgParametersMetadata: SvgParametersMetadata | undefined) { + this.svgParametersMetadata = svgParametersMetadata; } public getVoltageLevelCircleRadius(): number { - return this.voltageLevelCircleRadius; + return ( + this.svgParametersMetadata?.voltageLevelCircleRadius ?? SvgParameters.VOLTAGE_LEVEL_CIRCLE_RADIUS_DEFAULT + ); } public getInterAnnulusSpace(): number { - return this.interAnnulusSpace; + return this.svgParametersMetadata?.interAnnulusSpace ?? SvgParameters.INTER_ANNULUS_SPACE_DEFAULT; } public getTransformerCircleRadius(): number { - return this.transformerCircleRadius; + return this.svgParametersMetadata?.transformerCircleRadius ?? SvgParameters.TRANSFORMER_CIRCLE_RADIUS_DEFAULT; } public getEdgesForkAperture(): number { - return this.edgesForkAperture; + return degToRad(this.svgParametersMetadata?.edgesForkAperture ?? SvgParameters.EDGES_FORK_APERTURE_DEFAULT); } public getEdgesForkLength(): number { - return this.edgesForkLength; + return this.svgParametersMetadata?.edgesForkLength ?? SvgParameters.EDGES_FORK_LENGTH_DEFAULT; } public getArrowShift(): number { - return this.arrowShift; + return this.svgParametersMetadata?.arrowShift ?? SvgParameters.ARROW_SHIFT_DEFAULT; } public getArrowLabelShift(): number { - return this.arrowLabelShift; + return this.svgParametersMetadata?.arrowLabelShift ?? SvgParameters.ARROW_LABEL_SHIFT_DEFAULT; } public getConverterStationWidth(): number { - return this.converterStationWidth; + return this.svgParametersMetadata?.converterStationWidth ?? SvgParameters.CONVERTER_STATION_WIDTH_DEFAULT; } public getNodeHollowWidth(): number { - return this.nodeHollowWidth; + return this.svgParametersMetadata?.nodeHollowWidth ?? SvgParameters.NODE_HOLLOW_WIDTH_DEFAULT; } public getUnknownBusNodeExtraRadius(): number { - return this.unknownBusNodeExtraRadius; + return ( + this.svgParametersMetadata?.unknownBusNodeExtraRadius ?? SvgParameters.UNKNOWN_BUS_NODE_EXTRA_RADIUS_DEFAULT + ); } public getEdgeNameDisplayed(): boolean { - return this.edgeNameDisplayed; + return this.svgParametersMetadata?.edgeNameDisplayed ?? SvgParameters.EDGE_NAME_DISPLAYED_DEFAULT; } } From 99cc3f468d73aadf66786013b352b3232c787c32 Mon Sep 17 00:00:00 2001 From: "massimo.ferraro" Date: Thu, 10 Oct 2024 19:09:44 +0200 Subject: [PATCH 5/9] Split mouse events methods in network area diagram viewer Signed-off-by: massimo.ferraro --- .../network-area-diagram-viewer.ts | 159 +++++++++--------- 1 file changed, 84 insertions(+), 75 deletions(-) diff --git a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts index f773c026..713f7bbf 100644 --- a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts +++ b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts @@ -170,8 +170,8 @@ export class NetworkAreaDiagramViewer { const elemToMove: SVGElement | null = this.container.querySelector('[id="' + nodeId + '"]'); if (elemToMove) { const newPosition = new Point(x, y); - this.processStartDrag(elemToMove, false); - this.processEndDrag(newPosition, false); + this.initializeDrag(elemToMove); + this.completeDrag(newPosition, false); } } } @@ -213,16 +213,16 @@ export class NetworkAreaDiagramViewer { // add events if (enableNodeMoving) { this.svgDraw.on('mousedown', (e: Event) => { - this.handleStartDrag(e); + this.handleStartDragSelectEvent(e); }); this.svgDraw.on('mousemove', (e: Event) => { - this.handleDrag(e); + this.handleDragEvent(e); }); this.svgDraw.on('mouseup', (e: Event) => { - this.handleEndDrag(e); + this.handleEndDragSelectEvent(e); }); this.svgDraw.on('mouseleave', (e: Event) => { - this.handleEndDrag(e); + this.handleEndDragSelectEvent(e); }); } this.svgDraw.on('panStart', function () { @@ -312,87 +312,96 @@ export class NetworkAreaDiagramViewer { }); } - private handleStartDrag(event: Event) { + private handleStartDragSelectEvent(event: Event) { + // check element is draggable or selectable const draggableElem = DiagramUtils.getDraggableFrom(event.target as SVGElement); if (!draggableElem) { return; } - const isShiftKeyDown = !!(event as MouseEvent).shiftKey; - this.processStartDrag(draggableElem, isShiftKeyDown); - } - - private processStartDrag(draggableElem: SVGElement, isShiftKeyDown: boolean) { this.disablePanzoom(); // to avoid panning the whole SVG when moving or selecting a node - this.selectedElement = draggableElem as SVGGraphicsElement; // element to be moved or selected // change cursor style const svg: HTMLElement = this.svgDraw?.node.firstElementChild?.parentElement; svg.style.cursor = 'grabbing'; - if (!isShiftKeyDown) { + // check dragging vs. selection + this.shiftKeyOnMouseDown = !!(event as MouseEvent).shiftKey; + if (!this.shiftKeyOnMouseDown) { // moving node - this.shiftKeyOnMouseDown = false; - this.ctm = this.svgDraw?.node.getScreenCTM(); // used to compute mouse movement - this.initialPosition = DiagramUtils.getPosition(this.selectedElement); // used for the offset - this.edgeAngles = new Map(); - // check if I'm moving a text node - if (DiagramUtils.isTextNode(this.selectedElement)) { - this.textNodeSelected = true; - } + this.initializeDrag(draggableElem); } else { // selecting node - this.shiftKeyOnMouseDown = true; + this.selectedElement = draggableElem as SVGGraphicsElement; // element to be selected } } - private handleDrag(event: Event) { - if (this.selectedElement) { + private initializeDrag(draggableElem: SVGElement) { + this.selectedElement = draggableElem as SVGGraphicsElement; // element to be moved + this.ctm = this.svgDraw?.node.getScreenCTM(); // used to compute mouse movement + this.initialPosition = DiagramUtils.getPosition(this.selectedElement); // used for the offset + this.edgeAngles = new Map(); // used for node redrawing + // check if I'm moving a text node + if (DiagramUtils.isTextNode(this.selectedElement)) { + this.textNodeSelected = true; + } + } + + private handleDragEvent(event: Event) { + if (this.selectedElement && !this.shiftKeyOnMouseDown) { event.preventDefault(); + this.ctm = this.svgDraw?.node.getScreenCTM(); // used to compute SVG transformations const newPosition = this.getMousePosition(event as MouseEvent); - this.processDrag(newPosition); + this.drag(newPosition); } } - private processDrag(newPosition: Point) { + private drag(newPosition: Point) { if (this.selectedElement) { - if (!this.shiftKeyOnMouseDown) { - // moving node - this.ctm = this.svgDraw?.node.getScreenCTM(); // used to compute SVG transformations - this.updateGraph(newPosition); - this.initialPosition = DiagramUtils.getPosition(this.selectedElement); + if (this.textNodeSelected) { + this.dragVoltageLevelText(newPosition); + } else { + this.dragVoltageLevelNode(newPosition); } + this.initialPosition = DiagramUtils.getPosition(this.selectedElement); } } - private handleEndDrag(event: Event) { - const newPosition = this.getMousePosition(event as MouseEvent); - this.processEndDrag(newPosition, true); + private handleEndDragSelectEvent(event: Event) { + if (!this.shiftKeyOnMouseDown) { + // moving node + const newPosition = this.getMousePosition(event as MouseEvent); + this.completeDrag(newPosition, true); + } else { + // selecting node + this.completeSelect(); + } + // change cursor style + const svg: HTMLElement = this.svgDraw?.node.firstElementChild?.parentElement; + svg.style.removeProperty('cursor'); + this.enablePanzoom(); } - private processEndDrag(newPosition: Point, callMoveNodeCallback: boolean) { + private completeDrag(newPosition: Point, callMoveNodeCallback: boolean) { if (this.selectedElement) { - if (!this.shiftKeyOnMouseDown) { - // moving node - this.updateGraph(newPosition); - if (this.textNodeSelected) { - this.updateTextNodeMetadataCallCallback(newPosition); - } else { - this.updateNodeMetadataCallCallback(newPosition, callMoveNodeCallback); - } - this.initialPosition = new Point(0, 0); - this.textNodeSelected = false; - this.endTextEdge = new Point(0, 0); + if (this.textNodeSelected) { + this.dragVoltageLevelText(newPosition); + this.updateTextNodeMetadataCallCallback(newPosition); } else { - // selecting node - this.callSelectNodeCallback(); - this.shiftKeyOnMouseDown = false; + this.dragVoltageLevelNode(newPosition); + this.updateNodeMetadataCallCallback(newPosition, callMoveNodeCallback); } - // change cursor style - const svg: HTMLElement = this.svgDraw?.node.firstElementChild?.parentElement; - svg.style.removeProperty('cursor'); - this.selectedElement = null; + // reset data this.initialPosition = new Point(0, 0); this.textNodeSelected = false; this.endTextEdge = new Point(0, 0); - this.enablePanzoom(); + this.selectedElement = null; + } + } + + private completeSelect() { + if (this.selectedElement) { + this.callSelectNodeCallback(); + // reset data + this.shiftKeyOnMouseDown = false; + this.selectedElement = null; } } @@ -409,26 +418,26 @@ export class NetworkAreaDiagramViewer { return new Point(mousePosition.x - this.initialPosition.x, mousePosition.y - this.initialPosition.y); } - private updateGraph(mousePosition: Point) { - if (this.textNodeSelected) { - window.getSelection()?.empty(); // to avoid text highlighting in firefox - const vlNode: SVGGraphicsElement | null = this.container.querySelector( - "[id='" + DiagramUtils.getVoltageLevelNodeId(this.selectedElement?.id) + "']" - ); - this.moveText(this.selectedElement, vlNode, mousePosition, DiagramUtils.getTextNodeAngleFromCentre); - } else { - this.moveNode(mousePosition); - const textNode: SVGGraphicsElement | null = this.container.querySelector( - "[id='" + DiagramUtils.getTextNodeId(this.selectedElement?.id) + "']" - ); - this.moveText( - textNode, - this.selectedElement, - this.getTranslation(mousePosition), - DiagramUtils.getTextNodeTranslatedPosition - ); - this.moveEdges(mousePosition); - } + private dragVoltageLevelText(mousePosition: Point) { + window.getSelection()?.empty(); // to avoid text highlighting in firefox + const vlNode: SVGGraphicsElement | null = this.container.querySelector( + "[id='" + DiagramUtils.getVoltageLevelNodeId(this.selectedElement?.id) + "']" + ); + this.moveText(this.selectedElement, vlNode, mousePosition, DiagramUtils.getTextNodeAngleFromCentre); + } + + private dragVoltageLevelNode(mousePosition: Point) { + this.moveNode(mousePosition); + const textNode: SVGGraphicsElement | null = this.container.querySelector( + "[id='" + DiagramUtils.getTextNodeId(this.selectedElement?.id) + "']" + ); + this.moveText( + textNode, + this.selectedElement, + this.getTranslation(mousePosition), + DiagramUtils.getTextNodeTranslatedPosition + ); + this.moveEdges(mousePosition); } private moveNode(mousePosition: Point) { From 970587ded548e4e8e8e72fb189e4b0eac96af3de Mon Sep 17 00:00:00 2001 From: "massimo.ferraro" Date: Fri, 11 Oct 2024 12:47:50 +0200 Subject: [PATCH 6/9] Fix issue with panzoom Signed-off-by: massimo.ferraro --- .../network-area-diagram-viewer.ts | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts index 713f7bbf..f96fbc80 100644 --- a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts +++ b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts @@ -365,18 +365,21 @@ export class NetworkAreaDiagramViewer { } private handleEndDragSelectEvent(event: Event) { - if (!this.shiftKeyOnMouseDown) { - // moving node - const newPosition = this.getMousePosition(event as MouseEvent); - this.completeDrag(newPosition, true); - } else { - // selecting node - this.completeSelect(); + // check if I moved or selected an element + if (this.selectedElement) { + if (!this.shiftKeyOnMouseDown) { + // moving node + const newPosition = this.getMousePosition(event as MouseEvent); + this.completeDrag(newPosition, true); + } else { + // selecting node + this.completeSelect(); + } + // change cursor style + const svg: HTMLElement = this.svgDraw?.node.firstElementChild?.parentElement; + svg.style.removeProperty('cursor'); + this.enablePanzoom(); } - // change cursor style - const svg: HTMLElement = this.svgDraw?.node.firstElementChild?.parentElement; - svg.style.removeProperty('cursor'); - this.enablePanzoom(); } private completeDrag(newPosition: Point, callMoveNodeCallback: boolean) { From f76162328b710356e859321bfee7f45ee6dfbc35 Mon Sep 17 00:00:00 2001 From: "massimo.ferraro" Date: Mon, 14 Oct 2024 12:56:57 +0200 Subject: [PATCH 7/9] Enable node selection when node moving is disabled in network area diagram viewer Signed-off-by: massimo.ferraro --- demo/src/diagram-viewers/add-diagrams.ts | 4 +- .../network-area-diagram-viewer.ts | 46 ++++++++++++++++--- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/demo/src/diagram-viewers/add-diagrams.ts b/demo/src/diagram-viewers/add-diagrams.ts index 9b5becd5..799dc901 100644 --- a/demo/src/diagram-viewers/add-diagrams.ts +++ b/demo/src/diagram-viewers/add-diagrams.ts @@ -72,8 +72,8 @@ export const addNadToDemo = () => { 600, 1000, 1200, - handleNodeMove, - handleTextNodeMove, + null, + null, handleNodeSelect, false, false, diff --git a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts index f96fbc80..d0075b8d 100644 --- a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts +++ b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts @@ -64,6 +64,7 @@ export class NetworkAreaDiagramViewer { onMoveTextNodeCallback: OnMoveTextNodeCallbackType | null; onSelectNodeCallback: OnSelectNodeCallbackType | null; shiftKeyOnMouseDown: boolean = false; + enableNodeMoving: boolean = false; dynamicCssRules: CSS_RULE[]; constructor( @@ -88,13 +89,14 @@ export class NetworkAreaDiagramViewer { this.height = 0; this.originalWidth = 0; this.originalHeight = 0; + this.enableNodeMoving = enableNodeMoving; this.dynamicCssRules = customDynamicCssRules ?? DEFAULT_DYNAMIC_CSS_RULES; - this.init(minWidth, minHeight, maxWidth, maxHeight, enableNodeMoving, enableLevelOfDetail); - this.svgParameters = new SvgParameters(diagramMetadata?.svgParameters); - this.layoutParameters = new LayoutParameters(diagramMetadata?.layoutParameters); this.onMoveNodeCallback = onMoveNodeCallback; this.onMoveTextNodeCallback = onMoveTextNodeCallback; this.onSelectNodeCallback = onSelectNodeCallback; + this.init(minWidth, minHeight, maxWidth, maxHeight, enableLevelOfDetail); + this.svgParameters = new SvgParameters(diagramMetadata?.svgParameters); + this.layoutParameters = new LayoutParameters(diagramMetadata?.layoutParameters); } public setWidth(width: number): void { @@ -181,7 +183,6 @@ export class NetworkAreaDiagramViewer { minHeight: number, maxWidth: number, maxHeight: number, - enableNodeMoving: boolean, enableLevelOfDetail: boolean ): void { if (!this.container || !this.svgContent) { @@ -211,13 +212,17 @@ export class NetworkAreaDiagramViewer { drawnSvg.style.overflow = 'visible'; // add events - if (enableNodeMoving) { + if (this.enableNodeMoving || this.onSelectNodeCallback !== null) { this.svgDraw.on('mousedown', (e: Event) => { this.handleStartDragSelectEvent(e); }); + } + if (this.enableNodeMoving) { this.svgDraw.on('mousemove', (e: Event) => { this.handleDragEvent(e); }); + } + if (this.enableNodeMoving || this.onSelectNodeCallback !== null) { this.svgDraw.on('mouseup', (e: Event) => { this.handleEndDragSelectEvent(e); }); @@ -269,7 +274,7 @@ export class NetworkAreaDiagramViewer { observer.observe(targetNode, { attributeFilter: ['viewBox'] }); } - if (enableNodeMoving) { + if (this.enableNodeMoving || this.onSelectNodeCallback !== null) { // fill empty elements: unknown buses and three windings transformers const emptyElements: NodeListOf = this.container.querySelectorAll( '.nad-unknown-busnode, .nad-3wt-nodes .nad-winding' @@ -313,17 +318,30 @@ export class NetworkAreaDiagramViewer { } private handleStartDragSelectEvent(event: Event) { + // check mouse button + if ((event as MouseEvent).button !== 0) { + return; + } // check element is draggable or selectable const draggableElem = DiagramUtils.getDraggableFrom(event.target as SVGElement); if (!draggableElem) { return; } + this.shiftKeyOnMouseDown = !!(event as MouseEvent).shiftKey; + // here to avoid disabling pannig and changing cursor + // when moving is disabled and the shift key is not pressed + if (!this.shiftKeyOnMouseDown && !this.enableNodeMoving) { + return; + } + // avoid selecting text nodes + if (this.shiftKeyOnMouseDown && DiagramUtils.isTextNode(draggableElem as SVGGraphicsElement)) { + return; + } this.disablePanzoom(); // to avoid panning the whole SVG when moving or selecting a node // change cursor style const svg: HTMLElement = this.svgDraw?.node.firstElementChild?.parentElement; svg.style.cursor = 'grabbing'; // check dragging vs. selection - this.shiftKeyOnMouseDown = !!(event as MouseEvent).shiftKey; if (!this.shiftKeyOnMouseDown) { // moving node this.initializeDrag(draggableElem); @@ -345,6 +363,13 @@ export class NetworkAreaDiagramViewer { } private handleDragEvent(event: Event) { + // check mouse button + if ((event as MouseEvent).button !== 0) { + return; + } + if (!this.enableNodeMoving) { + return; + } if (this.selectedElement && !this.shiftKeyOnMouseDown) { event.preventDefault(); this.ctm = this.svgDraw?.node.getScreenCTM(); // used to compute SVG transformations @@ -365,10 +390,17 @@ export class NetworkAreaDiagramViewer { } private handleEndDragSelectEvent(event: Event) { + // check mouse button + if ((event as MouseEvent).button !== 0) { + return; + } // check if I moved or selected an element if (this.selectedElement) { if (!this.shiftKeyOnMouseDown) { // moving node + if (!this.enableNodeMoving) { + return; + } const newPosition = this.getMousePosition(event as MouseEvent); this.completeDrag(newPosition, true); } else { From d027ccd3cab2dc42ac6733b0566584dcf0b30634 Mon Sep 17 00:00:00 2001 From: "massimo.ferraro" Date: Wed, 23 Oct 2024 18:27:48 +0200 Subject: [PATCH 8/9] Remove fix on mouse button and text node selection Signed-off-by: massimo.ferraro --- .../network-area-diagram-viewer.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts index d0075b8d..d51adb58 100644 --- a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts +++ b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts @@ -318,10 +318,6 @@ export class NetworkAreaDiagramViewer { } private handleStartDragSelectEvent(event: Event) { - // check mouse button - if ((event as MouseEvent).button !== 0) { - return; - } // check element is draggable or selectable const draggableElem = DiagramUtils.getDraggableFrom(event.target as SVGElement); if (!draggableElem) { @@ -333,10 +329,6 @@ export class NetworkAreaDiagramViewer { if (!this.shiftKeyOnMouseDown && !this.enableNodeMoving) { return; } - // avoid selecting text nodes - if (this.shiftKeyOnMouseDown && DiagramUtils.isTextNode(draggableElem as SVGGraphicsElement)) { - return; - } this.disablePanzoom(); // to avoid panning the whole SVG when moving or selecting a node // change cursor style const svg: HTMLElement = this.svgDraw?.node.firstElementChild?.parentElement; @@ -363,10 +355,6 @@ export class NetworkAreaDiagramViewer { } private handleDragEvent(event: Event) { - // check mouse button - if ((event as MouseEvent).button !== 0) { - return; - } if (!this.enableNodeMoving) { return; } @@ -390,10 +378,6 @@ export class NetworkAreaDiagramViewer { } private handleEndDragSelectEvent(event: Event) { - // check mouse button - if ((event as MouseEvent).button !== 0) { - return; - } // check if I moved or selected an element if (this.selectedElement) { if (!this.shiftKeyOnMouseDown) { From 722ac8f443505e2af9a3faba9fe886c5d71495f1 Mon Sep 17 00:00:00 2001 From: "massimo.ferraro" Date: Wed, 23 Oct 2024 18:50:11 +0200 Subject: [PATCH 9/9] Add fix on mouse button and text node selection Signed-off-by: massimo.ferraro --- .../network-area-diagram-viewer.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts index f96fbc80..2920b251 100644 --- a/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts +++ b/src/components/network-area-diagram-viewer/network-area-diagram-viewer.ts @@ -313,17 +313,25 @@ export class NetworkAreaDiagramViewer { } private handleStartDragSelectEvent(event: Event) { + // check mouse button + if ((event as MouseEvent).button !== 0) { + return; + } // check element is draggable or selectable const draggableElem = DiagramUtils.getDraggableFrom(event.target as SVGElement); if (!draggableElem) { return; } + this.shiftKeyOnMouseDown = !!(event as MouseEvent).shiftKey; + // avoid selecting text nodes + if (this.shiftKeyOnMouseDown && DiagramUtils.isTextNode(draggableElem as SVGGraphicsElement)) { + return; + } this.disablePanzoom(); // to avoid panning the whole SVG when moving or selecting a node // change cursor style const svg: HTMLElement = this.svgDraw?.node.firstElementChild?.parentElement; svg.style.cursor = 'grabbing'; // check dragging vs. selection - this.shiftKeyOnMouseDown = !!(event as MouseEvent).shiftKey; if (!this.shiftKeyOnMouseDown) { // moving node this.initializeDrag(draggableElem); @@ -345,6 +353,10 @@ export class NetworkAreaDiagramViewer { } private handleDragEvent(event: Event) { + // check mouse button + if ((event as MouseEvent).button !== 0) { + return; + } if (this.selectedElement && !this.shiftKeyOnMouseDown) { event.preventDefault(); this.ctm = this.svgDraw?.node.getScreenCTM(); // used to compute SVG transformations @@ -365,6 +377,10 @@ export class NetworkAreaDiagramViewer { } private handleEndDragSelectEvent(event: Event) { + // check mouse button + if ((event as MouseEvent).button !== 0) { + return; + } // check if I moved or selected an element if (this.selectedElement) { if (!this.shiftKeyOnMouseDown) {