Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix topological style #445

Merged
merged 6 commits into from
Nov 17, 2022
Merged
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 @@ -30,7 +30,7 @@ public class SvgParameters {
private double nodeHollowWidth = 15;
private double edgesForkLength = 80;
private double edgesForkAperture = Math.toRadians(60);
private double edgeStartShift = 2;
private double edgeStartShift = 0;
private double unknownBusNodeExtraRadius = 10;
private double loopDistance = 120;
private double loopEdgesAperture = Math.toRadians(60);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,23 @@
package com.powsybl.nad.svg.iidm;

import com.powsybl.commons.config.BaseVoltagesConfig;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.Bus;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.Terminal;
import com.powsybl.nad.model.BusNode;
import com.powsybl.nad.model.Node;
import com.powsybl.nad.utils.iidm.IidmUtils;

import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

/**
* @author Florian Dupuy <florian.dupuy at rte-france.com>
*/
public class TopologicalStyleProvider extends AbstractVoltageStyleProvider {

private final Map<String, String> styleMap = new HashMap<>();
private final Map<String, Integer> baseVoltagesCounter = new HashMap<>();
public static final String LINE_STYLE_SUFFIX = "-line";

public TopologicalStyleProvider(Network network) {
super(network);
Expand All @@ -44,63 +47,18 @@ public List<String> getNodeStyleClasses(Node node) {
public List<String> getNodeStyleClasses(BusNode busNode) {
List<String> styles = new ArrayList<>(super.getNodeStyleClasses(busNode));
Bus b = network.getBusView().getBus(busNode.getEquipmentId());
getNodeTopologicalStyle(b).ifPresent(styles::add);
getBaseVoltageStyle(b.getVoltageLevel().getNominalV())
.map(baseVoltageStyle -> baseVoltageStyle + "-" + busNode.getIndex())
.ifPresent(styles::add);
return styles;
}

private Optional<String> getNodeTopologicalStyle(Bus b) {
if (b == null) {
return Optional.empty();
}
if (styleMap.containsKey(b.getId())) {
return Optional.ofNullable(styleMap.get(b.getId()));
}
return getBaseVoltageStyle(b.getVoltageLevel().getNominalV())
.map(baseVoltageStyle -> fillStyleMap(baseVoltageStyle, b));
}

private String fillStyleMap(String style, Bus bus) {
Collection<Bus> connectedBuses = getConnectedBuses(bus);
String topologicalStyle = createNewTopologicalStyle(style);
connectedBuses.forEach(b -> styleMap.put(b.getId(), topologicalStyle));
return topologicalStyle;
}

private Collection<Bus> getConnectedBuses(Bus bus) {
Set<Bus> visitedBuses = new HashSet<>();
findConnectedBuses(bus, visitedBuses);
return visitedBuses;
}

private String createNewTopologicalStyle(String style) {
Integer baseVoltageIndex = baseVoltagesCounter.compute(style, (k, v) -> v == null ? 0 : v + 1);
return style + "-" + baseVoltageIndex;
}

private void findConnectedBuses(Bus bus, Set<Bus> visitedBus) {
if (visitedBus.contains(bus)) {
return;
}
visitedBus.add(bus);
bus.visitConnectedEquipments(new DefaultTopologyVisitor() {
@Override
public void visitLine(Line line, Branch.Side side) {
Terminal t = line.getTerminal(IidmUtils.getOpposite(side));
Bus otherBus = t.getBusView().getBus();
if (otherBus != null && !visitedBus.contains(otherBus)) {
findConnectedBuses(otherBus, visitedBus);
}
}
});
}

@Override
protected Optional<String> getBaseVoltageStyle(Terminal terminal) {
if (terminal == null) {
return Optional.empty();
}
return terminal.isConnected()
? getNodeTopologicalStyle(terminal.getBusView().getBus())
: getNodeTopologicalStyle(terminal.getBusView().getConnectableBus());
return getBaseVoltageStyle(terminal.getVoltageLevel().getNominalV())
.map(baseVoltageStyle -> baseVoltageStyle + LINE_STYLE_SUFFIX);
}
}
130 changes: 65 additions & 65 deletions network-area-diagram/src/main/resources/topologicalStyle.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,76 +17,76 @@
.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-0 {--nad-vl-color: #afb42b}
.nad-vl0to30-1 {--nad-vl-color: #e6ee9c}
.nad-vl0to30-2 {--nad-vl-color: #d4e157}
.nad-vl0to30-3 {--nad-vl-color: #827717}
.nad-vl0to30-4 {--nad-vl-color: #c0ca33}
.nad-vl0to30-5 {--nad-vl-color: #f0fc83}
.nad-vl0to30-6 {--nad-vl-color: #9e9d24}
.nad-vl0to30-7 {--nad-vl-color: #cddc39}
.nad-vl0to30-8 {--nad-vl-color: #dce775}
.nad-vl0to30-9 {--nad-vl-color: #ddfc88}
.nad-vl30to50-0 {--nad-vl-color: #ef9a9a}
.nad-vl0to30-line {--nad-vl-color: #afb42b}
.nad-vl0to30-0 {--nad-vl-color: #827717}
.nad-vl0to30-1 {--nad-vl-color: #d4e157}
.nad-vl0to30-2 {--nad-vl-color: #e6ee9c}
.nad-vl0to30-3 {--nad-vl-color: #c0ca33}
.nad-vl0to30-4 {--nad-vl-color: #f0fc83}
.nad-vl0to30-5 {--nad-vl-color: #9e9d24}
.nad-vl0to30-6 {--nad-vl-color: #cddc39}
.nad-vl0to30-7 {--nad-vl-color: #dce775}
.nad-vl0to30-8 {--nad-vl-color: #ddfc88}
.nad-vl30to50-line {--nad-vl-color: #ef9a9a}
.nad-vl30to50-0 {--nad-vl-color: #c2185b}
.nad-vl30to50-1 {--nad-vl-color: #f06292}
.nad-vl30to50-2 {--nad-vl-color: #d81b60}
.nad-vl30to50-3 {--nad-vl-color: #c2185b}
.nad-vl30to50-4 {--nad-vl-color: #ec407a}
.nad-vl30to50-5 {--nad-vl-color: #880e4f}
.nad-vl30to50-6 {--nad-vl-color: #ad1457}
.nad-vl30to50-7 {--nad-vl-color: #e91e63}
.nad-vl30to50-8 {--nad-vl-color: #f48fb1}
.nad-vl30to50-9 {--nad-vl-color: #f8bbd0}
.nad-vl50to70-0 {--nad-vl-color: #9c27b0}
.nad-vl50to70-1 {--nad-vl-color: #512da8}
.nad-vl50to70-2 {--nad-vl-color: #ba68c8}
.nad-vl50to70-3 {--nad-vl-color: #7b1fa2}
.nad-vl50to70-4 {--nad-vl-color: #ab47bc}
.nad-vl50to70-5 {--nad-vl-color: #e1bee7}
.nad-vl50to70-6 {--nad-vl-color: #6a1b9a}
.nad-vl50to70-7 {--nad-vl-color: #4a148c}
.nad-vl50to70-8 {--nad-vl-color: #ce93d8}
.nad-vl50to70-9 {--nad-vl-color: #9575cd}
.nad-vl70to120-0 {--nad-vl-color: #e65100}
.nad-vl30to50-3 {--nad-vl-color: #ec407a}
.nad-vl30to50-4 {--nad-vl-color: #880e4f}
.nad-vl30to50-5 {--nad-vl-color: #ad1457}
.nad-vl30to50-6 {--nad-vl-color: #e91e63}
.nad-vl30to50-7 {--nad-vl-color: #f48fb1}
.nad-vl30to50-8 {--nad-vl-color: #f8bbd0}
.nad-vl50to70-line {--nad-vl-color: #9c27b0}
.nad-vl50to70-0 {--nad-vl-color: #7b1fa2}
.nad-vl50to70-1 {--nad-vl-color: #ba68c8}
.nad-vl50to70-2 {--nad-vl-color: #512da8}
.nad-vl50to70-3 {--nad-vl-color: #ab47bc}
.nad-vl50to70-4 {--nad-vl-color: #e1bee7}
.nad-vl50to70-5 {--nad-vl-color: #6a1b9a}
.nad-vl50to70-6 {--nad-vl-color: #4a148c}
.nad-vl50to70-7 {--nad-vl-color: #ce93d8}
.nad-vl50to70-8 {--nad-vl-color: #9575cd}
.nad-vl70to120-line {--nad-vl-color: #e65100}
.nad-vl70to120-0 {--nad-vl-color: #fb8c00}
.nad-vl70to120-1 {--nad-vl-color: #ffb74d}
.nad-vl70to120-2 {--nad-vl-color: #fb8c00}
.nad-vl70to120-3 {--nad-vl-color: #f57c00}
.nad-vl70to120-4 {--nad-vl-color: #ffa726}
.nad-vl70to120-5 {--nad-vl-color: #ffe0b2}
.nad-vl70to120-6 {--nad-vl-color: #ef6c00}
.nad-vl70to120-7 {--nad-vl-color: #ff9800}
.nad-vl70to120-8 {--nad-vl-color: #ffcc80}
.nad-vl70to120-9 {--nad-vl-color: #fff3e0}
.nad-vl120to180-0 {--nad-vl-color: #00ACC1}
.nad-vl120to180-1 {--nad-vl-color: #b3e5fc}
.nad-vl120to180-2 {--nad-vl-color: #01579b}
.nad-vl120to180-3 {--nad-vl-color: #4fc3f7}
.nad-vl120to180-4 {--nad-vl-color: #039be5}
.nad-vl70to120-2 {--nad-vl-color: #f57c00}
.nad-vl70to120-3 {--nad-vl-color: #ffa726}
.nad-vl70to120-4 {--nad-vl-color: #ffe0b2}
.nad-vl70to120-5 {--nad-vl-color: #ef6c00}
.nad-vl70to120-6 {--nad-vl-color: #ff9800}
.nad-vl70to120-7 {--nad-vl-color: #ffcc80}
.nad-vl70to120-8 {--nad-vl-color: #fff3e0}
.nad-vl120to180-line {--nad-vl-color: #00ACC1}
.nad-vl120to180-0 {--nad-vl-color: #4fc3f7}
.nad-vl120to180-1 {--nad-vl-color: #01579b}
.nad-vl120to180-2 {--nad-vl-color: #b3e5fc}
.nad-vl120to180-3 {--nad-vl-color: #039be5}
.nad-vl120to180-4 {--nad-vl-color: #81d4fa}
.nad-vl120to180-5 {--nad-vl-color: #0288d1}
.nad-vl120to180-6 {--nad-vl-color: #29b6f6}
.nad-vl120to180-7 {--nad-vl-color: #81d4fa}
.nad-vl120to180-8 {--nad-vl-color: #0277bd}
.nad-vl120to180-9 {--nad-vl-color: #03a9f4}
.nad-vl180to300-0 {--nad-vl-color: #2e7d32}
.nad-vl180to300-1 {--nad-vl-color: #c8e6c9}
.nad-vl180to300-2 {--nad-vl-color: #558b2f}
.nad-vl180to300-3 {--nad-vl-color: #81c784}
.nad-vl180to300-4 {--nad-vl-color: #43a047}
.nad-vl180to300-5 {--nad-vl-color: #a5d6a7}
.nad-vl180to300-6 {--nad-vl-color: #388e3c}
.nad-vl180to300-7 {--nad-vl-color: #66bb6a}
.nad-vl180to300-8 {--nad-vl-color: #1b5e20}
.nad-vl180to300-9 {--nad-vl-color: #4caf50}
.nad-vl300to500-0 {--nad-vl-color: #d32f2f}
.nad-vl300to500-1 {--nad-vl-color: #ffcdd2}
.nad-vl300to500-2 {--nad-vl-color: #e57373}
.nad-vl300to500-3 {--nad-vl-color: #ff8a80}
.nad-vl300to500-4 {--nad-vl-color: #b71c1c}
.nad-vl300to500-5 {--nad-vl-color: #ef5350}
.nad-vl300to500-6 {--nad-vl-color: #e53935}
.nad-vl300to500-7 {--nad-vl-color: #ef9a9a}
.nad-vl300to500-8 {--nad-vl-color: #f44336}
.nad-vl300to500-9 {--nad-vl-color: #c62828}
.nad-vl120to180-7 {--nad-vl-color: #0277bd}
.nad-vl120to180-8 {--nad-vl-color: #03a9f4}
.nad-vl180to300-line {--nad-vl-color: #2e7d32}
.nad-vl180to300-0 {--nad-vl-color: #81c784}
.nad-vl180to300-1 {--nad-vl-color: #558b2f}
.nad-vl180to300-2 {--nad-vl-color: #c8e6c9}
.nad-vl180to300-3 {--nad-vl-color: #43a047}
.nad-vl180to300-4 {--nad-vl-color: #a5d6a7}
.nad-vl180to300-5 {--nad-vl-color: #388e3c}
.nad-vl180to300-6 {--nad-vl-color: #66bb6a}
.nad-vl180to300-7 {--nad-vl-color: #1b5e20}
.nad-vl180to300-8 {--nad-vl-color: #4caf50}
.nad-vl300to500-line {--nad-vl-color: #d32f2f}
.nad-vl300to500-0 {--nad-vl-color: #ef5350}
.nad-vl300to500-1 {--nad-vl-color: #ef9a9a}
.nad-vl300to500-2 {--nad-vl-color: #b71c1c}
.nad-vl300to500-3 {--nad-vl-color: #e57373}
.nad-vl300to500-4 {--nad-vl-color: #e53935}
.nad-vl300to500-5 {--nad-vl-color: #ff8a80}
.nad-vl300to500-6 {--nad-vl-color: #f44336}
.nad-vl300to500-7 {--nad-vl-color: #ffcdd2}
.nad-vl300to500-8 {--nad-vl-color: #c62828}
.nad-branch-edges .nad-overload .nad-edge-path {animation: line-blink 3s infinite}
.nad-vl-nodes .nad-overvoltage {animation: node-over-blink 3s infinite}
.nad-vl-nodes .nad-undervoltage {animation: node-under-blink 3s infinite}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ public void setup() {
setSvgParameters(new SvgParameters()
.setInsertNameDesc(true)
.setSvgWidthAndHeightAdded(true)
.setFixedWidth(800));
.setFixedWidth(800)
.setEdgeStartShift(2));
}

@Override
Expand Down Expand Up @@ -98,27 +99,6 @@ public void testIEEE24() {
assertEquals(toString("/IEEE_24_bus.svg"), generateSvgString(network, "/IEEE_24_bus.svg"));
}

@Test
public void testEurope() {
Network network = Network.read("simple-eu.uct", getClass().getResourceAsStream("/simple-eu.uct"));
LoadFlow.run(network);
assertEquals(toString("/simple-eu.svg"), generateSvgString(network, "/simple-eu.svg"));
}

@Test
public void testEuropeLoopAperture80() {
Network network = Network.read("simple-eu.uct", getClass().getResourceAsStream("/simple-eu.uct"));
getSvgParameters().setLoopEdgesAperture(80);
assertEquals(toString("/simple-eu-loop80.svg"), generateSvgString(network, "/simple-eu-loop80.svg"));
}

@Test
public void testEuropeLoopAperture100() {
Network network = Network.read("simple-eu.uct", getClass().getResourceAsStream("/simple-eu.uct"));
getSvgParameters().setLoopEdgesAperture(100);
assertEquals(toString("/simple-eu-loop100.svg"), generateSvgString(network, "/simple-eu-loop100.svg"));
}

@Test
public void testHvdc() {
Network network = FourSubstationsNodeBreakerFactory.create();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import com.powsybl.ieeecdf.converter.IeeeCdfNetworkFactory;
import com.powsybl.iidm.network.Network;
import com.powsybl.loadflow.LoadFlow;
import com.powsybl.nad.AbstractTest;
import com.powsybl.nad.build.iidm.VoltageLevelFilter;
import com.powsybl.nad.layout.LayoutParameters;
Expand Down Expand Up @@ -69,4 +70,25 @@ public void testIEEE118PartialNonConnectedGraph() {
VoltageLevelFilter vlDepthFilter = VoltageLevelFilter.createVoltageLevelsDepthFilter(network, Arrays.asList("VL32", "VL38"), 1);
assertEquals(toString("/IEEE_118_bus_partial_non_connected.svg"), generateSvgString(network, vlDepthFilter, "/IEEE_118_bus_partial_non_connected.svg"));
}

@Test
public void testEurope() {
Network network = Network.read("simple-eu.uct", getClass().getResourceAsStream("/simple-eu.uct"));
LoadFlow.run(network);
assertEquals(toString("/simple-eu.svg"), generateSvgString(network, "/simple-eu.svg"));
}

@Test
public void testEuropeLoopAperture80() {
Network network = Network.read("simple-eu.uct", getClass().getResourceAsStream("/simple-eu.uct"));
getSvgParameters().setLoopEdgesAperture(80);
assertEquals(toString("/simple-eu-loop80.svg"), generateSvgString(network, "/simple-eu-loop80.svg"));
}

@Test
public void testEuropeLoopAperture100() {
Network network = Network.read("simple-eu.uct", getClass().getResourceAsStream("/simple-eu.uct"));
getSvgParameters().setLoopEdgesAperture(100);
assertEquals(toString("/simple-eu-loop100.svg"), generateSvgString(network, "/simple-eu-loop100.svg"));
}
}
20 changes: 10 additions & 10 deletions network-area-diagram/src/test/resources/3wt.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading