# ✨ panel-mermaid

[![License](https://img.shields.io/badge/License-MIT%202.0-blue.svg)](https://opensource.org/licenses/MIT)
[![py.cafe](https://py.cafe/badge.svg)](https://py.cafe/awesome.panel.org/panel-mermaid-basic)

`panel-mermaid` provides the `MermaidDiagram` *pane* designed to integrate [Mermaid diagramming](https://mermaid.js.org/intro/) functionality with notebooks and [Panel](https://panel.holoviz.org/) data apps.

![panel-mermaid in notebook](https://github.com/awesome-panel/panel-mermaid/blob/main/static/panel-mermaid-notebook.png?raw=true)

It is based on [Mermaid JS](https://mermaid.js.org/).

## Key Features

- **Interactive Mermaid Diagrams**: Easily create flowcharts, sequence diagrams, class diagrams, and more using the familiar Mermaid syntax.
- **Configurable Themes and Looks**: Choose from a variety of themes (`default`, `dark`, `forest`, etc.) and looks (`classic`, `handDrawn`).
- **Real-time Configuration Updates**: Use the `MermaidConfiguration` widget to dynamically update your diagram’s configuration.
- **Customizable Events**: Handle diagram interactions with event subscriptions (e.g., click, mouseover).
- **Font-Awesome Icon Support**: Leverage Font-Awesome icons in your diagrams by including the Font-Awesome CSS in your application.

## Installation

You can install the package using `pip`:

```bash
pip install panel-mermaid
```

## Usage

### 1. Basic Mermaid Diagram

[![py.cafe](https://py.cafe/badge.svg)](https://py.cafe/awesome.panel.org/panel-mermaid-basic)

[![panel-mermaid](https://github.com/awesome-panel/panel-mermaid/blob/main/static/panel-mermaid-bootstrap.png?raw=true)](https://py.cafe/awesome.panel.org/panel-mermaid-basic)

Here’s how to create a simple Mermaid diagram using the `MermaidDiagram` widget:

```python
import panel as pn

from panel_mermaid import MermaidDiagram

pn.extension()

MermaidDiagram(
    object=(
        """
        graph LR
            A[Hello] --> B[Panel] --> E[World]
            A-->C(Mermaid) --> E ;
        """
    )
).servable()
```

### 2. Basic Mermaid Configuration

[![py.cafe](https://py.cafe/badge.svg)](https://py.cafe/snippet/panel/v1# )

Use the `configuration` parameter to modify the [Mermaid diagram configuration](https://mermaid.js.org/schemas/config.schema.json):

```python
import panel as pn

from panel_mermaid import MermaidDiagram

pn.extension()

MermaidDiagram(
    object=(
        """
        graph LR
            A[Hello] --> B[Panel] --> E[World]
            A-->C(Mermaid) --> E ;
        """
    ),
    configuration={"look": "handDrawn", "theme": "forest"},
).servable()
```

### 3. The MermaidConfiguration Widget

[![py.cafe](https://py.cafe/badge.svg)](https://py.cafe/snippet/panel/v1# )

The `MermaidConfiguration` widget allows you to adjust diagram styling and themes interactively, making it simple to adapt to various visual preferences. You can customize:

- **Look**: Choose between `classic` or `handDrawn`.
- **Theme**: Choose from several themes like `default`, `dark`, `forest`, etc.

Example:

```python
import panel as pn

from panel_mermaid import MermaidDiagram, MermaidConfiguration

pn.extension()

configuration = MermaidConfiguration(look="handDrawn", theme="forest")
diagram = MermaidDiagram(
    object=(
        """
        graph LR
            A[Hello] --> B[Panel] --> E[World]
            A-->C(Mermaid) --> E ;
        """
    ),
    configuration=configuration,
)

pn.FlexBox(configuration, diagram).servable()
```

### 4. Event Handling

[![py.cafe](https://py.cafe/badge.svg)](https://py.cafe/snippet/panel/v1# )

You can also add event listeners to the diagram, allowing interactivity such as responding to clicks on diagram nodes:

```python
import panel as pn

from panel_mermaid import MermaidDiagram, MermaidConfiguration

pn.extension()

diagram = MermaidDiagram(
    object=(
        """
        graph LR
            A[Hello] --> B[Panel] --> E[World]
            A-->C(Mermaid) --> E ;
        """
    ),
    event_configuration=[("click", ".node")]
)

pn.FlexBox(diagram, pn.pane.JSON(diagram.param.event, theme="light")).servable()
```

In this example we will subscribe to all `click` events on elements with the `.node` class.

### 5. Mermaid SVG Value

[![py.cafe](https://py.cafe/badge.svg)](https://py.cafe/snippet/panel/v1# )

If you would like the Mermaid SVG `value` to be updated would will need to set `update_value=True`:

```python
from io import StringIO
import panel as pn
from panel_mermaid import MermaidDiagram

pn.extension()

diagram = MermaidDiagram(
    object=(
        """
        graph LR
            A[Hello] --> B[Panel] --> E[World]
            A-->C(Mermaid) --> E ;
        """
    ),
    update_value=True,
)

pn.FlexBox(
    pn.Column(
        diagram,
        diagram.param.update_value,
    ),
    pn.Column(
        pn.widgets.TextAreaInput(value=diagram.param.value, disabled=True, height=200),
        pn.widgets.FileDownload(
            file=pn.bind(StringIO, diagram.param.value), filename="diagram.svg"
        ),
    ),
).servable()
```

### 6. Font-Awesome Icons

[![py.cafe](https://py.cafe/badge.svg)](https://py.cafe/snippet/panel/v1# )

To use Font-Awesome icons in your Mermaid diagrams, include the Font-Awesome CSS. Once included, you can add icons to your diagrams by prefixing with `fa:`:

```python
import panel as pn

from panel_mermaid import MermaidDiagram

pn.extension(sizing_mode="stretch_width", css_files=["https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css"])

MermaidDiagram(
    object=(
        """
        graph LR
            A[Hello] --> B[fa:fa-chart-simple Panel] --> E[World]
            A-->C(fa:fa-diagram-project Mermaid) --> E ;
        """
    )
).servable()
```

## API

### Parameters

- `object` (str): A valid Mermaid string.
- `value` (str): The SVG Value corresponding to Mermaid `object`. Will only be updated if `update_value` is True.
- `update_value`: If True the `value` will be updated. Default is False to save resources.
- `configuration` (dict): The mermaid configuration as described in [Mermaid | config.schema.json](https://mermaid.js.org/schemas/config.schema.json).
- `event` (dict): An event from interacting with the diagram.
- `event_configuration`: List of (event name, query selector string) tuples to subscribe to. For example `[("click", ".node")]` or `[("mouseover", ".node")]`.

## Mermaid Editor

[![py.cafe](https://py.cafe/badge.svg)](https://py.cafe/awesome.panel.org/panel-mermaid-editor)

[Open the Mermaid Editor](https://py.cafe/awesome.panel.org/panel-mermaid-editor) to explore the features and documentation of the `PanelMermaid` pane interactively.

[![Panel Mermaid | Diagram Editor](https://github.com/awesome-panel/panel-mermaid/blob/main/static/panel-mermaid-editor.gif?raw=true)](https://py.cafe/awesome.panel.org/panel-mermaid-editor)

## ❤️ Contributions

Contributions and co-maintainers are very welcome! Please submit issues or pull requests to the [GitHub repository](https://github.com/awesome-panel/panel-xml). Check out the [DEVELOPER_GUIDE](DEVELOPER_GUIDE.md) for more information.

## Alternative Projects

- [mermaid-py](https://github.com/ouhammmourachid/mermaid-py)
- [PyMermaid](https://github.com/QuattroMusic/PyMermaid)
- [pymermaider](https://github.com/diceroll123/pymermaider)
- [python-mermaid](https://github.com/Dynnammo/python_mermaid)
- [streamlit-mermaid](https://github.com/neka-nat/streamlit-mermaid)

---

Start building rich, interactive diagrams directly in your Python applications with `panel-mermaid`!
