Aller au contenu

Options de rendu ​

Pivotick vous permet de personnaliser la façon dont les nœuds, les bords et les étiquettes sont rendus via l'option render.

avertissement

Tous les styles définis ici s'appliquent uniquement lorsque render.type est défini sur svg.

OptionsTypeValeur par défautDescription
type'svg' | 'canvas''svg'La méthode de rendu. 'svg' utilise les éléments SVG, 'canvas' utilise le canevas HTML (expérimental - pas entièrement implémenté).
renderNode(node: Node) => HTMLElement | string | voidundefinedMoteur de rendu personnalisé pour les nœuds.
renderLabel(edge: Edge) => HTMLElement | string | voidundefinedMoteur de rendu personnalisé pour les étiquettes de bord.
defaultNodeStyleNodeStyledefaultNodeStyleStyle par défaut appliqué à tous les nœuds.
defaultEdgeStyleEdgeStyledefaultEdgeStyleStyle par défaut appliqué à tous les bords.
defaultLabelStyleLabelStyledefaultLabelStyleStyle par défaut appliqué à toutes les étiquettes de bord.
markerStyleMapRecord<string, MarkerStyle>defaultMarkerStyleStyles personnalisés pour les marqueurs de bord ('arrow', 'diamond', etc.). Voir MarkerStyle
nodeTypeAccessor(node: Node) => string | undefinedundefinedFonction pour accéder au type d'un nœud, utilisé avec nodeStyleMap.
nodeStyleMapRecord<string, NodeStyle>{}Mappe les types de nœuds (de nodeTypeAccessor) aux styles.
edgeTypeAccessor(edge: Edge) => string | undefinedundefinedLe kind d'un bord, utilisé avec edgeStyleMap et comme clé layer.
edgeStyleMapRecord<string, Partial<EdgeStyle>>undefinedMappe les types de bords (de edgeTypeAccessor) aux styles. Voir Couches de bord.
minZoomnumber0.1Niveau de zoom minimum.
maxZoomnumber10Niveau de zoom maximum.
minFitScalenumberundefinedLe zoom le plus bas auquel un ajustement va. Un graphique trop grand pour y tenir s'ouvre avec ce zoom, centré sur fitAnchor, et la mini-carte montre le reste.
fitAnchorstringundefinedIdentifiant du nœud sur lequel un ajustement maintenu à minFitScale est centré. La vue s'arrête aux bords du graphique, donc une ancre d'un côté reste près de ce côté.
zoomEnabledbooleantrueActivez le zoom. false prend également en charge les boutons de zoom du rail de la fenêtre, en gardant l'ajustement et le centre.
selectionBoxSelectionBoxundefinedSélection de région : enabled: false supprime le rectangle de sélection et l'outil Sélectionner ▸ Lasso.
enableNodeExpansionbooleantrueExtension d'un cluster : false prend le chevron, le raccourci Enter et le contour réduit en pointillés avec lui. Un enfant sélectionné allume toujours son cluster fermé.

Type de rendu ​

conseil

Pivotick vous offre un contrôle flexible sur le rendu, des simples valeurs par défaut au rendu entièrement personnalisé. Voici un bref aperçu :

  • renderNode et renderLabel vous permettent de personnaliser entièrement la façon dont les nœuds et les étiquettes sont dessinés (vous pouvez renvoyer HTML ou du texte).
  • defaultNodeStyle.html (par nœud ou par type) est la même trappe de secours à l'intérieur de la chaîne de style — voir HTML nœuds.
  • nodeTypeAccessor + nodeStyleMap permettent un style dynamique basé sur le type de chaque élément.
  • defaultNodeStyle, defaultEdgeStyle et defaultLabelStyle définissent l'apparence de base de tous les éléments.
  • edgeTypeAccessor + edgeStyleMap sont les homologues de bord, et ils servent également de clé par laquelle un calque de relation est désactivé — voir Couches de bord.

