princemaple

princemaple

DG - Elixir wrapper of :digraph with a pinch of protocols and sigils

Hi All,

After seeing the mermaid.js integration in livebook, I had a little idea to create a library on top of :digraph that bridges between a :digraph graph and a mermaid.js flowchart.

Highlights

Inspect

dg = DG.new()
DG.add_vertex(dg, "v1")
DG.add_vertex(dg, "v2", "label 2")
DG.add_vertex(dg, "v3")
DG.add_edge(dg, "v1", "v2")
DG.add_edge(dg, "v1", "v3", "1 to 3")

IO.inspect(dg)

Outputs mermaid.js format flowchart

graph LR
    v1-->v2[label 2]
    v1--1 to 3-->v3

which can be put into livebook mermaid block and will display as

livebook screenshot

Collectable

Easily add

  • vertices [{:vertex, 1}, {:vertex, 2, "label 2"}, ...]
  • or edges [{:edge, 1, 2}, {:edge, "a", "b", "label ab"}, ...]

to the graph via Enum.into/2

dg = DG.new()

~w(a b c d e) |> Enum.map(&{:vertex, &1}) |> Enum.into(dg)

~w(a b c d e)
|> Enum.chunk_every(2, 1, :discard)
|> Enum.map(fn [f, t] -> {:edge, f, t} end)
|> Enum.into(dg)

IO.inspect(dg)

outputs

graph LR
    b-->c
    c-->d
    a-->b
    d-->e

livebook screenshot

Functions

  • Most functions from :digraph and :digraph_utils are mirrored under DG.
  • Some functions have their parameters re-arranged so that the graph is always the first parameter.
    (namely reachable/2, reachable_neighbours/2, reaching/2 and reaching_neighbours/2)
  • new/{0,1,2,3} returns %DG{} instead of an Erlang digraph
  • new/2 and new/3 are shortcuts that can add vertices and edges on creation,
    which don’t exist on :digraph

Sigils

~G and ~g are provided so you can copy mermaid.js flowchart and paste into Elixir to get a %DG{}

import DG.Sigil

dg = ~G"""
graph LR
  a[some label]
  b[other label]
  1-->2
  3[three] -- three to four --> 4[four]
  a --> b
"""

caveat: :digraph is stateful (using ets), don’t use the sigil at compile time,
e.g. as a module attribute, it won’t carry over to runtime.
Only use it in runtime code, e.g. function body,
and remember to clean up properly when it’s no longer used, with delete/1.

Most Liked

princemaple

princemaple

Edit: added link to repo… How did I miss the most important thing :rofl:

Where Next?

Popular in Libraries Top

Qqwy
TypeCheck: Fast and flexible runtime type-checking for your Elixir projects. Core ideas Type- and function specifications are const...
336 13801 100
New
marcuslankenau
I feel kind of stuck with the absence of a proper xml library for Elixir. Currently I use SweetXML which was ok for me more or less to pa...
New
devonestes
Introducing assertions, the library that helps you write really great test assertions! GitHub: https://github.com/devonestes/assertions ...
New
treble37
Just looking for a little feedback on a tiny helper library I built - Sometimes I find the need to convert maps with atom keys to maps...
New
mbuhot
Leverage Open Api 3.0 (Swagger) to document, test, validate and explore your Plug and Phoenix APIs. Generate and serve a JSON Open API ...
New
archan937
It is a well-know topic within the Elixir community: “To mock or not to mock? :)” Every alchemist probably has his / her own opinion con...
New
New
benlime
I created a new library GitHub - benvp/ex_cva: Class Variance Authority for Elixir which aims to make it very easy to define different va...
New
josevalim
Yes, yet another parser combinator library! Most of the parser combinators in the ecosystem are either compile-time, often using AST tra...
159 18262 141
New
bluzky
You may know https://ui.shadcn.com/, a UI component library for React. I really love it’s design style and components. I’ve built some co...
381 12391 119
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New

Sub Categories:

We're in Beta

About us Mission Statement