Aller au contenu principal

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 :

Chargement…
{ id: 'web', type: 'server', text: 'Serveur Web' }
CatégorieTypes
Postesdesktop, laptop, mobile
Réseauclient, server, cloud
Donnéesdatabase
Acteursuser, admin, users
Personnagesalice, 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 (champ body). Pas de gros pictogramme, mais le subicon (icon) reste possible.
  • complex_node — comme simple_node, plus un header affiché 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…).

Chargement…
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 text

text 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.

Chargement…
nodes: [
{ id: 'cache', type: 'circle', text: 'Cache', body: 'Redis' },
{ id: 'choix', type: 'diamond', text: 'Routage', body: 'GET ?' },
{ id: 'file', type: 'height_rectangle', body: 'Queue' },
],
Gardez le texte court

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émaresistor, 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 + unit construisent le libellé (value: 220, unit: 'Ω'"220 Ω" ; combiné à text si les deux sont présents, p. ex. "R1 · 220 Ω") ;
  • closed (sur un switch / push_button) fixe l'état initial du contact, animé à l'exécution par l'action toggle.

La famille inclut aussi des portes logiques numériquesand_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 :

TypeBornes
d_flip_flop, t_flip_flopd / t, clkq, qn
jk_flip_flopj, clk, kq, qn
sr_latchs, rq, qn (sur niveau : pas d'horloge)
mux_2to1i0, i1, sel (par le bas) → y
demux_1to2i, sel (par le bas) → y0, y1
half_addera, bs (somme), cout (retenue)
full_addera, b, cins, 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.

Chargement…
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' },
],
Uniquement les blocs à broches fixes

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 (inout, 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 :

Chargement…
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 NANDDemi-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 (sans language). Avec language, 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).

Chargement…
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',
},
],
Bordure et texte automatiques

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 :

  1. 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)… ;
  2. une icône enregistrée par vous via registerSubIcon ;
  3. à défaut, un texte libre affiché en pastille (tronqué à 4 caractères).
Chargement…
{ id: 'spa', type: 'laptop', text: 'react', icon: 'react' }, // techno connue
{ id: 'edge', type: 'cloud', text: 'v2', icon: 'v2' }, // texte libre → pastille
Enregistrer ses propres badges

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.

Chargement…
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.

Chargement…
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
],