Visualize your SAP CDS Virtual Data Model (VDM) hierarchies with ease.
The VDM Diagram Generator is an ABAP tool designed to recursively discover and visualize CDS View relationships. Supporting ASSOCIATIONS, COMPOSITIONS, and INHERITANCE, this tool parses your metadata via the XCO Framework to generate syntax for your preferred rendering engine. Currently it generates a String Table that you will need to export to a file.
While the core engine generates raw syntax strings, we have introduced a Full-Stack SAP Fiori Application to make visualization instant and interactive. Activation of the OData V4 Service Binding ZUI_VDM_DIAGRAM_O4 is required.
Repository: abap-vdm-cds-diagram-ui
- Live Preview: Instantly render PlantUML, Mermaid.js, and Graphviz (WASM) diagrams directly within your browser.
- NEW: The Cytoscape engine transforms the diagram from a static map into a "Discovery Environment."
- Interactivity: Drag, zoom, and pan across complex VDM webs with automatic aspect-ratio protection.
- Export Center: One-click downloads for SVG, high-resolution PNG (rasterized at 2x DPI), or raw Source Code.
- Variant Management: Save filtering and layout configurations to local cache for instant re-selection.
- Contextual Help: Integrated help system explains every technical toggle and relationship mode.
- Preview: https://www.youtube.com/watch?v=FRI9ZK2F20w
The generator has been completely re-architected to support a multi-engine rendering model.
- Four Output Formats: Natively supports PlantUML, GraphViz, Mermaid.js, and D2.
- Universal Configuration: A single rendering configuration object controls layout, routing, and themes across all engines natively. Method pattern.
- Primary Support: SAP S/4HANA 2023 and higher
- Secondary support for ABAP Cloud
- Legacy Support (S/4HANA 2022): The tool may function on 2022, but it is not fully supported.
- Note: The XCO Framework underwent significant API changes between 2022 and 2023. You may encounter "Method Not Found" exceptions or incorrect cardinality mapping on older releases.
- XCO Framework: Standard availability in modern S/4HANA and BTP is required.
This project is largely compatible with ABAP Cloud and follows the Cloud language version and releasedโAPI restrictions.
An additional adapter file is included for onโpremise systems to access repositoryโlevel metadata.
When deploying to ABAP Cloud, the following class must be deleted:
**ZCL_VDM_DIAGRAM_XCO_ADP**
This class relies on APIs and tables that are intentionally unavailable in ABAP Cloud. All remaining sources are Cloudโcompliant.
Due to platform restrictions, the ABAP Cloud variant is not as featureโrich as the onโpremise version.
The following limitations apply in ABAP Cloud:
- CDS view names are displayed in uppercase only
- UNION structures cannot be detected or visualized
- JOIN structures cannot be detected or visualized
These limitations are a direct consequence of the restricted metadata access model in ABAP Cloud and are not implementation defects.
The solution uses a strict Template Method design pattern. The heavy lifting (looping, scope checking, cardinality logic, and data cleansing) is locked inside the Abstract Base Engine. The concrete subclasses act purely as syntax translators.
ZIF_VDM_DIAGRAM_RENDERER: The external contract defining the universal config and thebuild( )method.ZIF_VDM_DIAGRAM_HOOKS: The internal interface defining the exact rendering exits (e.g.,on_entity_start,on_relationship).ZCL_VDM_DIAGRAM_BASE: The abstract engine. It consumes the XCO metadata and orchestrates the calls to the interface hooks.- The Renderers: Subclasses that redefine the hooks to output specific diagram syntax.
Adding a new diagram language (e.g., DOT, Structurizr) requires zero changes to the SAP data extraction logic.
- Create a new class:
CLASS zcl_vdm_diagram_custom INHERITING FROM zcl_vdm_diagram_base. - Redefine the
zif_vdm_diagram_hooksmethods. - Use the protected
add_text( )method to append your specific syntax inside the hooks.
The generator uses the Strategy Pattern, allowing you to swap the visual output by injecting different renderer classes. They all inherit the base class <ZCL_VDM_DIAGRAM_BASE>
| Renderer | Technical Class | Best For | Output Style | Key Features |
|---|---|---|---|---|
| PlantUML | zcl_vdm_diagram_plantuml |
Enterprise Modeling | UML Class Diagram | Orthogonal routing, horizontal/vertical layouts, and detailed field grouping. |
| Mermaid.js | zcl_vdm_diagram_mermaid |
Documentation & Web | UML Class Diagram | Native support in GitHub/GitLab, Azure DevOps, and Notion. Extremely lightweight. |
| D2 | zcl_vdm_diagram_d2 |
Modern Presentation | SQL Table Shapes | ELK layout engine for optimized table routing, "Sketch" mode, and modern styling. |
| Graphviz | zcl_vdm_diagram_graphviz |
Complex Database Schemas | HTML-like Table Nodes | Unmatched automatic routing via the DOT engine. Features edge concentration, port binding for exact arrow placement, and monochrome print modes. |
The tool utilizes the Adapter Pattern to handle environment differences:
- On-Premise: Broader access to the ABAP Repository. Includes fallback logic to parse DDL source code via regex if the XCO API encounters unreleased or complex UNION/JOIN statements that the standard API cannot yet handle.
- Cloud (BTP / Public Edition): Restricted to Tier 1 (Cloud Optimized) ABAP. The generator only interacts with "Released" entities or those within your own software components. Low-level DDIC table reads (like
DDDLSVRC) are prohibited. All CDS entities must have a contract assigned to be able to be used.
The generator is designed for inline usage.
Controls what data is extracted from the SAP XCO metadata and rendered onto the canvas. Passed to the Generator <ZCL_VDM_DIAGRAM_GENERATOR>. Controls what data is extracted from SAP.
| Parameter | Type | Description |
|---|---|---|
cds_name |
String |
The root CDS view to start discovery from. Engine moves down, unless inheritance is true (moves up). |
max_allowed_level |
Integer |
Max recursion depth. Recommended: 3-5. Default is 1. |
discovery |
Toggle |
Logic for finding inheritance, associations, or compositions without drawing lines. |
lines |
Toggle |
Visualization settings for drawing arrows between boxes. |
base |
Boolean |
If true, shows the data source (tables/views) at the top. |
keys |
Boolean |
If true, displays key fields. |
fields |
Boolean |
If true, displays all non-key fields. |
associations_fields |
Boolean |
Lists association names inside the entity box. |
custom_developments_only |
Boolean |
Only draws boxes for the Z* and Y* namespaces. |
include_cds |
Table |
Whitelist: Only these views/entities will be expanded into boxes. |
exclude_cds |
Table |
Blacklist: These views/entities will be ignored by the generator. |
See Examples in this readme for usage.
Passed to the Renderer constructor. Controls how the diagram looks. Passed to a Renderer class based on the base class <ZCL_VDM_DIAGRAM_BASE>
| Engine | Key Format Parameters |
|---|---|
| PlantUML | ortho, modern, polyline, spaced_out |
| Mermaid | direction (TB/LR) |
| D2 | direction, sketch_mode, primary_color |
| Graphviz | ortho, polyline, modern, spaced_out, left_to_right, concentrate_edges, monochrome |
The generator provides granular control over the internal structure of the entity boxes.
- Key Fields (
keys): Rendered at the top of the box with a*prefix to denote primary keys. - Normal Fields (
fields): Standard non-key attributes listed below the keys. - Association Fields (
associations_fields): Lists the names of defined associations within the entity box itself.
The behavior of relationship lines (arrows) changes based on your associations_fields setting to ensure maximum clarity:
- Standard Mode (
associations_fields = abap_false): Relationship lines are drawn from the border of the source box to the border of the target box. Cleanest view for high-level overviews. - Detailed Mode (
associations_fields = abap_true): When associations are listed inside the box, the generator anchors the relationship lines directly to the specific field name within the box.- Why use Detailed Mode? Mapping lines directly to association fields is invaluable when a single CDS view has multiple associations to the same target view (e.g.,
_CreatedByUserand_LastChangedByUserboth pointing toI_User).
- Why use Detailed Mode? Mapping lines directly to association fields is invaluable when a single CDS view has multiple associations to the same target view (e.g.,
The engine splits relationship logic into two granular toggle sets:
- Discovery: Used when you want to find and display entities in the diagram without drawing relationship arrows (Landscape mode).
- Lines: When a specific line type is enabled, the engine automatically enables discovery for that type.
Discovery Only (Entities without lines):
DATA(lo_renderer) = NEW zcl_vdm_diagram_plantuml( ).
DATA(diagram_code) = NEW zcl_vdm_diagram_generator(
renderer = lo_renderer
selection = VALUE #(
cds_name = 'I_BUSINESSPARTNER'
max_allowed_level = 2
discovery = VALUE #( inheritance = abap_true associations = abap_true compositions = abap_true )
)
)->generate( ).
Lines Only (Auto-discovers and draws lines):
DATA(lo_renderer) = NEW zcl_vdm_diagram_mermaid( ).
DATA(diagram_code) = NEW zcl_vdm_diagram_generator(
renderer = lo_renderer
selection = VALUE #(
cds_name = 'I_BUSINESSPARTNER'
max_allowed_level = 2
lines = VALUE #( inheritance = abap_true associations = abap_true compositions = abap_true )
)
)->generate( ).
To prevent accidental empty diagrams, the root cds_name is always included by default.
Inclusion Strategy:
DATA(lo_renderer) = NEW zcl_vdm_diagram_plantuml( ).
DATA(diagram_code) = NEW zcl_vdm_diagram_generator(
renderer = lo_renderer
selection = VALUE #(
cds_name = 'I_BUSINESSPARTNER'
max_allowed_level = 2
lines = VALUE #( associations = abap_true )
" INCLUSION: ONLY expand these views into boxes
include_cds = VALUE #( ( cds_name = 'I_BPDATACONTROLLER' )
( cds_name = 'I_BPRELATIONSHIP_2' ) )
)
)->generate( ).
Exclusion Strategy:
DATA(lo_renderer) = NEW zcl_vdm_diagram_d2( ).
DATA(diagram_code) = NEW zcl_vdm_diagram_generator(
renderer = lo_renderer
selection = VALUE #(
cds_name = 'I_BUSINESSPARTNER'
max_allowed_level = 2
lines = VALUE #( associations = abap_true )
" EXCLUDE these views from selections
exclude_cds = VALUE #( ( cds_name = 'I_BPDATACONTROLLER' )
( cds_name = 'I_BPRELATIONSHIP_2' ) )
)
)->generate( ).
Hides standard SAP noise by only rendering entity boxes for your custom developments.
DATA(lo_renderer) = NEW zcl_vdm_diagram_mermaid( ).
DATA(diagram_code) = NEW zcl_vdm_diagram_generator(
renderer = lo_renderer
selection = VALUE #(
cds_name = 'ZR_BloxUIHeaderTP'
max_allowed_level = 6
lines = VALUE #( compositions = abap_true associations = abap_true )
custom_developments_only = abap_true " Only select entities starting with Z* or Y*
)
)->generate( ).
Generates a highly detailed, modern PlantUML diagram showing absolutely everything.
DATA(format) = VALUE zcl_vdm_diagram_plantuml=>ty_format(
ortho = abap_false
).
DATA(lo_renderer) = NEW zcl_vdm_diagram_plantuml( format ).
DATA(diagram_code) = NEW zcl_vdm_diagram_generator(
renderer = lo_renderer
selection = VALUE #(
cds_name = 'ZR_BloxUIHeaderTP'
max_allowed_level = 3
keys = abap_true
fields = abap_true
base = abap_true
associations_fields = abap_true
lines-associations = abap_true
lines-compositions = abap_true
lines-inheritance = abap_true
force_render_all_relationships = abap_false
)
)->generate( ).
Generates a highly detailed, modern PlantUML diagram showing absolutely everything.
DATA(format) = VALUE zcl_vdm_diagram_graphviz=>ty_format(
spaced_out = abap_true
).
DATA(lo_renderer) = NEW zcl_vdm_diagram_graphviz( format ).
DATA(diagram_code) = NEW zcl_vdm_diagram_generator(
renderer = lo_renderer
selection = VALUE #(
cds_name = 'ZR_BloxUIHeaderTP'
max_allowed_level = 3
keys = abap_true
fields = abap_true
base = abap_true
associations_fields = abap_true
lines-associations = abap_true
lines-compositions = abap_true
lines-inheritance = abap_true
force_render_all_relationships = abap_false
)
)->generate( ).
Strips away noise, hiding fields and base tables. Perfect for GitHub Markdown.
DATA(lo_renderer) = NEW zcl_vdm_diagram_mermaid( ).
DATA(diagram_code) = NEW zcl_vdm_diagram_generator(
renderer = lo_renderer
selection = VALUE #(
cds_name = 'I_BPCurrentDefaultAddress'
keys = abap_false
max_allowed_level = 2
fields = abap_false
base = abap_true
lines-associations = abap_true
lines-compositions = abap_true
lines-inheritance = abap_true
)
)->generate( ).
Maps out a strict data schema using D2. Focuses only on keys, fields, and standard associations (foreign keys).
DATA(lo_renderer) = NEW zcl_vdm_diagram_d2( ).
DATA(diagram_code) = NEW zcl_vdm_diagram_generator(
renderer = lo_renderer
selection = VALUE #(
cds_name = 'I_BPCurrentDefaultAddress'
max_allowed_level = 1
keys = abap_true
fields = abap_true
base = abap_true
lines-associations = abap_true
lines-compositions = abap_false " Turn off Composition
lines-inheritance = abap_false " Turn off Inheritance
force_render_all_relationships = abap_true " Force all target tables to draw
)
)->generate( ).
Fiori Application: We are planning a full-stack SAP Fiori application to dynamically generate and display these diagrams interactively within the SAP environment.
ยฉ 2026 Silicon Street Limited. All Rights Reserved.
Usage Terms:
- INTERNAL USE: Permission is granted to use this code for internal business documentation purposes within a single organization at no cost.
- NON-REDISTRIBUTION: You may NOT redistribute, sell, or include this source code (or derivatives thereof) in any commercial software, package, or library.
- PAID SERVICES: Use of this code to provide paid consulting or documentation services to third parties requires a Commercial License.
- MODIFICATIONS: Any modifications remain subject to this license.
DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING FROM THE USE OF THE SOFTWARE.
FOR COMMERCIAL LICENSING INQUIRIES: contact@siliconst.co.nz