Nœuds
Les nœuds (nodes) sont les objets statiques de la scène : serveurs,
clients, bases de données… Le moteur les place automatiquement (voir
Disposition) ; vous ne décrivez que leur identité et leur
apparence. Chaque nœud porte un id unique réutilisé partout ailleurs
(from/to des actions, connections, zones, object des commentaires…).
Types de nœuds
Le champ type choisit l'apparence. Dix types affichent un pictogramme :
{ id: 'web', type: 'server', text: 'Serveur Web' }
| Catégorie | Types |
|---|---|
| Postes | desktop, laptop, mobile |
| Réseau | client, server, cloud |
| Données | database |
| Acteurs | user, admin, users |
| Personnages | alice, bob, eve |
Deux types supplémentaires affichent du texte plutôt qu'un pictogramme :
simple_node et complex_node (voir ci-dessous).
Huit types dessinent une forme géométrique pouvant contenir un court texte :
square, diamond, circle, triangle, parallelogram, width_rectangle,
height_rectangle et star (voir Formes géométriques).
Nœuds textuels : simple_node et complex_node
Quand un nœud doit montrer du texte (un extrait de code, un en-tête HTTP, une clé de config…) plutôt qu'un pictogramme, utilisez :
simple_node— une boîte de texte (champbody). Pas de gros pictogramme, mais lesubicon(icon) reste possible.complex_node— commesimple_node, plus unheaderaffiché au-dessus du corps et séparé par un trait : le nœud prend l'allure d'un paquet HTTP.
Le champ language applique la coloration syntaxique à toutes les zones de
texte du nœud (l'en-tête et le corps). Les valeurs reconnues sont les mêmes que
pour content (javascript, json, sql, http…).
nodes: [
// simple_node : corps de texte + subicon, sans pictogramme.
{
id: 'snippet',
type: 'simple_node',
icon: 'node',
body: 'const total = a + b;',
language: 'javascript',
},
// complex_node : en-tête + corps, à la manière d'un paquet HTTP.
{
id: 'request',
type: 'complex_node',
header: 'GET /api/users HTTP/1.1',
body: 'Host: api.example.com\nAccept: application/json',
language: 'http', // colore l'en-tête ET le corps
},
],
body/header vs texttext reste le label sous le nœud (commun à tous les types). Pour les nœuds
textuels, le contenu de la boîte se met dans body (et header pour complex_node).
Un set_content actif remplace le panneau
textuel, exactement comme il masque un pictogramme.
Formes géométriques
Huit types dessinent une forme plutôt qu'un pictogramme : square, diamond,
circle, triangle, parallelogram, width_rectangle, height_rectangle et
star. Chaque forme peut contenir un court texte centré via body.
nodes: [
{ id: 'cache', type: 'circle', text: 'Cache', body: 'Redis' },
{ id: 'choix', type: 'diamond', text: 'Routage', body: 'GET ?' },
{ id: 'file', type: 'height_rectangle', body: 'Queue' },
],
Le body d'une forme est pensé pour une étiquette brève (un mot, un nombre,
un sigle). La forme s'agrandit pour accueillir le texte, mais celui-ci est borné
(max-width) et recadré au besoin pour ne jamais déborder du tracé : un
paragraphe entier serait tronqué. Pour du texte long, préférez un
simple_node.
Composants électriques
Une famille de symboles de schéma — resistor, capacitor, inductor,
battery, dc_source / ac_source, diode, led, transistor_npn, opamp,
switch, push_button, lamp, motor, ground, junction, ammeter,
voltmeter, fuse, potentiometer, transformer… — pour dessiner des circuits
électriques. Contrairement aux autres types, ils exposent des bornes nommées
que l'on câble par leur nom ("R1:a", "battery:+", "Q1:collector"), et
s'utilisent au mieux en
direction: 'circuit', où les
connections deviennent des fils orthogonaux. Deux champs les accompagnent :
value+unitconstruisent le libellé (value: 220, unit: 'Ω'→"220 Ω"; combiné àtextsi les deux sont présents, p. ex."R1 · 220 Ω") ;closed(sur unswitch/push_button) fixe l'état initial du contact, animé à l'exécution par l'actiontoggle.
La famille inclut aussi des portes logiques numériques — and_gate,
or_gate, not_gate, nand_gate, nor_gate, xor_gate, xnor_gate,
buffer_gate — avec deux entrées a / b à gauche et une sortie y à droite
(une seule entrée pour not_gate / buffer_gate), leurs équivalents à trois
entrées and3_gate, or3_gate, nand3_gate, nor3_gate et xor3_gate
(entrées a / b / c, celle du milieu à mi-hauteur pour qu'un fil droit
n'ait aucun coude à faire), et un nœud signal — un
pad d'E/S étiqueté qui affiche un bit en son centre (posé via
set_icon, allumé par
set_color) — pour les entrées et sorties
d'un schéma logique.
Blocs fonctionnels
Certains circuits se lisent mieux quand un sous-circuit est dessiné comme un seul boîtier étiqueté plutôt que comme les portes qu'il contient. Huit types couvrent les blocs dont le nombre de bornes est fixe :
| Type | Bornes |
|---|---|
d_flip_flop, t_flip_flop | d / t, clk → q, qn |
jk_flip_flop | j, clk, k → q, qn |
sr_latch | s, r → q, qn (sur niveau : pas d'horloge) |
mux_2to1 | i0, i1, sel (par le bas) → y |
demux_1to2 | i, sel (par le bas) → y0, y1 |
half_adder | a, b → s (somme), cout (retenue) |
full_adder | a, b, cin → s, cout |
qn répond aussi à q_bar, sel à s, et s à sum — écrivez la borne de
la façon qui se lit le mieux dans votre spec.
nodes: [
{ id: 'i0', type: 'signal', x: 0.12, y: 0.28, text: 'A', icon: '1' },
{ id: 'i1', type: 'signal', x: 0.12, y: 0.72, text: 'B', icon: '0' },
{ id: 'm', type: 'mux_2to1', x: 0.55, y: 0.45, text: 'MUX 2:1' },
{ id: 'sel', type: 'signal', x: 0.45, y: 0.86, text: 'S', icon: '0' },
{ id: 'y', type: 'signal', x: 0.88, y: 0.45, text: 'Y', icon: '1' },
],
connections: [
{ from: 'i0', to: 'm:i0' },
{ from: 'i1', to: 'm:i1' },
{ from: 'sel', to: 'm:sel' },
{ from: 'm:y', to: 'y' },
],
Un bloc dont le NOMBRE de bornes varie avec sa taille — un registre N bits, un multiplexeur 4:1, un décodeur n→2ⁿ — n'est délibérément pas un type. Un type par taille multiplierait les symboles sans fin ; ces blocs ont besoin que leurs broches soient déclarées dans la spec, ce que le format ne fait pas encore.
Transistors MOS
mosfet_n et mosfet_p exposent gate (g), drain (d) et source (s),
et transmission_gate est la porte de transmission CMOS (in → out,
commandes en au-dessus et enb au-dessous). Le N et le P se distinguent par
la bulle sur la grille, la convention des schémas logiques CMOS.
Les deux terminaux de canal sont inversés entre les deux : source est le
terminal du haut sur un pMOS, drain est celui du haut sur un nMOS. Ce n'est
pas une bizarrerie — c'est ce que fait tout schéma CMOS, et c'est ce qui permet
de câbler un réseau P et un réseau N de haut en bas :
connections: [
{ from: 'vdd', to: 'P:s' }, // la source du pMOS regarde l'alimentation
{ from: 'P:d', to: 'out' },
{ from: 'out', to: 'N:d' }, // le drain du nMOS regarde la sortie
{ from: 'N:s', to: 'gnd:a' },
{ from: 'out', to: 'y' },
{ from: 'in', to: 'P:g' },
{ from: 'in', to: 'N:g' },
],
Dans un schéma logique, chaque fil piloté par une entrée signal ou une sortie
de porte est automatiquement teinté selon son réseau (son pilote), afin que
les fils qui se croisent ou courent en parallèle se distinguent et ne semblent
pas fusionner. Les blocs ci-dessus pilotent eux aussi un réseau : le q d'une
bascule est teinté comme le y d'une porte. Une transmission_gate, non — elle
laisse passer un réseau au lieu d'en piloter un — et les transistors MOS non
plus, leurs réseaux P et N partageant un même nœud de sortie. La color explicite d'un fil (ou un
set_color sur la connexion) l'emporte
toujours sur la teinte automatique ; les fils pilotés par une source non logique
(une pile, une jonction) restent neutres.
Plusieurs démos de la galerie s'appuient sur tout cela : Circuit électrique
(une boucle pile/interrupteur/résistance/LED avec courant animé), Circuit
parallèle (deux branches résistance + LED), Loi d'Ohm (tension vs courant
vs résistance vs puissance), Circuit RC (un condensateur qui se charge — le
régime transitoire et sa constante de temps τ = R·C), Portes logiques (les
huit portes parcourant toute la table de vérité), Demi-additionneur, et une
famille construite
entièrement à partir de la porte universelle NAND — Demi-additionneur,
Demi-soustracteur, Additionneur complet, Soustracteur complet et un
verrou SR (deux NAND couplées en croix — un bit de mémoire), et un cran plus
bas, la porte NAND en CMOS — la même NAND dessinée en ses quatre transistors
MOS, allumant ceux qui conduisent. Dans les démos
logiques, chaque fil est coloré selon le bit qu'il transporte (vert = 1) via
set_color, pour que les étudiants tracent le signal à travers les portes.
Couleurs : background_color et border_color
Deux champs ajustent les couleurs d'un nœud :
background_color— le fond : remplissage d'une forme, fond d'un panneau (simple_node/complex_node), ou pastille derrière un pictogramme.border_color— la bordure : trait d'une forme, bordure d'un panneau, ou couleur des traits d'un pictogramme.text_color— la couleur du texte dans le nœud (corps d'une forme, en-tête/corps d'un panneau), uniquement si la coloration syntaxique est désactivée (sanslanguage). Aveclanguage, les couleurs de la syntaxe priment.
Chaque champ accepte une couleur prédéfinie (n'importe quel nom CSS : tomato,
steelblue, gold…) ou une valeur hexadécimale exacte (#3b82f6).
nodes: [
// background_color seul → bordure ET texte dérivés automatiquement.
{ id: 'api', type: 'server', background_color: '#bfdbfe' },
// nom prédéfini + bordure explicite, sur une forme.
{
id: 'cache',
type: 'circle',
body: 'Cache',
background_color: 'gold',
border_color: 'darkgoldenrod',
},
// fond sombre, texte auto-contrasté (blanc) ; ou text_color explicite.
{ id: 'note', type: 'simple_node', body: 'TODO', background_color: '#1e3a8a' },
{
id: 'tag',
type: 'square',
body: 'SALE',
background_color: '#fee2e2',
text_color: '#b91c1c',
},
],
Si vous donnez un background_color sans border_color, la bordure est
dérivée du fond (une variante plus sombre qui s'agence bien). De même, sans
text_color, la couleur du texte interne est choisie pour offrir un très fort
contraste avec le fond (noir ou blanc selon sa luminance) — un fond sombre reste
donc lisible sans rien régler. Précisez border_color / text_color pour forcer
une teinte. Avec language (coloration syntaxique), les couleurs des tokens priment
sur text_color.
text — le label
Le text s'affiche sous le nœud. Il est optionnel mais recommandé pour
lever toute ambiguïté entre deux nœuds du même type.
{ id: 'authdb', type: 'database', text: 'Base Auth' }
icon — le badge techno
Le champ icon superpose un petit badge en coin du nœud. Trois sources sont
acceptées, dans cet ordre de résolution :
- une techno connue (icône react-icons
intégrée) — ex.
react,node,postgres,mongodb,redis,nginx,docker,kubernetes,dotnet,python,typescript,go,rust,git,azure,aws,graphql, des protocoles (http,dns,oidc,wifi,bluetooth,5g) et des marques de paiement (visa,mastercard,googlepay,applepay)… ; - une icône enregistrée par vous via
registerSubIcon; - à défaut, un texte libre affiché en pastille (tronqué à 4 caractères).
{ id: 'spa', type: 'laptop', text: 'react', icon: 'react' }, // techno connue
{ id: 'edge', type: 'cloud', text: 'v2', icon: 'v2' }, // texte libre → pastille
registerSubIcon(name, icon) ajoute une techno au registre global, où icon est
du balisage SVG ou une fabrique () => SVGElement :
registerSubIcon('k8s', '<svg viewBox="0 0 24 24">…</svg>');
Appelez-la une seule fois au démarrage de l'application (jamais dans un corps de composant) — voir l'avertissement dans la Référence API.
url — rendre un nœud cliquable
Fournir une url rend le nœud cliquable : il ouvre le lien dans un nouvel
onglet. Pratique pour pointer vers la doc d'un service.
{ id: 'api', type: 'server', text: 'API', url: 'https://exemple.com/api' }
content — contenu initial
Un nœud peut afficher un contenu dès l'initialisation (avant toute action),
via le champ content. Il utilise la même forme que l'action
set_content : un terminal de code,
une fenêtre de navigateur, une image ou un tableau.
{
id: 'editor',
type: 'laptop',
text: 'Éditeur',
content: {
type: 'code',
language: 'javascript',
value: 'const add = (a, b) => a + b;',
},
}
visible — visibilité initiale
Par défaut, tout nœud est visible (visible: true). Passez visible: false
pour le masquer au départ et le révéler plus tard avec l'action
set_visible — utile pour montrer
l'ajout d'un composant (cache, réplica…) au fil de la narration.
nodes: [
{ id: 'app', type: 'server', text: 'App' },
{ id: 'cache', type: 'database', text: 'Cache', visible: false }, // caché au départ
],
timeline: [
{ type: 'set_visible', object: 'cache', visible: true }, // … puis révélé
],
rotation — orientation du nœud
rotation oriente le visuel du nœud (pictogramme, forme ou panneau) d'un
angle en degrés (sens horaire, défaut 0). Le label sous le nœud reste droit,
et l'ancrage des flèches est calculé sur la boîte non pivotée — un nœud pivoté se
connecte donc exactement comme un nœud droit.
L'orientation peut être animée à l'exécution avec l'action
rotate, qui amène le nœud vers un angle cible
absolu. Les rotations successives s'enchaînent depuis l'angle courant.
nodes: [
{ id: 'arm', type: 'triangle', text: '45°', rotation: 45 }, // orientation statique
{ id: 'spin', type: 'width_rectangle', text: 'rotate' },
],
timeline: [
{ type: 'rotate', object: 'spin', to: 180 }, // anime vers 180°
{ type: 'rotate', object: 'spin', to: 360 }, // … puis un tour complet
],