CustomLabelProvider.java
/**
* Copyright (c) 2025, 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
*/
package com.powsybl.nad.svg;
import com.powsybl.nad.model.*;
import com.powsybl.nad.utils.svg.SvgUtils;
import java.util.*;
/**
* Enables the configuration of content displayed in the NAD for branches and three-winding-transformers (labels, arrows direction),
* and VL info boxes (voltage levels and buses labels).
* <p>
* Customizations are defined in the constructor's map parameters.
*
* <p>
* The branchLabels map defines what will be displayed on the branches, and it is indexed by branch ID.
* The custom content is declared via the BranchLabels record: side1 and side2 are the labels displayed on the edges of a branch,
* while middle is the label displayed halfway along the branch.
* Arrow1 and arrow2 determine the direction of the arrows displayed on the edges.
*
* <p>
* The threeWtLabels map defines what will be displayed on the three-winding-transformers legs, and it is indexed by the equipment ID.
* The custom content is declared via the ThreeWtLabels record: side1, side2, and side3 are the labels to be displayed on the respective transformer's legs.
* Similarly, arrow1, arrow2, and arrow3 determine the direction of the arrows displayed on the respective transformer's legs.
*
* <p>
* The busDescriptions map is indexed by the ID of the bus (in the bus view) and allows to set a bus's label, displayed in the VL info box central section.
*
* <p>
* VlDescriptions and vlDetails maps, indexed by the voltage level ID, define the VL related content found in the VL info boxes.
* VlDescriptions data will be displayed in the VL info box top section, while vlDetails will be displayed in the bottom section.
* For each ID, the maps contain a list of strings that will be displayed sequentially, following the implicit order of the list.
*
* @author Christian Biasuzzi {@literal <christian.biasuzzi at soft.it>}
*/
public class CustomLabelProvider implements LabelProvider {
final Map<String, BranchLabels> branchLabels;
final Map<String, ThreeWtLabels> threeWtLabels;
final Map<String, String> busDescriptions;
final Map<String, List<String>> vlDescriptions;
final Map<String, List<String>> vlDetails;
public record BranchLabels(String side1, String middle, String side2, EdgeInfo.Direction arrow1, EdgeInfo.Direction arrow2) {
}
public record ThreeWtLabels(String side1, String side2, String side3, EdgeInfo.Direction arrow1, EdgeInfo.Direction arrow2, EdgeInfo.Direction arrow3) {
}
public CustomLabelProvider(Map<String, BranchLabels> branchLabels, Map<String, ThreeWtLabels> threeWtLabels,
Map<String, String> busDescriptions, Map<String, List<String>> vlDescriptions, Map<String, List<String>> vlDetails) {
this.branchLabels = Objects.requireNonNull(branchLabels);
this.threeWtLabels = Objects.requireNonNull(threeWtLabels);
this.busDescriptions = Objects.requireNonNull(busDescriptions);
this.vlDescriptions = Objects.requireNonNull(vlDescriptions);
this.vlDetails = Objects.requireNonNull(vlDetails);
}
@Override
public Optional<EdgeInfo> getEdgeInfo(Graph graph, BranchEdge edge, BranchEdge.Side side) {
BranchLabels bl = this.branchLabels.get(edge.getEquipmentId());
String label = null;
EdgeInfo.Direction arrowDirection = null;
if (bl != null) {
label = side == BranchEdge.Side.ONE ? bl.side1 : bl.side2;
arrowDirection = side == BranchEdge.Side.ONE ? bl.arrow1 : bl.arrow2;
}
return Optional.of(new EdgeInfo("Custom", arrowDirection, null, label));
}
@Override
public Optional<EdgeInfo> getEdgeInfo(Graph graph, ThreeWtEdge edge) {
ThreeWtLabels threeWtLabels1 = threeWtLabels.get(edge.getEquipmentId());
ThreeWtEdge.Side edgeSide = edge.getSide();
String labelSide = null;
EdgeInfo.Direction arrowDirection = null;
if (threeWtLabels1 != null) {
switch (edgeSide) {
case ONE -> {
labelSide = threeWtLabels1.side1;
arrowDirection = threeWtLabels1.arrow1;
}
case TWO -> {
labelSide = threeWtLabels1.side2;
arrowDirection = threeWtLabels1.arrow2;
}
case THREE -> {
labelSide = threeWtLabels1.side3;
arrowDirection = threeWtLabels1.arrow3;
}
}
}
return Optional.of(new EdgeInfo("Custom", arrowDirection, null, labelSide));
}
@Override
public String getLabel(Edge edge) {
BranchLabels bl = branchLabels.get(edge.getEquipmentId());
return (bl != null) ? bl.middle : null;
}
@Override
public String getBusDescription(BusNode busNode) {
return busDescriptions.get(busNode.getEquipmentId());
}
@Override
public List<String> getVoltageLevelDescription(VoltageLevelNode voltageLevelNode) {
return vlDescriptions.getOrDefault(voltageLevelNode.getEquipmentId(), Collections.emptyList());
}
@Override
public List<String> getVoltageLevelDetails(VoltageLevelNode vlNode) {
return vlDetails.getOrDefault(vlNode.getEquipmentId(), Collections.emptyList());
}
@Override
public String getArrowPathDIn() {
return SvgUtils.ARROW_PATH_DIN;
}
@Override
public String getArrowPathDOut() {
return SvgUtils.ARROW_PATH_DOUT;
}
}