Skip to content

Commit 83f33e9

Browse files
Fixes an issue where containers could be rendered outside of their software system boundary on component views.
1 parent ee0e4c0 commit 83f33e9

File tree

7 files changed

+271
-143
lines changed

7 files changed

+271
-143
lines changed

structurizr-autolayout/src/test/java/com/structurizr/autolayout/graphviz/DOTExporterTests.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -499,19 +499,23 @@ public void test_writeComponentViewWithGroupedElements() {
499499
500500
1 [width=1.500000,height=1.000000,fixedsize=true,id=1,label="1: Box"]
501501
502-
subgraph cluster_3 {
502+
subgraph cluster_2 {
503503
margin=25
504-
subgraph "cluster_group_1" {
504+
subgraph cluster_3 {
505505
margin=25
506-
5 [width=1.500000,height=1.000000,fixedsize=true,id=5,label="5: Component 2"]
507-
}
506+
subgraph "cluster_group_1" {
507+
margin=25
508+
5 [width=1.500000,height=1.000000,fixedsize=true,id=5,label="5: Component 2"]
509+
}
508510
509-
subgraph "cluster_group_2" {
510-
margin=25
511-
6 [width=1.500000,height=1.000000,fixedsize=true,id=6,label="6: Component 3"]
511+
subgraph "cluster_group_2" {
512+
margin=25
513+
6 [width=1.500000,height=1.000000,fixedsize=true,id=6,label="6: Component 3"]
514+
}
515+
516+
4 [width=1.500000,height=1.000000,fixedsize=true,id=4,label="4: Component 1"]
512517
}
513518
514-
4 [width=1.500000,height=1.000000,fixedsize=true,id=4,label="4: Component 1"]
515519
}
516520
517521
4 -> 5 [id=7]

structurizr-export/src/main/java/com/structurizr/export/AbstractDiagramExporter.java

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -283,30 +283,38 @@ public Diagram export(ComponentView view, Integer animationStep) {
283283
IndentingWriter writer = new IndentingWriter();
284284
writeHeader(view, writer);
285285

286-
boolean elementsWritten = false;
287-
for (ElementView elementView : view.getElements()) {
288-
if (!(elementView.getElement() instanceof Component)) {
289-
writeElement(view, elementView.getElement(), writer);
290-
elementsWritten = true;
291-
}
286+
List<CustomElement> customElements = getCustomElements(view);
287+
for (CustomElement customElement : customElements) {
288+
writeElement(view, customElement, writer);
292289
}
293-
294-
if (elementsWritten) {
290+
if (!customElements.isEmpty()) {
295291
writer.writeLine();
296292
}
297293

298-
boolean includeSoftwareSystemBoundaries = "true".equals(view.getProperties().getOrDefault("structurizr.softwareSystemBoundaries", "false"));
294+
List<Person> people = getPeople(view);
295+
for (Person person : people) {
296+
writeElement(view, person, writer);
297+
}
298+
if (!people.isEmpty()) {
299+
writer.writeLine();
300+
}
299301

300-
List<Container> containers = getBoundaryContainers(view);
301-
Set<SoftwareSystem> softwareSystems = containers.stream().map(Container::getSoftwareSystem).collect(Collectors.toCollection(LinkedHashSet::new));
302+
List<SoftwareSystem> softwareSystems = getSoftwareSystems(view);
302303
for (SoftwareSystem softwareSystem : softwareSystems) {
304+
writeElement(view, softwareSystem, writer);
305+
}
306+
if (!softwareSystems.isEmpty()) {
307+
writer.writeLine();
308+
}
303309

304-
if (includeSoftwareSystemBoundaries) {
305-
startSoftwareSystemBoundary(view, softwareSystem, writer);
306-
writer.indent();
307-
}
310+
List<Container> boundaryContainers = getBoundaryContainers(view);
311+
List<Container> containers = getContainers(view);
312+
Set<SoftwareSystem> boundarySoftwareSystems = boundaryContainers.stream().map(Container::getSoftwareSystem).collect(Collectors.toCollection(LinkedHashSet::new));
313+
for (SoftwareSystem softwareSystem : boundarySoftwareSystems) {
308314

309-
for (Container container : containers) {
315+
startSoftwareSystemBoundary(view, softwareSystem, writer);
316+
317+
for (Container container : boundaryContainers) {
310318
if (container.getSoftwareSystem() == softwareSystem) {
311319
startContainerBoundary(view, container, writer);
312320

@@ -317,10 +325,13 @@ public Diagram export(ComponentView view, Integer animationStep) {
317325
}
318326
}
319327

320-
if (includeSoftwareSystemBoundaries) {
321-
endSoftwareSystemBoundary(view, writer);
322-
writer.outdent();
328+
for (Container container : containers) {
329+
if (container.getSoftwareSystem() == softwareSystem) {
330+
writeElement(view, container, writer);
331+
}
323332
}
333+
334+
endSoftwareSystemBoundary(view, writer);
324335
}
325336

326337
writeRelationships(view, writer);
@@ -330,11 +341,24 @@ public Diagram export(ComponentView view, Integer animationStep) {
330341
return createDiagram(view, writer.toString());
331342
}
332343

344+
protected List<CustomElement> getCustomElements(ModelView view) {
345+
return view.getElements().stream().map(ElementView::getElement).filter(e -> e instanceof CustomElement).map(c -> ((CustomElement) c)).distinct().sorted(Comparator.comparing(Element::getId)).collect(Collectors.toList());
346+
}
347+
348+
protected List<Person> getPeople(ModelView view) {
349+
return view.getElements().stream().map(ElementView::getElement).filter(e -> e instanceof Person).map(c -> ((Person) c)).distinct().sorted(Comparator.comparing(Element::getId)).collect(Collectors.toList());
350+
}
351+
352+
protected List<SoftwareSystem> getSoftwareSystems(ModelView view) {
353+
return view.getElements().stream().map(ElementView::getElement).filter(e -> e instanceof SoftwareSystem).map(c -> ((SoftwareSystem) c)).distinct().sorted(Comparator.comparing(Element::getId)).collect(Collectors.toList());
354+
}
355+
333356
protected List<Container> getBoundaryContainers(ModelView view) {
334-
List<Container> containers = new ArrayList<>(view.getElements().stream().map(ElementView::getElement).filter(e -> e instanceof Component).map(c -> ((Component)c).getContainer()).collect(Collectors.toSet()));
335-
containers.sort(Comparator.comparing(Element::getId));
357+
return view.getElements().stream().map(ElementView::getElement).filter(e -> e instanceof Component).map(c -> ((Component) c).getContainer()).distinct().sorted(Comparator.comparing(Element::getId)).collect(Collectors.toList());
358+
}
336359

337-
return containers;
360+
protected List<Container> getContainers(ModelView view) {
361+
return view.getElements().stream().map(ElementView::getElement).filter(e -> e instanceof Container).map(c -> ((Container) c)).distinct().sorted(Comparator.comparing(Element::getId)).collect(Collectors.toList());
338362
}
339363

340364
public Diagram export(DynamicView view) {

structurizr-export/src/main/java/com/structurizr/export/plantuml/C4PlantUMLExporter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,6 @@ protected void writeHeader(ModelView view, IndentingWriter writer) {
249249
}
250250

251251
if (!boundaryStyles.isEmpty()) {
252-
writer.writeLine();
253-
254252
for (String tagList : boundaryStyles.keySet()) {
255253
ElementStyle elementStyle = boundaryStyles.get(tagList);
256254
tagList = tagList.replaceFirst("Element,", "");
@@ -273,6 +271,8 @@ protected void writeHeader(ModelView view, IndentingWriter writer) {
273271
line = line.replace(", $borderThickness=\"1\")", ")");
274272
writer.writeLine(line);
275273
}
274+
275+
writer.writeLine();
276276
}
277277
}
278278
}

0 commit comments

Comments
 (0)