Command/More/RunGraphizSample.ps1
Import-Module CmxModule -Force $dotExePath = "D:\Programs\Graphviz\bin\dot.exe" $inputFile = $env:Temp + "\GraphvizCode.gv" $outputFile = "C:\Temp\GraphizOutput.png" # https://graphviz.org/doc/info/attrs.html $code = @' digraph g { layout = "dot" rankdir = "TB" fontname = "Arial" label = "OPC UA Safety Object Model" labelloc = "top" node [style = filled; fillcolor = yellow; color = dimgrey; fontcolor = black; fontname = "Arial"] edge [color = black; fontsize = 8; fontname = "Arial"; arrowhead = vee] subgraph cluster0 { label = ""; labelloc = "bottom"; style = filled; color = white; n7 [label = "S7ControllerTargetData"; fillcolor = lightgrey] n1 [label = "FailsafeInfo"; fillcolor = yellow] n0 [label = "SafetyOverOpcUa \n Provider"; fillcolor = yellow] n2 [label = "DataBlockData"; fillcolor = lightgrey] n3 [label = "CodeBlockData"; fillcolor = lightgrey] n4 [label = "UserTypeData"; fillcolor = lightgrey] n5 [label = "FBlockInfo"; fillcolor = yellow] n6 [label = "FBlockInfo"; fillcolor = yellow] { rank = min; n7; } { rank = min; n1; } { rank = same; n0; } { rank = same; n2; n3; n4; } { rank = same; n5; n6; } edge[label = "SafetyOverOpcUa \n ProviderToFailsafeInfo \n 1"] n0 -> n1; edge[label = "FailsafeInfoTo \n SafetyOverOpcUa \n Provider \n *"] n1 -> n0; edge[label = "SafetyOverOpcUa \n ProviderToCoverInstanceDataBlock \n 1"] n0 -> n2; edge[label = "CoverInstanceDataBlockTo \n SafetyOverOpcUa \n Provider \n 1"] n2 -> n0; edge[label = "SafetyOverOpcUa \n ProviderToCoverFunctionBlock \n 1"] n0 -> n3; edge[label = "CoverFunctionBlockTo \n SafetyOverOpcUa \n Provider \n *"] n3 -> n0; edge[label = "SafetyOverOpcUa \n ProviderToUserTypeData \n 1"] n0 -> n4; edge[label = "UserTypeDataTo \n SafetyOverOpcUa \n Provider \n *"] n4 -> n0; edge[label = "NonSafetyData \n MappingExpandoLink \n 1"; style = dashed] n0 -> n4; edge[color = black; fontcolor = black] edge[label = "GeneralBlockSourceData \n ToBlockInfo \n 1"] n3 -> n5 edge[label = "BlockInfo \n ToGeneralBlockSourceData \n 1"] n5 -> n3 edge[label = "BlockInfo \n ToUserTypeData \n 1"] n5 -> n4 edge[label = "BlockInfo \n ToNonSafetyUdt \n 1"; style = dashed] n5 -> n4 edge[style = solid] edge[label = "UserTypeDataToBlockInfo \n *"] n4 -> n5 edge[label = "GeneralBlockSourceData \n ToBlockInfo \n 1"] n2 -> n6 edge[label = "BlockInfo \n ToGeneralBlockSourceData \n 1"] n6 -> n2 edge[label = "BelongsTo \n 1"] n0 -> n7 edge[label = "SWObjectsBelongingToMe \n *"] n7 -> n0 } subgraph cluster1 { rankdir = "TB" label = "Legend" labelloc = "bottom"; style = filled; color = black; fillcolor = grey95; subgraph cluster2 { label = ""; l0 [label = "Failsafe Type"; fillcolor = yellow] l1 [label = "Standard Type"; fillcolor = lightgrey] edge [style = invis] l0 -> l2; edge [style = invis] l1 -> l3; } subgraph cluster3 { label = ""; l2 [label = "Type 1"; fillcolor = yellow] l3 [label = "Type 2"; fillcolor = lightgrey] edge[label = " Default Link "; style = solid] l2 -> l3; edge[label = " Expando Link "; style = dashed] l3 -> l2; } { rank = same; l0; l1; } { rank = same; l2; l3; } } } '@ $code = @' digraph g { layout = dot rankdir = TB fontname = "Arial" label = "Safety Provider Model Attributes" labelloc = "top" node [style = filled; fillcolor = yellow; color = dimgrey; fontcolor = black; fontname = "Arial"] edge [color = black; fontsize = 8; fontname = "Arial"] subgraph cluster0 { label = ""; labelloc = "bottom"; style = filled; color = white; n1 [label = "SafetyOverOpcUa \n Provider"; fillcolor = yellow] n2 [label = "FBlockInfo"; fillcolor = yellow] } subgraph cluster1 { label = ""; labelloc = "bottom"; style = filled; color = white; node [shape = record; fillcolor = lightgrey]; set0 [ label = "{ICoreAttributes}" ]; node [shape = record; fillcolor = yellow]; set1 [ label = "{{ISafetyOverOpcUaProviderData} | { ProviderId : ulong } | { BaseId : Guid } | { Mapping : string } | { Namespace : string } | { InterfaceName : string } | { InterfaceId : string } | { ProviderDelay : uint } | { StructuredDataType : BlobT } | { GenericNodeId : BlobT } | { DataStatus : BlobT } }" ]; node [shape = record; fillcolor = yellow]; set2 [ label = "{{ISafetyOverOpcUaProviderDataExpando} | { NodeNamespaceIndices : OpcUaNodeNamespaceIndices } | { ActivateFsvMappingExpandoAttribute : string } | { NonSafetyDataMappingExpandoAttribute : string } | { NonSafetyDataTypeExpandoAttribute : OpcUaStructuredDataType } | { IsNonSafetyDataPlaceholderUsedExpandoAttribute : bool } | { NonSafetyDataMappingExpandoLink : IUdt } }" ]; node [shape = record; fillcolor = yellow]; set3 [ label = "{{IFBlockInfoExpando} | { BlockInfoToNonSafetyUdt : IUdt } | { . . . } }" ]; } edge[arrowhead = diamond] n1 -> set0; n1 -> set1; n1 -> set2; n2 -> set3; { rank = min; n1; } { rank = same; set0; set1; } } '@ New-Item $inputFile -Force Set-Content $inputFile $code & $dotExePath -Tpng $inputFile -o $outputFile Remove-Item $inputFile |