Skip to content

MkDiagram

Show source on GitHub

Class representing a mermaid diagram.

Description

MkDiagrams can show directed acyclic graphs and allows to manually create diagrams.

Example: Regular

Jinja

{{ ["1", "2", "3"] | MkDiagram(connections=[("1", "2"), ("2", "3")]) }}

Python

MkDiagram(['1', '2', '3'], {('2', '3'), ('1', '2')})
graph TD
  1
  2
  3
  2 --> 3
  1 --> 2
```` mermaid
graph TD
  1
  2
  3
  2 --> 3
  1 --> 2
````
<pre class="mermaid"><code>graph TD
  1
  2
  3
  2 --&gt; 3
  1 --&gt; 2</code></pre>

Example: Direction

Jinja

{{ ["1", "2", "3"] | MkDiagram(connections=[("1", "2"), ("2", "3", "comment")], direction="LR") }}

Python

MkDiagram(['1', '2', '3'], {('2', '3', 'comment'), ('1', '2')}, direction='LR')
graph LR
  1
  2
  3
  2 --> |comment| 3
  1 --> 2
```` mermaid
graph LR
  1
  2
  3
  2 --> |comment| 3
  1 --> 2
````
<pre class="mermaid"><code>graph LR
  1
  2
  3
  2 --&gt; |comment| 3
  1 --&gt; 2</code></pre>

Bases: MkCode

fence_title property

fence_title: str

mermaid_code property

mermaid_code: str

text property

text: str

__init__

__init__(
    names: list[str] | None = None,
    connections: list[tuple] | None = None,
    *,
    direction: Literal["TD", "DT", "LR", "RL"] = "TD",
    **kwargs: Any
)

Parameters:

Name Type Description Default
names list[str] | None

names which should be part of the diagram

None
connections list[tuple] | None

tuples indicating the connections of the names

None
direction Literal['TD', 'DT', 'LR', 'RL']

diagram direction

'TD'
kwargs Any

Keyword arguments passed to parent

{}
Name Children Inherits
MkClassDiagram
mknodes.templatenodes.mkclassdiagram
Node to display the class hierarchy of a class. Supports multiple modes.
    MkPipDepTree
    mknodes.templatenodes.mkpipdeptree
    Node to display a mermaid diagram for the dependencies.
      Name Children Inherits
      MkCode
      mknodes.basenodes.mkcode
      Class representing a Code block.
      graph TD
        94721311944192["mkdiagram.MkDiagram"]
        94721306031680["mkcode.MkCode"]
        94721311697232["mkcontainer.MkContainer"]
        94721308848336["mknode.MkNode"]
        94721311766592["node.Node"]
        140564252373184["builtins.object"]
        94721306031680 --> 94721311944192
        94721311697232 --> 94721306031680
        94721308848336 --> 94721311697232
        94721311766592 --> 94721308848336
        140564252373184 --> 94721311766592
      /home/runner/work/mknodes/mknodes/mknodes/basenodes/mkdiagram/metadata.toml
      [metadata]
      icon = "mdi:graph-outline"
      name = "MkDiagram"
      group = "diagram"
      
      [[requirements.extension."pymdownx.superfences".custom_fences]]
      name = "mermaid"
      class = "mermaid"
      format = "pymdownx.superfences.fence_code_format"
      
      [examples.regular]
      title = "Regular"
      jinja = """
      {{ ["1", "2", "3"] | MkDiagram(connections=[("1", "2"), ("2", "3")]) }}
      """
      
      [examples.direction]
      title = "Direction"
      jinja = """
      {{ ["1", "2", "3"] | MkDiagram(connections=[("1", "2"), ("2", "3", "comment")], direction="LR") }}
      """
      
      [output.markdown]
      template = """
      {{ node.fence_boundary }} mermaid
      graph {{ node.direction }}
      {% if node.connections %}
      {% for name in node.names %}
        {{ name }}
      {% endfor %}
      {% for connection in node.connections %}
      {% if connection | length == 2 %}
        {{ connection[0] }} --> {{ connection[1] }}
      {% else %}
        {{ connection[0] }} --> |{{ connection[2] }}| {{ connection[1] }}
      {% endif %}
      {% endfor %}
      {% else %}
      {% for name in node.names %}
        {{ name | get_hash }}["{{ name }}"]
      {% endfor %}
      {% for prev, nxt in node.names | pairwise %}
        {{ prev | get_hash }} --> {{ nxt | get_hash }}
      {% endfor %}
      {% endif %}
      {{ node.fence_boundary }}
      """
      
      mknodes.basenodes.mkdiagram.MkDiagram
      class MkDiagram(mkcode.MkCode):
          """Class representing a mermaid diagram.
      
          MkDiagrams can show directed acyclic graphs and allows to manually
          create diagrams.
          """
      
          ICON = "material/graph-outline"
          REQUIRED_EXTENSIONS = [resources.Extension("pymdownx.superfences", **config)]
      
          def __init__(
              self,
              names: list[str] | None = None,
              connections: list[tuple] | None = None,
              *,
              direction: Literal["TD", "DT", "LR", "RL"] = "TD",
              **kwargs: Any,
          ):
              """Constructor.
      
              Args:
                  names: names which should be part of the diagram
                  connections: tuples indicating the connections of the names
                  direction: diagram direction
                  kwargs: Keyword arguments passed to parent
              """
              super().__init__(language="mermaid", **kwargs)
              self.direction = direction
              # Preserve order. Useful if only names are passed, order is important then.
              self.names = iterfilters.reduce_list(names or [])
              self.connections = set(connections or [])
      
          @property
          def text(self) -> str:
              """MkCode override."""
              return f"graph {self.direction}\n{self.mermaid_code}"
      
          @property
          def mermaid_code(self) -> str:
              """Return code block, excluding fences and (graph type direction) line.
      
              Can be overriden by subclasses.
              """
              lines = list(self.names)
              if not self.connections:
                  lines = [f'{utils.get_hash(i)}["{i}"]' for i in lines]
                  for prev, nxt in itertools.pairwise(self.names):
                      lines.append(f"{utils.get_hash(prev)} --> {utils.get_hash(nxt)}")
                  return textwrap.indent("\n".join(lines), "  ")
              for connection in self.connections:
                  if len(connection) == 2:  # noqa: PLR2004
                      source, target = connection
                      lines.append(f"{source} --> {target}")
                  elif len(connection) == 3:  # noqa: PLR2004
                      source, target, mark = connection
                      lines.append(f"{source} --> |{mark}| {target}")
                  else:
                      msg = f"Tuple with wrong length: {connection}"
                      raise TypeError(msg)
              return textwrap.indent("\n".join(lines), "  ")
      
          @property
          def fence_title(self) -> str:
              """MkCode override."""
              return "mermaid"