Votre carte est mesurée, quelle que soit sa forme

Pivotick mesure ce que vous retournez pour dimensionner son <foreignObject> et pour alimenter le rayon de collision de la disposition des forces. La carte est mesurée à l'intérieur d'une boîte de rétrécissement propre à la bibliothèque, vous n'avez donc pas de faire en sorte que votre racine s'auto-dimensionne : width: 100% dessus se résout par rapport à son propre contenu plutôt que par rapport à l'espace réservé.

Les trois exemples de rendu suivants utilisent les données suivantes :

ts
const data = {
    nodes: [
        { id: 1, data: { label: 'A', type: 'hub' } },
        { id: 2, data: { label: 'B', type: 'spoke' } }
    ],
    edges: [{ from: 1, to: 2 }]
}
js
const options = {
    render: {
        defaultNodeStyle: {
            shape: 'circle',
            color: '#007acc',
            size: 12,
            strokeColor: '#fff',
            strokeWidth: 2,
            fontFamily: 'system-ui',
            textColor: '#fff'
        },
        defaultEdgeStyle: {
            markerStart: (edge: Edge) => edge.getData().mstart,
            markerEnd: 'arrow',
            curveStyle: 'straight',
        },
    }
}
js
const options = {
    render: {
        nodeTypeAccessor: (node) => node.getData()?.type,
        nodeStyleMap: {
            'hub': {
                shape: 'hexagon',
                color: '#f90',
                size: 25,
                text: (node) => node.getData()?.label
            },
            'spoke': {
                shape: 'triangle',
                color: '#09f'
            }
        },
    },
    UI: {
        mode: 'static'
    }
}
js
const options = {
    render: {
        renderNode: (node: Node): HTMLElement | string | void => {
            const size = 12
            const color = '#09f'
            const style = [
                'display: block',
                `width: ${size}px`,
                `height: ${size}px`,
                `background-color: ${color}`,
                'border: 2px solid #fff',
                'border-radius: 50%',
                'opacity: 1',
            ].join(';')

            return `<span style="${style}"></span>`
        }
    }
}

Exemple de rendu Map-Accessor ​

HTML nœuds ​

Lorsqu'aucune combinaison de shape, color, icon et text ne suffit, donnez au moteur de rendu un balisage. Il y a deux manières d'entrer, et la différence est seulement où elles sont déclarées :

Déclaré leAtteint
NodeStyle.htmldefaultNodeStyle, nodeStyleMap[type], le style propre d'un nœud, un retour styleCbun type ou un nœud
render.renderNodeles options du moteur de renduchaque nœud, en avance sur la chaîne de style

html est celui à atteindre en premier : c'est un canal de style ordinaire, il se résout donc via la même chaîne de priorité que color ou shape, et une carte peut être donnée à un type de nœud tandis que les autres conservent leur forme.

ts
const options = {
    render: {
        nodeTypeAccessor: (node) => node.getData()?.kind,
        nodeStyleMap: {
            // A card, and nothing else: `shape: 'none'` is what makes it the whole node.
            service: {
                shape: 'none',
                html: (node) => {
                    const card = document.createElement('div')
                    card.className = 'my-service-card'
                    card.textContent = node.getData()?.name
                    return card
                },
            },
            // Same graph, ordinary shapes.
            host: { shape: 'circle', size: 18, color: '#0891b2' },
        },
    },
}

shape: 'none' ​

Sans cela, la forme est toujours dessinée derrière votre carte, et size est le plus petit que le nœud peut être – ce qui est ce que vous voulez pour une carte posée sur un disque coloré, et non ce que vous voulez pour une carte qui est le nœud. shape: 'none' ne dessine aucune forme et transmet à la carte le rayon de collision et les ancres de bord du nœud.

C'est une valeur de forme comme une autre, donc elle compose : un nœud d'étiquette uniquement est shape: 'none' avec un text et aucune carte, et un nœud uniquement d'icône est shape: 'none' avec un iconClass. Un nœud informe sans aucun contenu est invisible – mais toujours là, toujours déplaçable et toujours sélectionnable sur 2 × size.

