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

Feature Request: Support different views/selective renderings of the same model (support C4Model approach) #711

Closed
kmindi opened this issue Jan 23, 2023 · 9 comments · Fixed by #2394

Comments

@kmindi
Copy link

kmindi commented Jan 23, 2023

Like explained and shown for example here: https://www.workingsoftware.dev/software-architecture-documentation-the-ultimate-guide/ it would be very beneficial for D2 to have a feature to create different views of a diagram based on the same model.

This does not mean that the SVG or other available formats need to have all the views within one rendering/export.
Basic fullfillment of this feature would be to have command line options to generate different renderings/views based on the same input/d2 file.

E.g. like --tags network,security --depth-max 3 --root-node frontend will select all nodes and edges that have a tag with network and or security, as well as only render nodes until 3 nested nodes below the node frontend and does not show nodes nested below depth 3 as well as no nodes above frontend (of course also possible without specifying --root-node, aslo possible to use only --root-node without --tags and --depth to show all below that node).

If you have a good approach to provide this as some kind of annotations in the d2 file to generate multiple outputs right-away that would of course also be interesting.

See also https://c4model.com/.

Especially useful for big models/diagrams.

@cyborg-ts cyborg-ts added this to D2 Jan 23, 2023
@alixander
Copy link
Collaborator

have a feature to create different views of a diagram based on the same model.

work on this is almost complete, should be in next release!

@nightscape
Copy link

@alixander is the work you're doing here generalizable to other models as well?
I'm thinking of Archimate which also allows visualizing the same objects in different views.

@alixander
Copy link
Collaborator

alixander commented Feb 16, 2023

@nightscape Yes. the work in the compiler is actually complete, but we're trying to make it accessible now through interfaces. #825

For example, C4 uses web viewers and idk what Archimate uses but for these diagrams with different views, a single regular SVG or img won't suffice.

We're working on exports in:

@kmindi
Copy link
Author

kmindi commented Feb 16, 2023

I would also have understood this feature request to not offer all possible views in one generated svg/file!

But to allow specifying maybe build commands/options which specify/select which view should be generated (the default still being that all nodes and edges and hiearchy layers are generated).

E.g. like --tags network,security --depth 3 which will select all nodes and edges that have a tag with network and or security, as well as only goes until 3 nested nodes and does not show nodes nested below that depth

@kmindi kmindi changed the title Feature Request: Support different views/selective renderings of the same model (support C4Model apporach) Feature Request: Support different views/selective renderings of the same model (support C4Model approach) Feb 17, 2023
@orange-buffalo
Copy link

We are also interested in this feature - using a single model and rendering different sub-sets of it.

Structurizr has support for this via views. For this reason, we are actually defining our model as Structurizr workspace with views, and then have a custom exporter to convert it to multiple D2s, which are then rendered with TALA for superior layout. Having this built-in into D2 would be so much better experience.

@alixander
Copy link
Collaborator

@orange-buffalo this should be entirely doable within d2. We just haven't documented all the different flavors of it (though here's one: https://d2lang.com/tour/model-view/). Can you describe your use case?

@orange-buffalo
Copy link

Sure, the use case is best described by C4 model and its "System Context diagram", "Container diagram" etc, all created from a single source.

But I could also try to provide a simplified example of what we are looking for.

Having this D2 model:

user
softwareSystem: {
  serviceA
  serviceB
  serviceC
  serviceD

  serviceA -> serviceB
  serviceA -> serviceD
  serviceC -> serviceB
}
externalSystem
user -> softwareSystem
softwareSystem -> externalSystem

We currently can only get this output - with all elements in it:
image

What we want to achieve is having the same model, be able to generate diagrams of different level of detalization, e.g.

  • System Context diagram
    image

  • Container diagram
    image

  • And deeper.

  • And specific sub-sets (e.g. only serviceA,B,C and their connections).

As suggested in the issue description, this could be done via CLI keys that configure the included elements. Another alternative would be to make views the first-class citizen of D2 (similarly to steps, layers and scenarios):

user
softwareSystem: {
  serviceA
  serviceB
  serviceC
  serviceD

  serviceA -> serviceB
  serviceA -> serviceD
  serviceC -> serviceB
}
externalSystem
user -> softwareSystem
softwareSystem -> externalSystem

views: {
  <name> {
    include ->softwareSystem->    // includes the element and all incoming and outgoing connections
    include softwareSystem.*         // includes the element and all children
    tags "<tag1>, <tag2>"            // by tag
    // other options
  }
}

Which we could then render into one of the formats with some new CLI options like --view=<name>.

@alixander
Copy link
Collaborator

alixander commented Oct 16, 2024

tracking individual tasks to enable this here:

@alixander
Copy link
Collaborator

alixander commented Feb 28, 2025

Here's how it'll work

# Models
user.style.fill: blue
softwareSystem: {
  serviceA.class: ok
  serviceB
  serviceC.class: ok
  serviceD

  serviceA -> serviceB
  serviceA -> serviceD
  serviceC -> serviceB
}
externalSystem
user -> softwareSystem
softwareSystem -> externalSystem

# Clear models
**: suspend
(** -> **)[*]: suspend

# Include all top-level objects
*: unsuspend
# Include all objects with a certain class
**: unsuspend {
  &class: ok
}
# Include all connections/objects connected to an object
(** -> softwareSystem.serviceA)[*]: unsuspend
(softwareSystem.serviceA -> **)[*]: unsuspend

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

4 participants