Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ public static void drawScada(Path demoResourcesDirectory) {
public static void drawFourSubstations(Path demoResourcesDirectory) {
Network network = FourSubstationsNodeBreakerFactory.create();
NetworkAreaDiagram.draw(network, demoResourcesDirectory.resolve("nad-four-substations.svg"),
getNadParametersWithDefaultLabelProvider(),
getNadParametersWithSizeAdded(),
VoltageLevelFilter.NO_FILTER);
}

Expand Down Expand Up @@ -245,6 +245,17 @@ private static NadParameters getNadParametersWithDefaultLabelProvider() {
.setLayoutFactory(new BasicForceLayoutFactory())
.setLabelProviderFactory(DefaultLabelProvider::new);
}

private static NadParameters getNadParametersWithSizeAdded() {
SvgParameters svgParameters = new SvgParameters()
.setCssLocation(SvgParameters.CssLocation.EXTERNAL_NO_IMPORT)
.setSvgWidthAndHeightAdded(true)
.setFixedHeight(600);
return new NadParameters()
.setSvgParameters(svgParameters)
.setLayoutFactory(new BasicForceLayoutFactory())
Comment thread
NathanDissoubray marked this conversation as resolved.
.setLabelProviderFactory(DefaultLabelProvider::new);
}

private static NadParameters getNadParametersWithInjectionsAdded() {
SvgParameters svgParameters = new SvgParameters()
Expand Down
2 changes: 1 addition & 1 deletion demo/src/diagram-viewers/data/nad-four-substations.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
"bottom" : 200.0
},
"insertNameDesc" : false,
"svgWidthAndHeightAdded" : false,
"svgWidthAndHeightAdded" : true,
"cssLocation" : "EXTERNAL_NO_IMPORT",
"sizeConstraint" : "FIXED_SCALE",
"sizeConstraint" : "FIXED_HEIGHT",
"fixedWidth" : -1,
"fixedHeight" : -1,
"fixedHeight" : 600,
"fixedScale" : 0.2,
"arrowShift" : 30.0,
"arrowLabelShift" : 19.0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,76 +316,78 @@ test('getRightClickableElementData', () => {
expect(elementData?.type).toBe(EdgeType[EdgeType.TWO_WINDINGS_TRANSFORMER]);
});

test('getViewBox', () => {
test('getViewBoxAndDimensions', () => {
const nodes: NodeMetadata[] = [
{
svgId: '0',
equipmentId: 'VL1',
x: -500.0,
y: 0.0,
x: -500,
y: 0,
},
{
svgId: '1',
equipmentId: 'VL2',
x: 0,
y: -500.0,
y: -500,
},
{
svgId: '2',
equipmentId: 'VL3',
x: 500.0,
y: 0.0,
x: 500,
y: 0,
},
{
svgId: '3',
equipmentId: 'VL4',
x: 0,
y: 500.0,
y: 500,
},
];
const textNodes: TextNodeMetadata[] = [
{
svgId: '0-textnode',
equipmentId: 'VL1',
vlNode: '0',
shiftX: 100.0,
shiftY: -40.0,
connectionShiftX: 100.0,
connectionShiftY: -15.0,
shiftX: 100,
shiftY: -40,
connectionShiftX: 100,
connectionShiftY: -15,
},
{
svgId: '1-textnode',
equipmentId: 'VL2',
vlNode: '1',
shiftX: 100.0,
shiftY: -40.0,
connectionShiftX: 100.0,
connectionShiftY: -15.0,
shiftX: 100,
shiftY: -40,
connectionShiftX: 100,
connectionShiftY: -15,
},
{
svgId: '2-textnode',
equipmentId: 'VL3',
vlNode: '2',
shiftX: 100.0,
shiftY: -40.0,
connectionShiftX: 100.0,
connectionShiftY: -15.0,
shiftX: 100,
shiftY: -40,
connectionShiftX: 100,
connectionShiftY: -15,
},
{
svgId: '3-textnode',
equipmentId: 'VL4',
vlNode: '3',
shiftX: 100.0,
shiftY: -40.0,
connectionShiftX: 100.0,
connectionShiftY: -15.0,
shiftX: 100,
shiftY: -40,
connectionShiftX: 100,
connectionShiftY: -15,
},
];
const viewBox = MetadataUtils.getViewBox(nodes, textNodes, new SvgParameters(undefined));
expect(viewBox.x).toBe(-700);
expect(viewBox.y).toBe(-740);
expect(viewBox.width).toBe(1700);
expect(viewBox.height).toBe(1500);
const viewBoxAndDimensions = MetadataUtils.getViewBoxAndDimensions(nodes, textNodes, new SvgParameters(undefined));
expect(viewBoxAndDimensions.viewbox.x).toBe(-700);
expect(viewBoxAndDimensions.viewbox.y).toBe(-740);
expect(viewBoxAndDimensions.viewbox.width).toBe(1700);
expect(viewBoxAndDimensions.viewbox.height).toBe(1500);
expect(viewBoxAndDimensions.width).toBe(340);
expect(viewBoxAndDimensions.height).toBe(300);
Comment thread
NathanDissoubray marked this conversation as resolved.
});

test('getBendableLines', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import {
PointMetadata,
TextNodeMetadata,
} from './diagram-metadata';
import { SvgParameters } from './svg-parameters';
import { SizeConstraintEnum, SvgParameters } from './svg-parameters';
import { getDistance, getPointAtDistance, getVoltageLevelCircleRadius, round } from './diagram-utils';
import { EdgeType, ElementData, ElementType, NodeMove, NodeRadius, NodeType, ViewBox } from './diagram-types';
import { Dimensions, EdgeType, ElementData, ElementType, NodeMove, NodeRadius, NodeType } from './diagram-types';

const TEXT_BOX_WIDTH_DEFAULT = 200;
const TEXT_BOX_HEIGHT_DEFAULT = 100;
Expand Down Expand Up @@ -221,12 +221,12 @@ export function getRightClickableElementData(

// get view box computed starting from node and text positions
// defined in diagram metadata
export function getViewBox(
export function getViewBoxAndDimensions(
nodes: NodeMetadata[] | undefined,
textNodes: TextNodeMetadata[] | undefined,
svgParameters: SvgParameters,
textBoxSize?: { width: number; height: number }
): ViewBox {
): Dimensions {
Comment thread
NathanDissoubray marked this conversation as resolved.
const size = { minX: Number.MAX_VALUE, maxX: -Number.MAX_VALUE, minY: Number.MAX_VALUE, maxY: -Number.MAX_VALUE };
const nodesMap: Map<string, NodeMetadata> = new Map<string, NodeMetadata>();
nodes?.forEach((node) => {
Expand All @@ -248,18 +248,36 @@ export function getViewBox(
);
}
});
const width =
size.maxX - size.minX + svgParameters.getDiagramPadding().left + svgParameters.getDiagramPadding().right;
const height =
size.maxY - size.minY + svgParameters.getDiagramPadding().top + svgParameters.getDiagramPadding().bottom;
const scale = getScale(width, height, svgParameters);
return {
x: round(size.minX - svgParameters.getDiagramPadding().left),
y: round(size.minY - svgParameters.getDiagramPadding().top),
width: round(
size.maxX - size.minX + svgParameters.getDiagramPadding().left + svgParameters.getDiagramPadding().right
),
height: round(
size.maxY - size.minY + svgParameters.getDiagramPadding().top + svgParameters.getDiagramPadding().bottom
),
width: round(width * scale),
height: round(height * scale),
viewbox: {
x: round(size.minX - svgParameters.getDiagramPadding().left),
y: round(size.minY - svgParameters.getDiagramPadding().top),
width: round(width),
height: round(height),
},
};
}

function getScale(width: number, height: number, svgParameters: SvgParameters): number {
switch (svgParameters.getSizeConstraint()) {
case SizeConstraintEnum.FIXED_WIDTH:
return svgParameters.getFixedWidth() / width;
case SizeConstraintEnum.FIXED_HEIGHT:
return svgParameters.getFixedHeight() / height;
case SizeConstraintEnum.FIXED_SCALE:
return svgParameters.getFixedScale();
default:
return 1;
}
}

// get inner and outer radius of bus node and radius of voltage level
export function getNodeRadius(
busNode: BusNodeMetadata | undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2581,11 +2581,11 @@ export class NetworkAreaDiagramViewer {
}

public zoomToFit() {
const viewBox = MetadataUtils.getViewBox(
const viewBox = MetadataUtils.getViewBoxAndDimensions(
this.diagramMetadata?.nodes,
this.diagramMetadata?.textNodes,
this.svgParameters
);
).viewbox;
this.svgDraw?.viewbox(viewBox.x, viewBox.y, viewBox.width, viewBox.height);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ const CssLocationEnumMapping: { [key: string]: CssLocationEnum } = {
EXTERNAL_NO_IMPORT: CssLocationEnum.EXTERNAL_NO_IMPORT,
};

export enum SizeConstraintEnum {
NONE,
FIXED_SCALE,
FIXED_WIDTH,
FIXED_HEIGHT,
}

const SizeConstraintEnumMapping: { [key: string]: SizeConstraintEnum } = {
NONE: SizeConstraintEnum.NONE,
FIXED_SCALE: SizeConstraintEnum.FIXED_SCALE,
FIXED_WIDTH: SizeConstraintEnum.FIXED_WIDTH,
FIXED_HEIGHT: SizeConstraintEnum.FIXED_HEIGHT,
};

export class SvgParameters {
static readonly VOLTAGE_LEVEL_CIRCLE_RADIUS_DEFAULT = 30;
static readonly INTER_ANNULUS_SPACE_DEFAULT = 5;
Expand Down Expand Up @@ -73,6 +87,11 @@ export class SvgParameters {
static readonly LOOP_EDGE_APERTURE_DEFAULT = 60;
static readonly LOOP_DISTANCE_DEFAULT = 120;
static readonly LOOP_CONTROL_DISTANCE_DEFAULT = 40;
static readonly SIZE_CONSTRAINT_DEFAULT = SizeConstraintEnum.FIXED_SCALE;
static readonly FIXED_WIDTH_DEFAULT = -1;
static readonly FIXED_HEIGHT_DEFAULT = -1;
static readonly FIXED_SCALE_DEFAULT = 0.2;
static readonly SVG_WIDTH_AND_HEIGHT_ADDED_DEFAULT = false;

svgParametersMetadata: SvgParametersMetadata | undefined;

Expand Down Expand Up @@ -203,4 +222,26 @@ export class SvgParameters {
public getLoopControlDistance(): number {
return this.svgParametersMetadata?.loopControlDistance ?? SvgParameters.LOOP_CONTROL_DISTANCE_DEFAULT;
}

public getSizeConstraint(): SizeConstraintEnum {
return this.svgParametersMetadata?.sizeConstraint
? SizeConstraintEnumMapping[this.svgParametersMetadata?.sizeConstraint]
: SvgParameters.SIZE_CONSTRAINT_DEFAULT;
}

public getFixedWidth(): number {
return this.svgParametersMetadata?.fixedWidth ?? SvgParameters.FIXED_WIDTH_DEFAULT;
}

public getFixedHeight(): number {
return this.svgParametersMetadata?.fixedHeight ?? SvgParameters.FIXED_HEIGHT_DEFAULT;
}

public getFixedScale(): number {
return this.svgParametersMetadata?.fixedScale ?? SvgParameters.FIXED_SCALE_DEFAULT;
}

public getSvgWidthAndHeightAdded(): boolean {
return this.svgParametersMetadata?.svgWidthAndHeightAdded ?? SvgParameters.SVG_WIDTH_AND_HEIGHT_ADDED_DEFAULT;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import '../../../../global.d.ts';
import IEE14CdfNetworkMetadata from '../resources/test-data/nad-ieee14cdf-solved_metadata.json';
import FourSubstationsNetworkCustomStyleMetadata from '../resources/test-data/nad-four-substations_custom_metadata.json';
import FourSubstationsNetworkMetadata from '../resources/test-data/nad-four-substations_metadata.json';

import { SvgWriter } from './svg-writer';
import { getSvgFromFile } from './test-utils';
Expand All @@ -24,3 +25,9 @@ test('testFourSubstationsNetworkCustomStyle', () => {
const expected = getSvgFromFile('../resources/test-data/nad-four-substations_custom.svg');
expect(actual).toEqualSvg(expected, { epsilon: 0.1 });
});

test('testFourSubstationsNetwork', () => {
const actual = new SvgWriter(FourSubstationsNetworkMetadata).getSvg({ width: 0, height: 0 });
const expected = getSvgFromFile('../resources/test-data/nad-four-substations.svg');
expect(actual).toEqualSvg(expected, { epsilon: 0.1 });
});
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,25 @@ export class SvgWriter {

private getSvgRootElement(textBoxSize?: { width: number; height: number }): SVGSVGElement {
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
const viewBox = MetadataUtils.getViewBox(
const viewBoxAndDimensions = MetadataUtils.getViewBoxAndDimensions(
this.diagramMetadata.nodes,
this.diagramMetadata.textNodes,
this.svgParameters,
textBoxSize
);
svg.setAttribute('viewBox', [viewBox.x, viewBox.y, viewBox.width, viewBox.height].join(' '));
svg.setAttribute(
'viewBox',
[
viewBoxAndDimensions.viewbox.x,
viewBoxAndDimensions.viewbox.y,
viewBoxAndDimensions.viewbox.width,
viewBoxAndDimensions.viewbox.height,
].join(' ')
);
if (this.svgParameters.getSvgWidthAndHeightAdded()) {
svg.setAttribute('width', viewBoxAndDimensions.width + '');
svg.setAttribute('height', viewBoxAndDimensions.height + '');
}
return svg;
}

Expand Down
Loading
Loading