Quelle carte pas éteint

text est un canal séparé, donc une carte et une étiquette de nœud sont dessinées ensemble. Si votre carte porte son propre titre, définissez text: '' — une valeur héritée ne peut pas être effacée avec undefined, ce qui correspond à ce que dit la carte de style.

Dimensionnement ​

Votre carte est mesurée et le nœud s'y développe, de sorte qu'il n'est jamais coupé, la force de collision espace les vraies cartes et les bords atterrissent sur la bordure de la carte plutôt que sur un cercle autour d'elle. Vous n'avez rien à faire pour que cela fonctionne - renvoyer une racine width: 100% est très bien, car la mesure s'effectue dans une boîte rétrécie pour s'adapter.

Deux conséquences à connaître :

  • La mesure est asynchrone (une carte ne peut pas être mesurée avant d'être à l'écran), donc le rayon d'un nœud est stylisé size pour la première ou les deux premières images, puis devient celui de la carte. La mise en page est décalée une fois lorsque celle-ci atterrit.
  • Une carte est mesurée une fois, au rendu. Si son contenu change de taille par la suite, effectuez un nouveau rendu du nœud pour le mesurer à nouveau.

Carder seulement certains nœuds ​

Les deux rappels peuvent renvoyer rien pour un nœud, qui renvoie ce nœud à la chaîne de style - forme, entrée de carte de style, icônes et étiquette comme d'habitude. Ainsi, un seul renderNode global peut carder les nœuds qui en méritent un :

ts
renderNode: (node) => node.getData()?.featured ? buildCard(node) : undefined

Balisage approuvé uniquement

Tout ce que vous retournez est inséré tel quel. Construisez-le avec textContent ou échappez-le — n'interpolez pas les données du nœud dans une chaîne de balisage. Consultez le guide de sécurité.

Étiquettes de nœud complètes ​

Une étiquette de nœud plus longue que la pièce dont elle dispose est raccourcie avec des points de suspension au milieu (Supe…abel). Définissez textTruncate: false pour le dessiner dans son intégralité — par défaut, par type de nœud ou par nœud :

ts
const options = {
    render: {
        defaultNodeStyle: { textTruncate: false },
    },
}

Entre les deux, textMaxWidth termine l'étiquette à une largeur que vous choisissez, en unités graphiques (CSS pixels au zoom 1), au lieu de la pièce que le nœud lui donne. Une étiquette qui convient est dessinée dans son intégralité, et une étiquette plus longue est raccourcie avec des points de suspension au milieu à cette largeur :

ts
const options = {
    render: {
        defaultNodeStyle: { textTruncate: true, textMaxWidth: 160 },
    },
}

Taille de la police de l'étiquette ​

Une étiquette de nœud est dessinée à max(12, size × 0.45) par défaut, elle grandit donc avec le nœud. Lorsqu'un nœud est grand pour ce qu'il dessine plutôt que pour son importance, comme une vignette d'image, définissez textFontSize (unités graphiques) pour que son étiquette reste alignée avec ses voisins :

ts
const options = {
    render: {
        nodeStyleMap: {
            image: { size: 80, imagePath: (node) => node.getData()?.url, textFontSize: 12 },
        },
    },
}

L'étiquette se trouve toujours juste à côté du nœud, le budget intégré prend toujours sa largeur à partir du nœud (donc une police plus petite peut contenir plus de caractères) et le zoom gate le juge en fonction de la taille que vous avez définie.

Le capuchon évolue avec le zoom comme le reste du nœud, et peut être fonction du nœud. Il est ignoré lorsque textTruncate est false.

Une étiquette pleine ou coiffée dépasse généralement la forme du nœud, elle est donc dessinée sur le même thème qu'une étiquette flottante pour rester lisible sur la toile. Associez-le à textVerticalShift: 1 (ou textHorizontalShift) pour déplacer toute l'étiquette hors du nœud. Les étiquettes de bord ne sont jamais tronquées.

