# core/formatters/diagram.structure.formatter.ts

> 34 lines of code and 11 definitions.

Tree: GovLab Docs
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/docs#file-docs-core-formatters-diagram-structure-formatter-ts
Source text: https://banes-lab.com/source/docs/core/formatters/diagram.structure.formatter.ts.txt

Listed in [core/formatters](https://banes-lab.com/api/source/docs/core/formatters.md), after [core/formatters/diagram.sequence.formatter.ts](https://banes-lab.com/source/docs/core/formatters/diagram.sequence.formatter.ts.md) and before [core/formatters/document.formatter.ts](https://banes-lab.com/source/docs/core/formatters/document.formatter.ts.md).

## Definitions

- `emitClassDiagram` (lexical_declaration, line 33, exported)
- `relationLine` (lexical_declaration, line 27)
- `INDENT` (lexical_declaration, line 6)
- `RELATION_SYMBOLS` (lexical_declaration, line 8)
- `byBoxId` (lexical_declaration, line 15)
- `byMemberName` (lexical_declaration, line 16)
- `byRelation` (lexical_declaration, line 17)
- `memberLines` (lexical_declaration, line 19)
- `id` (lexical_declaration, line 20)
- `suffix` (lexical_declaration, line 28)
- `symbol` (lexical_declaration, line 29)

## Contained in

- [core/formatters](https://banes-lab.com/anatomy/docs/folder-docs-core-formatters.md)

## Uses

- [core/formatters/diagram.formatter.ts](https://banes-lab.com/source/docs/core/formatters/diagram.formatter.ts.md)
- [core/normalizers/diagram.normalizer.ts](https://banes-lab.com/source/docs/core/normalizers/diagram.normalizer.ts.md)

## Used by

- [core/formatters/system.formatter.ts](https://banes-lab.com/source/docs/core/formatters/system.formatter.ts.md)
- [core/plugins/diagram.definition.plugin.ts](https://banes-lab.com/source/docs/core/plugins/diagram.definition.plugin.ts.md)
- [core/plugins/diagram.structure.plugin.ts](https://banes-lab.com/source/docs/core/plugins/diagram.structure.plugin.ts.md)

## Linked from

- [core/formatters](https://banes-lab.com/anatomy/docs/folder-docs-core-formatters.md)
- [core/normalizers](https://banes-lab.com/anatomy/docs/folder-docs-core-normalizers.md)
- [core/plugins](https://banes-lab.com/anatomy/docs/folder-docs-core-plugins.md)

## Source

```typescript
import type { ClassBox, ClassMember, ClassModel, ClassRelation, ClassRelationKind } from "#types/diagram.types";
import { idSanitize, label } from "#core/normalizers/diagram.normalizer";
import { accLines } from "#core/formatters/diagram.formatter";
import { byString } from "#core/selectors/base.selector";

const INDENT = "    ";

const RELATION_SYMBOLS: ReadonlyMap<ClassRelationKind, string> = new Map<ClassRelationKind, string>([
    ["composition", "*--"],
    ["aggregation", "o--"],
    ["realization", "<|.."],
    ["dependency", "..>"],
]);

const byBoxId = byString<ClassBox>((box) => box.id);
const byMemberName = byString<ClassMember>((member) => member.name);
const byRelation = byString<ClassRelation>((relation) => `${relation.from} ${relation.to} ${relation.kind}`);

const memberLines = function memberLines(box: ClassBox): string[] {
    const id = idSanitize(box.id);
    return [
        `${INDENT}class ${id}["${label(box.label)}"]`,
        ...box.members.toSorted(byMemberName).map((member) => `${INDENT}${id} : +${label(member.name)}`),
    ];
};

const relationLine = function relationLine(relation: ClassRelation): string {
    const suffix = typeof relation.label === "string" ? ` : ${label(relation.label)}` : "";
    const symbol = RELATION_SYMBOLS.get(relation.kind) ?? "";
    return `${INDENT}${idSanitize(relation.from)} ${symbol} ${idSanitize(relation.to)}${suffix}`;
};

export const emitClassDiagram = function emitClassDiagram(model: ClassModel): string {
    return [
        "classDiagram",
        ...accLines(model),
        ...model.classes.toSorted(byBoxId).flatMap(memberLines),
        ...model.relations.toSorted(byRelation).map(relationLine),
    ].join("\n");
};
```
