FormatNestedLayerGraph renders the layer graph as a Mermaid flowchart TB with nested subgraphs.
( c *checker.Checker, layerGraph *graph.Graph[LayerGraphNodeInfo, LayerGraphEdgeInfo], sf *ast.SourceFile, )
| 173 | |
| 174 | // FormatNestedLayerGraph renders the layer graph as a Mermaid flowchart TB with nested subgraphs. |
| 175 | func FormatNestedLayerGraph( |
| 176 | c *checker.Checker, |
| 177 | layerGraph *graph.Graph[LayerGraphNodeInfo, LayerGraphEdgeInfo], |
| 178 | sf *ast.SourceFile, |
| 179 | ) string { |
| 180 | var result []string |
| 181 | |
| 182 | // Create subgraph boxes for each node. |
| 183 | for idx, nodeInfo := range layerGraph.Nodes() { |
| 184 | var subgraphDefs []string |
| 185 | |
| 186 | for _, kind := range []string{"requires", "provides"} { |
| 187 | var types []*checker.Type |
| 188 | if kind == "requires" { |
| 189 | types = nodeInfo.Requires |
| 190 | } else { |
| 191 | types = nodeInfo.Provides |
| 192 | } |
| 193 | |
| 194 | var typeNodes []string |
| 195 | for i, t := range types { |
| 196 | typeName := getTypeDisplayName(c, t) |
| 197 | typeNodes = append(typeNodes, fmt.Sprintf(`%d_%s_%d["%s"]`, idx, kind, i, mermaidSafe(typeName))) |
| 198 | } |
| 199 | |
| 200 | if len(typeNodes) > 0 { |
| 201 | kindLabel := "Requires" |
| 202 | if kind == "provides" { |
| 203 | kindLabel = "Provides" |
| 204 | } |
| 205 | subgraphDefs = append(subgraphDefs, fmt.Sprintf("subgraph %d_%s [%s]", idx, kind, kindLabel)) |
| 206 | for _, tn := range typeNodes { |
| 207 | subgraphDefs = append(subgraphDefs, " "+tn) |
| 208 | } |
| 209 | subgraphDefs = append(subgraphDefs, "end") |
| 210 | subgraphDefs = append(subgraphDefs, fmt.Sprintf("style %d_%s stroke:none", idx, kind)) |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | // Wrap in inner wrap subgraph. |
| 215 | var wrapped []string |
| 216 | wrapped = append(wrapped, fmt.Sprintf(`subgraph %d_wrap[" "]`, idx)) |
| 217 | for _, line := range subgraphDefs { |
| 218 | wrapped = append(wrapped, " "+line) |
| 219 | } |
| 220 | wrapped = append(wrapped, "end") |
| 221 | wrapped = append(wrapped, fmt.Sprintf("style %d_wrap fill:transparent", idx)) |
| 222 | wrapped = append(wrapped, fmt.Sprintf("style %d_wrap stroke:none", idx)) |
| 223 | |
| 224 | // Get display node text and location. |
| 225 | displayNode := nodeInfo.DisplayNode |
| 226 | displaySourceFile := getNodeSourceFile(displayNode) |
| 227 | nodeText := getNodeText(displayNode, displaySourceFile) |
| 228 | location := formatLocation(displayNode, sf) |
| 229 | |
| 230 | // Outer subgraph. |
| 231 | result = append(result, fmt.Sprintf("subgraph %d [\"`%s<br/><small>_%s_</small>`\"]", idx, mermaidSafe(nodeText), mermaidSafe(location))) |
| 232 | for _, line := range wrapped { |
no test coverage detected