text est une étiquette sur un nœud, et ne remplace pas celle-ci. Un nœud qui est son texte doit être dessiné comme le nœud, en passant par html, renderNode ou un tier — ce sont le dessin du nœud, et le zoom les conserve quel que soit minLabelFontSize fait aux étiquettes.

Insignes de nœud ​

Au moment où un graphique est utile, color, shape, size et iconClass portent généralement tous quelque chose. badges est un canal à part entière : de petits indicateurs épinglés sur le bord du nœud, ne dépensant aucun des autres :

ts
const options = {
    render: {
        defaultNodeStyle: {
            badges: (node) => {
                const { notes, disputed } = node.getData()
                return [
                    notes && { text: String(notes), color: '#2563eb', title: `${notes} notes` },
                    disputed && { iconClass: 'fa fa-exclamation', color: '#b94a48', title: 'Disputed' },
                ].filter(Boolean)
            },
        },
    },
}

Donnez un badge text (un nombre, ou un caractère ou deux), un iconClass, iconUnicode ou svgIcon et un title pour son info-bulle native. text gagne si vous fournissez les deux. Un texte plus long transforme le badge en une pilule, et au-delà de trois caractères, il affiche 99+.

Où ils vont ​

Omettez position et les badges remplissent les coins libres dans le sens des aiguilles d'une montre à partir de 'ne'. Nommez-en un ('ne' | 'nw' | 'se' | 'sw') et il est honoré textuellement, chevauchements inclus.

Quatre ajustements sur un nœud simple, deux contre un avec des enfants. Le contrôle d'expansion/réduction se trouve au nord-est lorsqu'un nœud est réduit et au sud-est lorsqu'il est développé, donc sur tout nœud extensible les deux Les coins est sont réservés — sinon chaque badge changerait de coin au moment où un cluster s'ouvrirait. Les badges au-delà de ce qui convient se replient dans un +n dont l'info-bulle les nomme.

Les badges évoluent avec le nœud entre le sol et le plafond, de sorte qu'ils restent lisibles sur un petit nœud sans gonfler sur un grand, et ils reposent sur le véritable bord de la forme - le coin d'un carré ou d'une image encadrée, le point à 45° d'un cercle.

Clics ​

Un badge est testable mais transparent par défaut : sans gestionnaire, son clic échoue et sélectionne le nœud en dessous, donc un badge n'est jamais un point mort.

ts
{ text: '3', onClick: (event, node, badge) => openNotes(node) }

Donnez à un badge un onClick — ou déclarez callbacks.onBadgeClick pour le comportement qu'ils partagent tous — et il prend le curseur du pointeur et consomme son clic, laissant le nœud non sélectionné. Les deux tirent, celui de l'insigne en premier. Appuyer sur un badge fait toujours glisser le nœud dans un sens ou dans l'autre, et un auditeur badgeClick sur le bus d'interaction peut cancel() les deux.

Portée ​

Les badges décrivent ** uniquement le nœud sur lequel ils se trouvent **. Un cluster réduit n'agrège pas ses enfants - parcourez node.children dans votre propre fonction badges si c'est ce que vous voulez, puisque vous seul savez si un fait totalise, gagne ou ni l'un ni l'autre.

Détail qui suit le zoom ​

Un dessin qui se lit bien de près est illisible sur un aperçu, et un point qui s'adapte à un aperçu ne peut pas dire de quoi il s'agit. tiers permet à un nœud de transporter plusieurs dessins et de choisir entre eux en fonction de la taille actuelle du nœud.

ts
const options = {
    render: {
        defaultNodeStyle: {
            tiers: [
                // Small: a coloured dot.
                { width: 32, height: 32, style: { shape: 'circle', size: 16 } },
                // Once there is room for it: a labelled chip.
                { width: 140, height: 44, style: { shape: 'none', html: buildChip } },
            ],
        },
    },
}

Les niveaux sont classés en premier et le plus riche qui correspond gagne. Quand aucun ne le fait, le nœud dessine à son style de base, donc le style que vous avez déjà est le sol : un graphique qui déclare non tiers n'est pas affecté à tous égards.

De quel niveau hérite ​

Un niveau fusionne sur le style de base, de sorte qu'un canal qu'il ne nomme pas est hérité. Le dessin est l'exception : iconUnicode, iconClass, svgIcon, imagePath et html sont un seul emplacement, donc un niveau qui nomme l'un d'entre eux remplace carrément le dessin de la base (et son imageFit). Un glyphe au repos avec un niveau de carte n'a besoin que de la carte :

ts
const options = {
    render: {
        defaultNodeStyle: {
            svgIcon: buildGlyph,
            tiers: [
                { width: 140, height: 44, style: { shape: 'none', html: buildChip } },
            ],
        },
    },
}

Un niveau qui ne nomme aucun dessin, seulement size, color ou text disons, conserve le glyphe de base.

Pour supprimer un canal que le niveau ne remplace pas autrement, définissez-le sur null, ce qui signifie que le niveau dessine celui-là pas du tout. strokeColor: null supprime le contour de la base, par exemple. undefined ne peut pas remplacer : cela signifie "Je ne nomme pas ce canal", ce qui est exactement ainsi que la valeur de la base survit.

C'est la seule couche où null fonctionne de cette façon. Partout ailleurs dans la chaîne de styles, null tombe toujours dans la couche inférieure, car un styleCb restituant une valeur nulle directement à partir des données du nœud est une forme ordinaire et a toujours signifié "utiliser la valeur par défaut".

Pour rendre un nœud informe, utilisez shape: 'none' plutôt que d'effacer shape.

Qu'est-ce qui choisit un niveau ​

La taille rendue : l'empreinte du nœud en CSS pixels, soit footprint × zoom. Un niveau s'engage une fois qu'il atteint son minRenderedSize, qui est par défaut le propre width du niveau, donc { width: 140 } se lit comme "s'engager une fois qu'il y a de la place pour dessiner 140 pixels de nœud".

L’échelle de zoom à elle seule ne suffirait pas. Il multiplie les coordonnées de la disposition inventée, de sorte que la même échelle signifie une taille apparente différente sur un graphique différent, et un seuil réglé sur un ensemble de données serait erroné sur le suivant.

Un niveau engagé est conservé jusqu'à ce que la taille rendue tombe à 85 % de son seuil. Chaque nœud partage un seuil, donc sans cette bande, une toile garée sur l'un d'entre eux scintillerait dans son ensemble.

L'empreinte reste en place ​

La boîte qu'un nœud réserve dans la mise en page ne change pas lorsque son dessin change. Il s'agit de layoutSize, et la valeur par défaut est la moitié du niveau déclaré le plus large, donc déclarer les niveaux donne au graphique le bon espacement sans deuxième nombre. Rien ne bouge lors d'un échange de niveaux : le dessin change à l'intérieur d'une case déjà de la bonne taille, et les forces ne voient jamais la différence.

width et height sont déclarés plutôt que mesurés, pour la même raison. La mise en page doit connaître l'empreinte avant le premier tick, et une carte mesurée ne rapporte sa taille qu'une fois dessinée.

Réglez vous-même layoutSize pour espacer le graphique plus serré ou plus large que le niveau le plus large. Notez qu'un niveau est dessiné à sa taille de conception uniquement lorsque sa largeur est égale à l'empreinte au sol ; un plus étroit s'engage proportionnellement plus tôt et est tiré proportionnellement plus petit. Donnez-lui un minRenderedSize explicite si cela compte.

Le dessin de mise au point ​

