Skip to content

Commit

Permalink
Merge branch 'main' into ied-editor
Browse files Browse the repository at this point in the history
  • Loading branch information
Flurb authored Jan 10, 2022
2 parents b16101e + dfae9b0 commit 885c536
Show file tree
Hide file tree
Showing 27 changed files with 1,654 additions and 73 deletions.
83 changes: 56 additions & 27 deletions src/editors/SingleLineDiagram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,18 @@ import {
state,
TemplateResult,
} from 'lit-element';

import panzoom from 'panzoom';

import {
compareNames,
getDescriptionAttribute,
getNameAttribute,
getPathNameAttribute,
identity,
newWizardEvent,
SCLTag
} from '../foundation.js';
import {
getAbsolutePosition,
createTerminalElement,
Expand All @@ -31,15 +41,14 @@ import {
isBusBar,
getConnectedTerminals,
} from './singlelinediagram/foundation.js';
import { isSCLNamespace } from '../schemas.js';
import { wizards } from '../wizards/wizard-library.js';
import {SingleSelectedEvent} from "@material/mwc-list/mwc-list-foundation";
import {translate} from "lit-translate";

import '@material/mwc-list/mwc-list-item';
import '@material/mwc-select';
import '@material/mwc-textfield';
import { compareNames, getDescriptionAttribute, getNameAttribute, getPathNameAttribute, identity, newWizardEvent, SCLTag } from '../foundation.js';
import { isSCLNamespace } from '../schemas.js';

/**
* Main class plugin for Single Line Diagram editor.
Expand All @@ -55,7 +64,7 @@ export default class SingleLineDiagramPlugin extends LitElement {
// Container for giving the panzoom to.
@query('#panzoom') panzoomContainer!: HTMLElement;
// The main canvas to draw everything on.
@query('#svg') svg!: SVGElement;
@query('#svg') svg!: SVGGraphicsElement;

private get substations() : Element[] {
return Array.from(this.doc.querySelectorAll(':root > Substation'))
Expand Down Expand Up @@ -156,7 +165,9 @@ export default class SingleLineDiagramPlugin extends LitElement {
* @param powerTransformerElement - The PowerTransformer to draw.
*/
private drawPowerTransformer(parentGroup: SVGElement, powerTransformerElement: Element): void {
const powerTransformerGroup = createPowerTransformerElement(powerTransformerElement);
const powerTransformerGroup = createPowerTransformerElement(powerTransformerElement,
(event: Event) => this.openEditWizard(event, powerTransformerElement!)
);
parentGroup.appendChild(powerTransformerGroup);
}

Expand All @@ -182,11 +193,11 @@ export default class SingleLineDiagramPlugin extends LitElement {
this.getVoltageLevels(substationElement)
.forEach(voltageLevelElement => {
this.getBusBars(voltageLevelElement).forEach( busbarElement => {
this.drawBusBarConnections(substationElement, substationGroup, busbarElement);
this.drawBusBarConnections(substationElement, this.svg, busbarElement);
});

this.getBays(voltageLevelElement).forEach( bayElement => {
this.drawBayConnections(substationElement, substationGroup, bayElement);
this.drawBayConnections(substationElement, this.svg, bayElement);
});
});
}
Expand Down Expand Up @@ -223,8 +234,8 @@ export default class SingleLineDiagramPlugin extends LitElement {
terminal => terminal.getAttribute('cNodeName') !== 'grounded'
).length !== 0)
.forEach(conductingEquipmentElement => {
const conductingEquipmentGroup = createConductingEquipmentElement(conductingEquipmentElement, () =>
this.openEditWizard(conductingEquipmentElement!)
const conductingEquipmentGroup = createConductingEquipmentElement(conductingEquipmentElement,
(event: Event) => this.openEditWizard(event, conductingEquipmentElement!)
);
bayGroup.appendChild(conductingEquipmentGroup);
});
Expand All @@ -239,8 +250,8 @@ export default class SingleLineDiagramPlugin extends LitElement {
this.getConnectivityNode(bayElement)
.filter(cNode => getConnectedTerminals(cNode).length > 0)
.forEach(cNode => {
const cNodegroup = createConnectivityNodeElement(cNode, () =>
this.openEditWizard(cNode)
const cNodegroup = createConnectivityNodeElement(cNode,
(event: Event) => this.openEditWizard(event, cNode)
);

bayGroup.appendChild(cNodegroup);
Expand All @@ -258,11 +269,12 @@ export default class SingleLineDiagramPlugin extends LitElement {
this.getConnectivityNode(bayElement)
.forEach(cNode => {
this.findEquipment(rootElement, getPathNameAttribute(cNode))
.forEach(element => {
const sides = getDirections(element, cNode);
.forEach(equipmentElement => {
const commonParentElement = getCommonParentElement(cNode, equipmentElement, bayElement);
const sides = getDirections(equipmentElement, cNode);

const elementsTerminalPosition = getAbsolutePositionTerminal(
element,
equipmentElement,
sides.startDirection
);

Expand All @@ -272,7 +284,7 @@ export default class SingleLineDiagramPlugin extends LitElement {
);

rootGroup
.querySelectorAll(`g[id="${identity(bayElement)}"]`)
.querySelectorAll(`g[id="${identity(commonParentElement)}"]`)
.forEach(eq =>
drawCNodeConnections(
cNodePosition,
Expand All @@ -281,18 +293,18 @@ export default class SingleLineDiagramPlugin extends LitElement {
)
);

const terminalElement = element.querySelector(
const terminalElement = equipmentElement.querySelector(
`Terminal[connectivityNode="${cNode.getAttribute('pathName')}"]`
);

const terminal = createTerminalElement(
terminalElement!,
sides.startDirection,
() => this.openEditWizard(terminalElement!)
(event: Event) => this.openEditWizard(event, terminalElement!)
);

rootGroup
.querySelectorAll(`g[id="${identity(element)}"]`)
.querySelectorAll(`g[id="${identity(equipmentElement)}"]`)
.forEach(eq => eq.appendChild(terminal));
});
});
Expand All @@ -315,7 +327,8 @@ export default class SingleLineDiagramPlugin extends LitElement {
* @param busbarElement - The Busbar Element to draw.
*/
private drawBusBar(parentElement: Element, parentGroup: SVGElement, busbarElement: Element): void {
const busBarGroup = createBusBarElement(busbarElement, getBusBarLength(parentElement));
const busBarGroup = createBusBarElement(busbarElement, getBusBarLength(parentElement),
(event: Event) => this.openEditWizard(event, busbarElement));
parentGroup.appendChild(busBarGroup);
}

Expand All @@ -331,6 +344,7 @@ export default class SingleLineDiagramPlugin extends LitElement {

this.findEquipment(rootElement, pathName)
.forEach(element => {
const parentElement = element.parentElement;
const elementPosition = getAbsolutePosition(element);

const elementsTerminalSide =
Expand All @@ -351,7 +365,7 @@ export default class SingleLineDiagramPlugin extends LitElement {
);

rootGroup
.querySelectorAll(`g[id="${identity(busbarElement)}"]`)
.querySelectorAll(`g[id="${identity(parentElement)}"]`)
.forEach(eq =>
drawBusBarRoute(
busbarTerminalPosition,
Expand All @@ -363,7 +377,7 @@ export default class SingleLineDiagramPlugin extends LitElement {
const terminal = createTerminalElement(
terminalElement!,
elementsTerminalSide,
() => this.openEditWizard(terminalElement!)
(event: Event) => this.openEditWizard(event, terminalElement!)
);

rootGroup
Expand Down Expand Up @@ -394,14 +408,29 @@ export default class SingleLineDiagramPlugin extends LitElement {
* Open an Edit wizard for an element.
* @param element - The element to show the wizard for.
*/
openEditWizard(element: Element): void {
openEditWizard(event: Event, element: Element): void {
const wizard = wizards[<SCLTag>element.tagName].edit(element);
if (wizard) this.dispatchEvent(newWizardEvent(wizard));
if (wizard) {
this.dispatchEvent(newWizardEvent(wizard));
event.stopPropagation();
}
}

firstUpdated(): void {
panzoom(this.panzoomContainer);
this.drawSubstationElements();

// Set the new size of the SVG.
const bbox = this.svg.getBBox();
this.svg.setAttribute("viewBox", (bbox.x-10)+" "+(bbox.y-10)+" "+(bbox.width+20)+" "+(bbox.height+20));
this.svg.setAttribute("width", (bbox.width+20) + "px");
this.svg.setAttribute("height",(bbox.height+20) + "px");

panzoom(this.panzoomContainer, {
zoomSpeed: 0.2,
maxZoom: 1.5,
minZoom: 0.2,
initialZoom: 0.5,
});
}

onSelect(event: SingleSelectedEvent): void {
Expand Down Expand Up @@ -465,8 +494,6 @@ export default class SingleLineDiagramPlugin extends LitElement {
<svg
xmlns="http://www.w3.org/2000/svg"
id="svg"
width="5000"
height="5000"
></svg>
</div>
</div>`;
Expand Down Expand Up @@ -507,9 +534,11 @@ export default class SingleLineDiagramPlugin extends LitElement {
pointer-events: bounding-box;
}
g[type='Busbar']:hover,
g[type='ConductingEquipment']:hover,
g[type='ConnectivityNode']:hover,
g[type='Terminal']:hover,
g[type='ConductingEquipment']:hover {
g[type='PowerTransformer']:hover,
g[type='Terminal']:hover {
outline: 2px dashed var(--mdc-theme-primary);
transition: transform 200ms linear, box-shadow 250ms linear;
}
Expand Down
31 changes: 25 additions & 6 deletions src/editors/singlelinediagram/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export interface Point {
y: number;
}

export const SCL_COORDINATES_NAMESPACE = 'http://www.iec.ch/61850/2003/SCLcoordinates';

/** Scope factor: the ConnectivityNode allocation algorithm works better with a scale factor which is bigger than 1. */
const COORDINATES_SCALE_FACTOR = 2;

Expand All @@ -18,11 +20,11 @@ const COORDINATES_SCALE_FACTOR = 2;
*/
export function getRelativeCoordinates(element: Element): Point {
const x = element.getAttributeNS(
'http://www.iec.ch/61850/2003/SCLcoordinates',
SCL_COORDINATES_NAMESPACE,
'x'
);
const y = element.getAttributeNS(
'http://www.iec.ch/61850/2003/SCLcoordinates',
SCL_COORDINATES_NAMESPACE,
'y'
);

Expand Down Expand Up @@ -89,8 +91,7 @@ export function getConnectedTerminals(element: Element): Element[] {
* - Get all elements that are connected to this Connectivity Node.
* - Extract the SCL x and y coordinates of these Connectivity Nodes and add them up.
* - Divide the final x and y numbers by the number of connected elements. This way, you get an so-called average.
* @param doc - The full SCL document to scan for connected elements.
* @param cNodePathName - The pathName of the Connectivity Node to calculate the SCL x and y coordinates.
* @param cNodeElement - The Connectivity Node to calculate the X and Y Coordinates for.
* @returns The calculated SCL x and y coordinates for this Connectivity Node.
*/
export function calculateConnectivityNodeCoordinates(
Expand All @@ -103,6 +104,7 @@ export function calculateConnectivityNodeCoordinates(
const pathName = getPathNameAttribute(cNodeElement);

let nrOfConnections = 0;
let nrOfXConnections = 0;
let totalX = 0;
let totalY = 0;

Expand All @@ -119,15 +121,32 @@ export function calculateConnectivityNodeCoordinates(

const { x, y } = getAbsoluteCoordinates(equipment);

totalX += x!;
// Only if the Element is in the same bay, we will use that X-value to calculate the location
// of the Connectivity Node. This will cause the Connectivity Node to stay with the boundaries
// of the Bay and not causing al kind of overlays between bays.
if (equipment.parentElement === cNodeElement.parentElement) {
nrOfXConnections++;
totalX += x!;
}
totalY += y!;
});

if (nrOfConnections === 0) return { x: 0, y: 0 };
if (nrOfConnections === 1) return { x: totalX + 1, y: totalY + 1 };

return {
x: Math.round(totalX / nrOfConnections),
x: Math.round(totalX / nrOfXConnections),
y: Math.round(totalY / nrOfConnections),
};
}

export function getCommonParentElement(leftElement: Element, rightElement: Element, defaultParent: Element | null): Element | null {
let leftParentElement = leftElement.parentElement
while (leftParentElement) {
if (leftParentElement.contains(rightElement)) {
return leftParentElement;
}
leftParentElement = leftParentElement.parentElement;
}
return defaultParent;
}
Loading

0 comments on commit 885c536

Please sign in to comment.