aboutsummaryrefslogtreecommitdiff
path: root/content/Informatique/2020-12-05-graphviz_en_js.rst
blob: 161d0a05aba088b8f6b86284af05f55be86c1280 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
.. -*- mode: rst -*-
.. -*-  coding: utf-8 -*-

===========================
Prise de note avec graphviz
===========================

:date: 2020-12-06
:tags: graphviz, javascript
:summary: |summary|

.. default-role:: literal

.. |summary| replace::


 J'utilise Graphviz depuis un moment — même pour des notes — car la
 représentation en graphe permet de synthétiser facilement des notions
 complexes. Mais c'est compliqué et long à saisir, du coup, j'ai choisi de me
 faire un petit outil pour me faciliter la vie…

J'utilise Graphviz depuis un moment — même pour des notes — car la
représentation en graphe permet de synthétiser facilement des notions complexes :

- relation de dépendances
- séquence de processus
- …

Mais il me manquait une manière de pouvoir les créer de manière rapide,
c'est-à-dire avec une syntaxe adaptée à la prise de note, et pouvoir éditer le
résultat en temps réel. Or créer une syntaxe est quelque chose que je sais
faire, et voir le résultat en temps réel est possible grâce à `viz.js`_ qui a
recompilé Graphviz en javascript à l'aide d'Emscripten_, et permet donc de le
faire tourner dans le navigateur.


.. _viz.js: http://viz-js.com/
.. _emscripten: https://fr.wikipedia.org/wiki/Emscripten

Il ne reste donc plus qu'à assembler tout ça, pour faire tourner un petit
éditeur de graphe. J'ai choisi de ne représenter que des tables, et d'utiliser
l'indentation pour marquer la relation au parent : (si vous souhaitez en
profiter en pleine page, c'est `ici que ça se passe`_)

.. _ici que ça se passe: {filename}/pages/graph-editor/graph-editor.rst#graph-editor

La démo
-------

.. raw:: html

    <style>
    #app {width: 100%; height: 100%; overflow: hidden; position: relative;}
    #panes {display: flex; width: 100%; height: 100%; overflow: auto;}
    #output svg, #output object { top: 0; left: 0; width: 100%; height: 100%; }
    .flex-child {flex: 1;}
    .vcenter {display: table-cell; vertical-align: middle}
    #overlay {
    display: table;
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 99;
    color: white;
    text-align: center;
    }
    </style>

    <div id="app" disabled="true">
      <button id="dot_output">Export DOT</button>
      <button id="png_output">Export PNG</button>
      <div id="panes">
        <textarea id="editor" class="flex-child">
    g1
     Nom
     -
     propriété 1 <-> g2:2
     propriété 2

    g2
     Autre
     -
     propriété 1
     encore une autre <i>entrée</i>
     autre champ -> g1:3 retour

    g3
     Dernier élément
     -
     ligne 2
     ligne 3
    </textarea>
      <div id="graph" class="flex-child">
        <div id="output">
          <div id="svg"><object data="{static}/resources/viz.js/example.svg" type="image/svg+xml"></object></div>
            <div id="error"></div>
          </div>
        </div>
      </div>
      <div id="overlay">
      </div>
    </div>


.. admonition:: Exécution du script
 :class: hint
 :name: note

 Les librairies étant relativement lourdes (+2Mo), elles ne sont pas chargées
 automatiquement avec la page. Je vous laisse cliquer sur le bouton pour les
 charger et lancer la mise à jour.

 .. raw:: html

  <div style="text-align:center; width:100%; position:relative;">
  <button type="button" id="load_button">Activer</button>
  </div>

  <script type="text/javascript">
   async function getScript(url){
     var script = document.createElement('script');

     promise = new Promise((res, rej) => {
       script.addEventListener('load', () => {
         res(script);
       })
     });

     script.setAttribute('type', 'text/javascript');
     script.setAttribute('src', url);
     if(document.body == null) {
       document.head.appendChild(script);
     } else {
       document.body.appendChild(script);
     }
     return promise;
   }
  var load_button = document.getElementById('load_button');

  load_button.onclick = async function() {
      var note = document.getElementById('note');
      note.remove();
      var s1 = getScript("/resources/viz.js/convert.js");
      await Promise.all([s1]);
      generator.load();
      var overlay = document.getElementById("overlay");
      overlay.remove();
      return false;
  }
  </script>



Vous pouvez édite le texte ci-dessus pour mettre à jour le graphe de la partie
droite directement. Les nœuds sont représentés à l'aide des `HTML Like label`_
de graphviz, il est donc possible d'utiliser de la couleur, ou des balises de
mises en formes qui seront reprises dans le graphe final. Tout ce qui est saisi
est transformé dans le navigateur, et aucune donnée ne transite sur le réseau.


.. _HTML Like label: https://www.graphviz.org/doc/info/shapes.html#html

Avec les boutons d'export, cela me suffit pour produire un petit schéma
rapidement, ou ensuite le retravailler le fichier dot correspondant si j'ai
besoin d'aller plus loin…

Le code
-------

Il est écrit en OCaml et compilé en javascript (c'est pour ça qu'il s'exécute
dans la page). Vous pouvez télécharger une version hors ligne à exécuter en
local ci-dessous :

.. figure:: {static}/images/mimetypes/package-x-generic.png
    :alt: get the file
    :align: center
    :target: {static}/resources/viz.js/graphviz.zip

    Télécharger

la commande `make html` permet de régénérer les sources.