Le matériel, dont nous publions la traduction aujourd'hui, est consacré au processus de développement d'un système de visualisation pour les diagrammes d'arbres dynamiques. Pour dessiner des courbes de Bézier cubiques, la technologie SVG (Scalable Vector Graphics, scalable vector graphics) est utilisée ici. Le travail réactif avec les données est organisé par Vue.js.
Voici une version de démonstration du système avec laquelle vous pouvez expérimenter.
Graphique d'arbre interactifLa combinaison des puissantes fonctionnalités de SVG et du cadre Vue.js nous a permis de créer un système de construction de diagrammes basés sur des données, interactifs et personnalisables.
Un diagramme est un ensemble de courbes de Bézier cubiques commençant à un point. Les courbes se terminent en différents points équidistants les uns des autres. Leur position finale dépend des données saisies par l'utilisateur. En conséquence, le graphique est capable de réagir de manière réactive aux changements de données.
Tout d'abord, nous parlerons de la façon dont les courbes cubiques de Bézier sont formées, puis nous verrons comment les représenter dans le système de coordonnées de l'élément
<svg>
, et parler de la création de masques pour les images.
L'auteur du document dit qu'elle a préparé de nombreuses illustrations pour lui, en essayant de le rendre compréhensible et intéressant. Le but du matériel est d'aider chacun à acquérir les connaissances et les compétences nécessaires pour développer ses propres systèmes de schémas.
Svg
▍ Comment se forment les courbes de Bézier cubiques?
Les courbes utilisées dans ce projet sont appelées Cubic Bezier Curve. La figure suivante montre les éléments clés de ces courbes.
Éléments clés d'une courbe cubique de BézierLa courbe est décrite par quatre paires de coordonnées. La première paire
(x0, y0)
est le point d'ancrage de départ de la courbe. La dernière paire de coordonnées
(x3, y3)
est le point de référence final.
Entre ces points, vous pouvez voir les soi-disant points de contrôle. C'est le point
(x1, y1)
et le point
(x2, y2)
.
L'emplacement des points de contrôle par rapport aux points de contrôle détermine la forme de la courbe. Si la courbe n'était définie que par les points de début et de fin, les coordonnées
(x0, y0)
et
(x3, y3)
, alors cette courbe ressemblerait à un segment droit situé en diagonale.
Nous allons maintenant utiliser les coordonnées des quatre points décrits ci-dessus pour tracer la courbe à l'aide de l'élément
<path>
SVG. Voici la syntaxe utilisée dans l'élément
<path>
pour construire des courbes de Bézier cubiques:
<path D="M x0,y0 C x1,y1 x2,y2 x3,y3" />
La lettre
, visible dans le code, est l'abréviation de Cubic Bezier Curve. La lettre minuscule (
c
) signifie l'utilisation de valeurs relatives, la majuscule (
C
) signifie l'utilisation de valeurs absolues. J'utilise des valeurs absolues pour construire le diagramme, cela est indiqué par la lettre majuscule utilisée dans l'exemple.
▍Création d'un diagramme symétrique
La symétrie est un aspect clé de ce projet. Pour construire un diagramme symétrique, j'ai utilisé une seule variable, recevant sur sa base des valeurs telles que la hauteur, la largeur ou les coordonnées du centre d'un certain objet.
Appelons cette
size
variable. Étant donné que le graphique est orienté horizontalement, la variable de
size
peut être considérée comme l'ensemble de l'espace horizontal disponible pour le graphique.
Attribuez à cette variable une valeur réaliste. Nous utiliserons cette valeur pour calculer les coordonnées des éléments du graphique.
size = 1000
Recherche des coordonnées des éléments du graphique
Avant de pouvoir trouver les coordonnées nécessaires pour construire le diagramme, nous devons traiter avec le système de coordonnées SVG.
▍Système coordonné et viewBox
L'attribut de l'
<svg> viewBox
très important dans notre projet. Le fait est qu'il décrit le système de coordonnées utilisateur de l'image SVG. Autrement dit, la
viewBox
détermine la position et la taille de l'espace dans lequel l'image SVG visible à l'écran sera créée.
L'attribut
viewBox
compose de quatre nombres qui spécifient les paramètres du système de coordonnées et les suivants dans cet ordre:
min-x
,
min-y
,
width
,
height
. Les paramètres
min-x
et
min-y
définissent l'origine du système de coordonnées utilisateur, les paramètres
width
et
height
définissent la largeur et la hauteur de l'image affichée. Voici à quoi pourrait ressembler l'attribut
viewBox
:
<svg viewBox="min-x min-y width height">...</svg>
La variable de
size
que nous avons décrite ci-dessus sera utilisée pour contrôler les paramètres de
width
et de
height
de ce système de coordonnées.
Plus tard, dans la section sur Vue.js, nous
viewBox
le
viewBox
à une propriété calculée pour spécifier les valeurs de
width
et de
height
. De plus, dans notre projet, les propriétés
min-x
et
min-y
seront toujours mises à 0.
Notez que nous n'utilisons pas les attributs de
height
et de
width
de l'élément
<svg>
lui-même. Nous allons les régler sur
width: 100%
et
height: 100%
utilisant CSS. Cela nous permettra de créer une image SVG qui s'adapte de manière flexible à la taille de la page.
Maintenant que le système de coordonnées utilisateur est prêt à dessiner un graphique, parlons de l'utilisation de la variable de
size
pour calculer les coordonnées des éléments du graphique.
▍ Coordonnées invariables et dynamiques
Concept graphiqueLe cercle dans lequel le dessin est affiché fait partie du diagramme. C'est pourquoi il est important de l'inclure dans les calculs dès le début. À partir de l'illustration ci-dessus, recherchons les coordonnées du cercle et d'une courbe expérimentale.
La hauteur du graphique est divisée en deux parties. Ce sont
topHeight
(20% de la
size
) et
bottomHeight
(les 80% restants de la
size
). La largeur totale du diagramme est divisée en 2 parties - la longueur de chacune d'entre elles est de 50% de la
size
.
Cela rend la conclusion des paramètres du cercle ne nécessitant pas d'explications spéciales (ici, les indicateurs
halfSize
et
topHeight
sont utilisés). Le paramètre
radius
est défini sur la moitié de la valeur de
topHeight
. Grâce à cela, le cercle s'intègre parfaitement dans l'espace disponible.
Voyons maintenant les coordonnées des courbes.
- Les coordonnées
(x0, y0)
définissent le point de référence de départ de la courbe. Ces coordonnées restent constantes tout le temps. La coordonnée x0
est le centre du graphique (la moitié de la size
) et y0
est la coordonnée à laquelle se termine le bas du cercle. Par conséquent, dans la formule de calcul de cette coordonnée, le rayon du cercle est utilisé. Par conséquent, les coordonnées de ce point peuvent être trouvées par la formule suivante : (50% size, 20% size + radius)
. - Les coordonnées
(x1, y1)
sont le premier point de contrôle de la courbe. Il reste également inchangé pour toutes les courbes. Si nous n'oublions pas que les courbes doivent être symétriques, il s'avère que les valeurs de x1
et y1
toujours égales à la moitié de la valeur de size
. D'où la formule de leur calcul: (50% size, 50% size)
. - Les coordonnées
(x2, y2)
représentent le deuxième point de contrôle de la courbe de Bézier. Ici, x2
indique la forme de la courbe. Cet indicateur est calculé dynamiquement pour chaque courbe. Et l'indicateur y2
, comme précédemment, sera de moitié. D'où la formule suivante pour calculer ces coordonnées: (x2, 50% size)
. - Les coordonnées
(x3, y3)
sont le point de référence final de la courbe. Cette coordonnée indique où vous souhaitez terminer le tracé de la ligne. Ici, la valeur de x3
, comme x2
, est calculée dynamiquement. Et y3
prend une valeur égale à 80% de la size
. En conséquence, nous obtenons la formule suivante: (x3, 80% size)
.
Nous réécrivons, en termes généraux, le code de l'élément
<path>
, en tenant compte des formules que nous venons de dériver. Les pourcentages utilisés ci-dessus sont présentés ici en les divisant par 100.
<path d="M size*0.5, (size*0.2) + radius C size*0.5, size*0.5 x2, size*0.5 x3, size*0.8" >
Veuillez noter qu'à première vue, l'utilisation de pourcentages dans nos formules peut sembler facultative, basée uniquement sur mon propre avis. Cependant, ces valeurs ne sont pas appliquées sur un coup de tête, mais parce que leur utilisation aide à atteindre la symétrie et les proportions correctes du diagramme. Après avoir senti leur rôle dans la représentation graphique, vous pouvez essayer vos propres valeurs de pourcentage et examiner les résultats obtenus en les appliquant.
Parlons maintenant de la façon dont nous chercherons les coordonnées
x2
et
x3
. Ils vous permettent de créer dynamiquement de nombreuses courbes en fonction de l'
index
éléments dans le tableau correspondant.
La division de l'espace horizontal disponible du graphique en parties égales est basée sur le nombre d'éléments dans le tableau. Par conséquent, chaque pièce reçoit le même espace le long de l'axe x.
La formule que nous dérivons devrait ensuite fonctionner avec n'importe quel nombre d'éléments. Mais ici, nous allons expérimenter avec un tableau contenant 5 éléments:
[0,1,2,3,4]
. La visualisation d'un tel tableau signifie qu'il est nécessaire de tracer 5 courbes.
▍Trouver des coordonnées dynamiques (x2 et x3)
Tout d'abord, j'ai divisé la
size
par le nombre d'éléments, c'est-à-dire par la longueur du tableau. J'ai appelé cette
distance
variable. Il représente la distance entre deux éléments.
distance = size/arrayLength
Puis j'ai parcouru le tableau et multiplié l'index de chacun de ses éléments (
index
) par la
distance
. Pour simplifier, j'appelle simplement
x
à la fois le paramètre
x2
et le paramètre
x3
.
Si vous appliquez les valeurs obtenues lors de la construction du diagramme, c'est-à-dire utilisez la valeur
x
calculée ci-dessus pour
x2
et
x3
, cela aura l'air un peu étrange.
Le diagramme est asymétriqueComme vous pouvez le voir, les éléments sont situés dans la zone où ils devraient être, mais le diagramme s'est révélé asymétrique. Il semble que dans sa partie gauche il y ait plus d'éléments qu'à droite.
Maintenant, je dois
x3
valeur
x3
au centre des segments correspondants, dont la longueur est définie à l'aide de la variable de
distance
.
Afin d'amener le diagramme à la forme dont j'ai besoin, j'ai simplement ajouté à
x
moitié de la valeur de la
distance
.
x = index * distance + (distance * 0.5)
En conséquence, j'ai trouvé le centre du segment de
distance
et y ai placé la coordonnée
x3
. De plus, j'ai apporté à la forme que nous avons besoin de la coordonnée
x2
pour la courbe n ° 2.
Diagramme symétriqueL'ajout de la moitié de la valeur de la
distance
aux coordonnées
x2
et
x3
rendu la formule de calcul de ces coordonnées appropriée pour visualiser des tableaux contenant un nombre pair et impair d'éléments.
▍ Masquage d'image
Nous avons besoin qu'une certaine image soit affichée en haut du diagramme, dans le cercle. Pour résoudre ce problème, j'ai créé un masque d'écrêtage contenant un cercle.
<defs> <mask id="svg-mask"> <circle :r="radius" :cx="halfSize" :cy="topHeight" fill="white"/> </mask> </defs>
Ensuite, en utilisant la
<image>
de l'élément
<image>
<svg>
<image>
pour afficher l'image, j'ai lié l'image à l'élément
<mask>
créé ci-dessus en utilisant l'attribut
mask
de l'élément
<image>
.
<image mask="url(#svg-mask)" :x="(halfSize-radius)" :y="(topHeight-radius)" ... > </image>
Puisque nous essayons d'ajuster une image carrée dans une «fenêtre» ronde, j'ai ajusté la position de l'élément en soustrayant le paramètre de
radius
paramètres correspondants. En conséquence, l'image est visible à travers un masque réalisé sous la forme d'un cercle.
Rassemblons tout ce dont nous avons parlé dans un dessin. Cela nous aidera à voir le tableau d'ensemble de l'avancement des travaux.
Données utilisées dans le calcul des paramètres du graphiqueCréation d'une image SVG dynamique à l'aide de Vue.js
À ce stade, nous avons déterminé les courbes de Bézier cubiques et effectué les calculs nécessaires pour former le diagramme. Par conséquent, nous pouvons maintenant créer des diagrammes SVG statiques. Si nous combinons les capacités de SVG et Vue.js, nous pouvons créer des diagrammes pilotés par les données. Les diagrammes statiques deviendront dynamiques.
Dans cette section, nous révisons le diagramme SVG, le présentant comme un ensemble de composants Vue. Nous attacherons également des attributs SVG aux propriétés calculées et ferons en sorte que le graphique réponde aux modifications des données.
De plus, à la fin du projet, nous allons créer un composant qui est un panneau de configuration. Ce composant sera utilisé pour saisir les données qui seront transmises à la carte.
▍Lier des données aux paramètres viewBox
Commençons par ajuster le système de coordonnées. Sans cela, nous ne pourrons pas dessiner d'images SVG. La propriété
viewbox
calculée
viewbox
ce dont nous avons besoin en utilisant la variable de
size
. Il y aura quatre valeurs séparées par des espaces. Tout cela deviendra la valeur de l'attribut
viewBox
de l'élément
<svg>
.
viewbox() { return "0 0 " + this.size + " " + this.size; }
En SVG, le nom de l'attribut
viewBox
déjà écrit en utilisant le style camel.
<svg viewBox="0 0 1000 1000"> </svg>
Par conséquent, afin de lier correctement cet attribut à la propriété calculée, j'ai noté le nom de l'attribut dans le style kebab et mis le modificateur
.camel
après. Avec cette approche, il est possible de "tromper" le HTML et d'implémenter correctement la liaison d'attribut.
<svg :view-box.camel="viewbox"> ... </svg>
Maintenant, lorsque vous modifiez la
size
graphique est reconfiguré indépendamment. Nous n'avons pas besoin de modifier manuellement la mise en page.
▍Calcul des paramètres de courbe
Étant donné que la plupart des valeurs nécessaires pour construire les courbes sont calculées sur la base d'une seule variable (
size
), j'ai utilisé pour trouver toutes les coordonnées fixes par les propriétés calculées. Ce que nous appelons ici "coordonnées fixes" est calculé sur la base de la
size
, et après cela, il ne change pas et ne dépend pas du nombre de courbes que le diagramme inclura.
Si vous changez la
size
- "les coordonnées fixes" seront recomptées. Après cela, ils ne changeront pas avant le prochain changement de
size
. Compte tenu de ce qui précède, voici cinq valeurs dont nous avons besoin pour tracer des courbes de Bézier:
topHeight — size * 0.2
bottomHeight — size * 0.8
width — size
halfSize — size * 0.5
distance — size/arrayLength
Il ne nous reste plus que deux valeurs inconnues -
x2
et
x3
. La formule de calcul que nous avons déjà dérivée:
x = index * distance + (distance * 0.5)
Pour trouver des valeurs spécifiques, nous devons remplacer les indices des éléments du tableau dans cette formule.
Maintenant, demandons-nous si la propriété calculée nous convient pour trouver
x
. Répondez brièvement à cette question, alors - non, cela ne suffira pas.
Impossible de transmettre des paramètres à la propriété calculée. Le fait est que c'est une propriété, pas une fonction. De plus, la nécessité d'utiliser un paramètre pour calculer quelque chose signifie qu'il n'y a aucun avantage tangible à utiliser des propriétés calculées en termes de mise en cache.
Veuillez noter qu'il existe une exception concernant le principe ci-dessus. Il s'agit de Vuex. Si vous utilisez des getters Vuex qui renvoient des fonctions, vous pouvez leur transmettre des paramètres.
Dans ce cas, nous n'utilisons pas Vuex. Mais même dans cette situation, nous avons deux façons de résoudre ce problème.
▍ Numéro d'option 1
Vous pouvez déclarer une fonction à laquelle l'
index
passé en argument et qui renvoie le résultat dont nous avons besoin. Cette approche semble plus propre si nous allons utiliser la valeur renvoyée par une fonction similaire à plusieurs endroits du modèle.
<g v-for="(item, i) in itemArray"> <path :d="'M' + halfSize + ',' + (topHeight+r) +' '+ 'C' + halfSize + ',' + halfSize +' '+ calculateXPos(i) + ',' + halfSize +' '+ calculateXPos(i) + ',' + bottomHeight" /> </g>
La méthode
calculateXPos()
effectuera des calculs à chaque appel. Cette méthode prend comme argument l'indice de l'élément -
i
.
<script> methods: { calculateXPos (i) { return distance * i + (distance * 0.5) } } </script>
Voici un exemple sur CodePen qui utilise cette solution.
Écran de la première variante d'application▍ Option numéro 2
Cette option est meilleure que la première. Nous pouvons extraire le petit balisage SVG nécessaire pour construire la courbe dans un petit composant enfant séparé et lui passer l'
index
comme l'une des propriétés.
Avec cette approche, vous pouvez même utiliser la propriété calculée pour trouver
x2
et
x3
.
<g v-for="(item, i) in items"> <cubic-bezier :index="i" :half-size="halfSize" :top-height="topHeight" :bottom-height="bottomHeight" :r="radius" :d="distance" > </cubic-bezier> </g>
Cette option nous donne la possibilité de mieux organiser le code. Par exemple, nous pouvons créer un autre composant enfant pour le masque:
<clip-mask :title="title" :half-size="halfSize" :top-height="topHeight" :r="radius"> </clip-mask>
▍ Panneau de configuration
Panneau de configurationVous avez probablement déjà vu le panneau de configuration, appelé par le bouton situé dans le coin supérieur gauche de l'écran de l'
exemple ci-dessus. Ce panneau facilite l'ajout d'éléments au tableau et leur suppression. En suivant les idées discutées dans la section "Option # 2", j'ai créé un composant enfant pour le panneau de configuration. Grâce à cela, le composant de niveau supérieur est propre et bien lisible. En conséquence, notre petite arborescence de composants Vue ressemble à celle ci-dessous.
Arborescence des composants du projetVous voulez jeter un œil au code qui implémente cette version du projet? Si oui, jetez un œil
ici .
Écran de la deuxième variante d'applicationDépôt de projets
Voici le référentiel GitHub du projet ("Option # 2" est implémentée ici). Je pense qu'il vous sera utile de l'examiner avant de passer à la section suivante.
Devoirs
Essayez de créer le même diagramme que nous avons décrit ici, mais faites-le orienté verticalement. Profitez des idées décrites dans cet article.
Si vous pensez que c'est une tâche facile, que pour construire un tel diagramme il suffit d'échanger les coordonnées
x
et
y
, alors vous avez raison. Étant donné que le projet considéré ici n'a pas été créé comme universel, après avoir modifié les coordonnées là où vous en avez besoin, vous devrez également modifier le code en renommant certaines variables et méthodes.
Grâce à Vue.js, notre graphique simple peut être équipé de fonctionnalités supplémentaires. Par exemple, les éléments suivants:
- Vous pouvez créer un mécanisme qui vous permet de basculer entre les modes de graphique horizontal et vertical.
- Les courbes peuvent essayer d'animer. Par exemple, utiliser GSAP.
- Vous pouvez ajuster les propriétés des courbes (disons - couleur et largeur de ligne) depuis le panneau de configuration.
- Vous pouvez utiliser une bibliothèque externe pour organiser l'enregistrement des diagrammes dans n'importe quel format graphique ou sous forme de fichier PDF. Ces documents peuvent être téléchargés pour ceux qui travaillent avec le graphique.
Essayez ces devoirs. Et si vous avez des problèmes - ci-dessous sera donné un lien vers sa solution.
Résumé
L'élément
<path>
est l'une des puissantes fonctionnalités de SVG. Cet élément vous permet de créer diverses images avec une grande précision. Ici, nous avons compris comment les courbes de Bézier sont structurées et comment les mettre en pratique pour créer vos propres diagrammes.
, , JavaScript-. Vue.js . , , , , DOM. , — .
, , , , , Vue.js SVG. —
, Vue.js.
— .
, - , , , — .
Chers lecteurs! ?