focusTier est le dessin qu'un nœud utilise lorsqu'il est survolé, ou sélectionné seul, quel que soit le zoom. C'est là qu'un nœud dit tout sur lui-même, donc en lire un ne signifie jamais zoomer dessus.

ts
const options = {
    render: {
        defaultNodeStyle: {
            tiers: [/* … */],
            focusTier: { shape: 'none', html: buildDetailCard },
        },
    },
}

Il fusionne sur le style base du nœud plutôt que sur le niveau actif, de sorte que le shape ou html d'un niveau de puce ne peut pas y pénétrer. Il a une taille constante à l'écran : le dessin est à l'échelle opposée au zoom, donc une carte 280×150 fait 280×150 CSS pixels, quelle que soit la distance du graphique. Et cela ne touche jamais la géométrie du nœud, donc les bords continuent d'atterrir sur le niveau inférieur et le survol ne déplace rien.

Le dessin de focus porte les badges du nœud sur son propre bord, à la même taille à l'écran que la carte. Les propres badges du nœud sont masqués pendant qu'il s'affiche, donc aucun n'est dessiné deux fois. Donnez à focusTier un badges qui lui est propre pour afficher un ensemble différent sur la carte.

Seul un nœud sélectionné ** seul** est promu. Une sélection de boîte de cinquante nœuds serait un mur de cartes qui se chevauchent.

render.focusTierTrigger indique quand il se déclenche : 'both' (la valeur par défaut), 'hover', 'selection' ou 'off'. Atteignez 'off' lorsque vous intégrez un style prédéfini que quelqu'un d'autre expédie et que vous souhaitez que son dessin de focus soit supprimé sans le modifier.

Lorsqu'un niveau l'affiche déjà ​

Parfois, le dessin de mise au point est le même que celui de l'un des niveaux de zoom : un glyphe au repos qui plane dans une puce, la puce étant également dessinée une fois que le graphique est suffisamment zoomé. Là, le survol peindrait une deuxième puce, plus petite, sur celle déjà à l'écran. focusTierYieldsAt nomme l'index dans tiers à partir duquel le dessin du focus cesse de se déclencher :

ts
defaultNodeStyle: {
    tiers: [{ width: 140, height: 44, style: { shape: 'none', html: chipFor } }],
    focusTier: { shape: 'none', html: chipFor },
    focusTierYieldsAt: 0,
}

Pendant que le nœud est dessiné à ce niveau ou à un niveau plus riche, survolez-le et une seule sélection le laisse tel quel. Il suit le niveau actif, et non le niveau de zoom, il utilise donc les mêmes seuils que le swap. Un zoom avant avec la carte ouverte la fait disparaître à mesure que le niveau apparaît, et un zoom arrière la ramène sans déplacer le pointeur. Laissez-le non défini sur un nœud dont le dessin de focus en dit plus que n'importe quel niveau, et un nœud sans tiers l'ignore.

Les info-bulles s'allument toujours

Une carte de focus ne remplace pas l'info-bulle. Les deux sont indépendants et une info-bulle peut contenir quelque chose que la carte ne contient pas.

L'échange lui-même ​

Un nœud effectue un fondu enchaîné d'un dessin au suivant plutôt que d'y accéder. Le dessin sortant est conservé sur un calque qui lui est propre et les deux se fondent l'un devant l'autre, de sorte qu'un nœud n'est jamais absent à mi-échange, seulement brièvement plus doux là où ils se chevauchent.

render.detailTransition est le temps que cela prend, en millisecondes. Sa valeur par défaut est 160 et couvre tous les dessins décidés par le zoom : un croisement de niveaux, le dessin ciblé et un croisement d'étiquettes minLabelFontSize. Réglez-le sur 0 pour remplacer le dessin dans un seul cadre :

ts
const options = {
    render: {
        detailTransition: 0,
        defaultNodeStyle: { tiers: [/* … */] },
    },
}

Chaque nœud à l'écran se croise au même moment, donc un croisement déclenche autant de fondus qu'il y a de nœuds qui changent. Mesuré sur 210 nœuds contenant chacun une carte 140×44, le fondu s'exécute à 60 ips sur toute sa longueur ; ce que cela coûte est d'environ 26 ms sur la seule image que la traversée dépense déjà, et ce chiffre n'augmente pas avec la durée. Désactivez-le sur un graphique où ce cadre compte plus que la transition.

prefers-reduced-motion l'éteint tout seul, quelle que soit l'option choisie.

Étiquettes à une taille lisible ​

Une étiquette chevauche le graphique et évolue avec lui, de sorte que plus la vue est éloignée, plus elle est peinte. Un graphique s'ouvre à l'échelle choisie par l'ajustement, et cette échelle diminue à mesure que le graphique grandit : au-delà de quelques centaines de nœuds, le cadre d'ouverture est un texte que personne ne peut lire, dessiné sur le graphique qu'il nomme.

render.minLabelFontSize est la taille de rendu, en CSS pixels, en dessous de laquelle aucune étiquette n'est dessinée. La valeur par défaut est 9.

ts
const options = {
    render: {
        minLabelFontSize: 9,
    },
}

Le test est fontSize × zoom, en pixels rendus plutôt qu'en échelle de zoom : une échelle multiplie les coordonnées de la mise en page inventée, donc la même valeur signifie une taille apparente différente sur l'ensemble de données suivant.

Il s'agit d'un numéro pour l'ensemble du canevas, les étiquettes de bord et les étiquettes de nœuds. La différence entre eux réside déjà dans la taille de la police : une étiquette de bord est dessinée à defaultLabelStyle.fontSize (12 par défaut), tandis que celle d'un nœud est dérivée du nœud, max(12, size × 0.45), donc un grand nœud garde son étiquette avec un zoom inférieur à celui d'un petit. Le textFontSize d'un style de nœud remplace cette taille dérivée.

0 désactive la porte et dessine chaque étiquette à chaque zoom.

Ce qui compte comme étiquette

Le texte que la bibliothèque place : le label d'un bord, le text d'un nœud et tout ce que render.renderLabel renvoie. Le html, renderNode ou la carte de niveau d'un nœud est son dessin, et tiers est ce qui choisit entre les dessins.

Une étiquette affichée est conservée jusqu'à ce que sa taille rendue tombe à 85 % du seuil, de sorte qu'une vue stationnée sur la ligne se stabilise au lieu de scintiller. Chaque étiquette dessinée à une taille unique répond ensemble, quel que soit l'élément auquel elle appartient.

Un bord sélectionné ** seul ** affiche son étiquette quel que soit le zoom, contre-dimensionné pour qu'il soit lisible plutôt que les deux pixels sur lesquels il était masqué. Un bord n'a ni info-bulle ni panneau, donc son étiquette est la seule chose qui répond "qu'est-ce que c'est". Un nœud n'a besoin de rien de tout cela : il répond déjà via son info-bulle, la barre latérale et son focusTier dessin.

Une étiquette cachée n’est pas simplement invisible, elle ne figure pas dans le graphique – c’est là que va le coût. Une étiquette est repositionnée à chaque tick de simulation, et sur un grand graphique, un passage seul coûte plus cher qu'un cadre. Ce qui reste après le portail, c'est le coup, qui est bon marché.

Ce qu'il ne fait pas

Au-dessus du seuil, les étiquettes peuvent toujours se chevaucher. Une étiquette de bord est généralement plus large que le bord qu'elle nomme, et ce rapport ne change pas avec le zoom. Cette option concerne la lisibilité et non le désencombrement.

API ​

Pivotick expose un contrôleur de rendu qui vous permet d'interagir directement avec le moteur de rendu. Toutes les méthodes sont disponibles en ligne

Ajuster et zoomer ​

ts
graph.renderer.fitAndCenter()
ts
graph.renderer.zoomIn()
graph.renderer.zoomOut()