diff --git a/src/main/app/src/Components/Landscape/Map/Map.css b/src/main/app/src/Components/Landscape/Map/Map.css index d87e1f3e6..b0d695740 100644 --- a/src/main/app/src/Components/Landscape/Map/Map.css +++ b/src/main/app/src/Components/Landscape/Map/Map.css @@ -1,16 +1,30 @@ - .landscapeMapContainer .map .title { fill: rgba(255, 255, 255, 0.75); } + +@media screen { + .title { + display: none; + } + .logo { + display: none; + } +} + .landscapeMapContainer .map .details { border: 1px solid #3f51b5; border-radius: 10px; background-color: white; } -.landscapeMapContainer .map .item { + +.landscapeMapContainer .map .item:hover { cursor: pointer; } +.map g.item.unselected:hover circle { + stroke: #C0C0C0; +} + .landscapeMapContainer .map g .group { fill-opacity: 0.4; stroke: #3f51b5; @@ -20,21 +34,26 @@ fill: rgba(255, 255, 255, 0.75); cursor: pointer; } + .landscapeMapContainer .map g .label rect { fill-opacity: 1; stroke-width: 0.1em; } + .landscapeMapContainer .map g .item_shortName { fill: #000; } + .landscapeMapContainer .map path { stroke-opacity: 0.8; stroke-linecap: round; stroke-linejoin: round; } + .landscapeMapContainer .ReactSVGPanZoom svg g rect { fill: transparent; } + @-o-keyframes highlightLabel { 0% { stroke-width: 5px; @@ -47,6 +66,7 @@ stroke-width: 5px; } } + @-webkit-keyframes highlightLabel { 0% { stroke-width: 5px; @@ -59,6 +79,7 @@ stroke-width: 5px; } } + @keyframes highlightLabel { 0% { stroke-width: 5px; @@ -71,13 +92,14 @@ stroke-width: 5px; } } + @-o-keyframes highlightRelation { 0% { stroke-width: 5px; stroke: #000; } 50% { - stroke-width: 40px; + stroke-width: 13; stroke: white; } to { @@ -85,13 +107,14 @@ stroke-width: 5px; } } + @-webkit-keyframes highlightRelation { 0% { stroke-width: 5px; stroke: #000; } 50% { - stroke-width: 40px; + stroke-width: 13; stroke: white; } to { @@ -99,13 +122,14 @@ stroke-width: 5px; } } + @keyframes highlightRelation { 0% { stroke-width: 5px; stroke: #000; } 50% { - stroke-width: 40px; + stroke-width: 13; stroke: white; } to { @@ -113,6 +137,7 @@ stroke-width: 5px; } } + .landscapeMapContainer .highlightLabel { /* box-shadow: 0 0 0 2px #FF4081; */ @@ -123,22 +148,36 @@ -o-animation-iteration-count: 2; animation-iteration-count: 2; } + .landscapeMapContainer .highlightRelation { /* box-shadow: 0 0 0 2px #FF4081; */ -webkit-animation: highlightRelation 1s linear; -o-animation: highlightRelation 1s linear; animation: highlightRelation 1s linear; - -webkit-animation-iteration-count: 2; - -o-animation-iteration-count: 2; - animation-iteration-count: 2; + -webkit-animation-iteration-count: 1.5; + -o-animation-iteration-count: 1.5; + animation-iteration-count: 1.5; } + .landscapeMapContainer .with-transition { z-index: 2; } + .landscapeMapContainer .with-transition svg > g { transition: transform 1s ease-out; } + .landscapeMapContainer .showHighlight { z-index: 2; } + +.landscapeMapContainer .map g.groupArea.unselected:hover polygon { + fill-opacity: 0.2 +} + +.map g.relation.unselected path:hover { + stroke: #C0C0C0; + stroke-width: 13; + stroke-opacity: 1; +} \ No newline at end of file diff --git a/src/main/java/de/bonndan/nivio/model/LandscapeFactory.java b/src/main/java/de/bonndan/nivio/model/LandscapeFactory.java index e260f158f..e39d3932b 100644 --- a/src/main/java/de/bonndan/nivio/model/LandscapeFactory.java +++ b/src/main/java/de/bonndan/nivio/model/LandscapeFactory.java @@ -83,7 +83,7 @@ public static Landscape recreate(Landscape existing, LandscapeDescription input) //overwrite some data which is not handled by resolvers builder.withContact(input.getContact()); - if (!StringUtils.isEmpty(input.getName())) { + if (StringUtils.hasLength(input.getName())) { builder.withName(input.getName()); } builder.withConfig(input.getConfig()); diff --git a/src/main/java/de/bonndan/nivio/output/map/svg/SVGDocument.java b/src/main/java/de/bonndan/nivio/output/map/svg/SVGDocument.java index 24b6d7c22..5d2eb272e 100644 --- a/src/main/java/de/bonndan/nivio/output/map/svg/SVGDocument.java +++ b/src/main/java/de/bonndan/nivio/output/map/svg/SVGDocument.java @@ -41,6 +41,11 @@ public class SVGDocument extends Component { private boolean debug = false; private HexMap hexMap; + private static final String CLASS = "class"; + private static final String WIDTH = "width"; + private static final String HEIGHT = "height"; + + public SVGDocument(@NonNull final LayoutedComponent layouted, @Nullable final Assessment assessment, @Nullable final String cssStyles) { this.layouted = Objects.requireNonNull(layouted); this.landscape = (Landscape) layouted.getComponent(); @@ -123,10 +128,10 @@ public DomContent render() { .attr("version", "1.1") .attr("xmlns", "http://www.w3.org/2000/svg") .attr("xmlns:xlink", "http://www.w3.org/1999/xlink") - .attr("width", dimension.cartesian.horMax) - .attr("height", dimension.cartesian.vertMax) + .attr(WIDTH, dimension.cartesian.horMax) + .attr(HEIGHT, dimension.cartesian.vertMax) .attr("viewBox", dimension.cartesian.asViewBox()) - .attr("class", "map") + .attr(CLASS, "map") .with(background) .with(logo, title) @@ -147,8 +152,9 @@ private DomContent getLogo(SVGDimension dimension) { .attr("xlink:href", logoUrl) .attr("x", dimension.cartesian.horMin - dimension.cartesian.padding) .attr("y", dimension.cartesian.vertMin - dimension.cartesian.padding + 80) - .attr("width", LABEL_WIDTH) - .attr("height", LABEL_WIDTH); + .attr(WIDTH, LABEL_WIDTH) + .attr(HEIGHT, LABEL_WIDTH) + .attr(CLASS, "logo"); } return logo; } @@ -157,7 +163,7 @@ private ContainerTag getTitle(SVGDimension dimension) { return SvgTagCreator.text(landscape.getName()) .attr("x", dimension.cartesian.horMin - dimension.cartesian.padding) .attr("y", dimension.cartesian.vertMin - dimension.cartesian.padding + 60) - .attr("class", "title"); + .attr(CLASS, "title"); } /** @@ -165,17 +171,15 @@ private ContainerTag getTitle(SVGDimension dimension) { */ private List getRelations(LayoutedComponent layouted) { List relations = new ArrayList<>(); - layouted.getChildren().forEach(layoutedGroup -> { - layoutedGroup.getChildren().forEach(layoutedItem -> { - Item item = (Item) layoutedItem.getComponent(); - LOGGER.debug("Adding {} relations for {}", item.getRelations().size(), item.getFullyQualifiedIdentifier()); - item.getRelations().stream() - .filter(rel -> rel.getSource().equals(item)) //do not paint twice / incoming (inverse) relations - .map(rel -> getSvgRelation(layoutedItem, item, rel)) - .filter(Objects::nonNull) - .forEach(relations::add); - }); - }); + layouted.getChildren().forEach(layoutedGroup -> layoutedGroup.getChildren().forEach(layoutedItem -> { + Item item = (Item) layoutedItem.getComponent(); + LOGGER.debug("Adding {} relations for {}", item.getRelations().size(), item.getFullyQualifiedIdentifier()); + item.getRelations().stream() + .filter(rel -> rel.getSource().equals(item)) //do not paint twice / incoming (inverse) relations + .map(rel -> getSvgRelation(layoutedItem, item, rel)) + .filter(Objects::nonNull) + .forEach(relations::add); + })); return relations; } @@ -194,5 +198,4 @@ private SVGRelation getSvgRelation(LayoutedComponent layoutedItem, Item source, public String getXML() { return render().render(); } -} - +} \ No newline at end of file diff --git a/src/test/java/de/bonndan/nivio/output/map/svg/SVGDocumentTest.java b/src/test/java/de/bonndan/nivio/output/map/svg/SVGDocumentTest.java index 8e8e28d03..03742c7e9 100644 --- a/src/test/java/de/bonndan/nivio/output/map/svg/SVGDocumentTest.java +++ b/src/test/java/de/bonndan/nivio/output/map/svg/SVGDocumentTest.java @@ -1,15 +1,25 @@ package de.bonndan.nivio.output.map.svg; +import de.bonndan.nivio.assessment.Assessment; import de.bonndan.nivio.input.http.CachedResponse; import de.bonndan.nivio.model.Landscape; import de.bonndan.nivio.output.RenderingTest; +import de.bonndan.nivio.output.layout.LayoutedComponent; +import j2html.tags.DomContent; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.mockito.stubbing.OngoingStubbing; +import org.springframework.lang.NonNull; +import org.springframework.lang.Nullable; +import org.springframework.util.StringUtils; import java.io.IOException; import java.net.URISyntaxException; import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import static org.assertj.core.api.Assertions.as; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; @@ -18,10 +28,10 @@ class SVGDocumentTest extends RenderingTest { - @BeforeEach + @BeforeEach public void setup() throws URISyntaxException { super.setup(); - } + } @Test void renderInout() throws IOException { @@ -30,6 +40,7 @@ void renderInout() throws IOException { String svg = renderLandscape(path, landscape); assertTrue(svg.contains("svg version=\"1.1\"")); assertTrue(svg.contains("class=\"title\">Input and Output")); + assertTrue(svg.contains("class=\"logo\"")); assertThat(svg).contains("Docker Compose files")); } @@ -71,4 +82,5 @@ void embedsExternalImages() throws IOException, URISyntaxException { .contains("fill=\"url(#Wm05dg==)\""); //pattern for "foo" response } + } \ No newline at end of file diff --git a/src/test/resources/example/inout.yml b/src/test/resources/example/inout.yml index 31e3aac7e..a8f830698 100644 --- a/src/test/resources/example/inout.yml +++ b/src/test/resources/example/inout.yml @@ -1,7 +1,8 @@ identifier: inout name: Input and Output description: Misuses the landscape graph to show the input and output possibilities of nivio. -icon: https://dedica.team/images/logo_orange_weiss.png +labels: + icon: https://dedica.team/images/logo_orange_weiss.png config: branding: