Naar inhoud

Legende ​

UI.legend koppelt een legende in een canvashoek: één rij per categorie, elk met een kleurstaal, een label en het aantal knooppunten erachter. Wijzend naar een rij lichten die categorie op het canvas; Als u erop klikt, wordt deze verborgen, zodat de legenda ook dienst doet als de snelste filter in de gebruikersinterface.

ts
const options = {
    UI: {
        legend: { key: 'type', title: 'Node type' },
    },
}

Het kan zijn dat je dat blok helemaal niet nodig hebt: zonder UI.legend verschijnt er een legenda op zijn own wanneer de kleuren van uw grafiek worden verklaard door een gedeclareerde render.nodeTypeAccessor — zie Standaard ingeschakeld. UI.legend: false schakelt het uit.

Een grafiek die meerdere dingen tegelijk codeert, heeft meerdere sleutels nodig: pass sections in plaats van een enkele sleutel — zie Meerdere sleutels tegelijk.

De legenda maakt deel uit van het chroom en verschijnt dus alleen in de modi full en light — viewer en static hebben er geen.

De legende kleurt nooit iets

De legenda is beschrijvend. Het leest de kleur waarvoor de renderer al heeft gekozen een knooppunt (renderer.getNodeStyle(node).color) en rapporteert dit. Het kleuren blijft waar het is was: render.defaultNodeStyle.color, render.nodeStyleMap, of een stijl per knooppunt — meestal via ColorPaletteMapper. Verander het palet en de legenda volgt vanzelf.

Standaard ingeschakeld ​

Een legende is alleen de moeite waard om ongevraagd te laten zien als deze gegarandeerd de waarheid vertelt automatisch gaat men uit van iets dat u al heeft aangegeven, en niet van een gok over uw gegevens: render.nodeTypeAccessor, de dimensie waarnaar u wijst nodeStyleMap op.

Het hebben van een kandidaat is echter niet voldoende: een dimensie kan uw gegevens zonder een partitie verdelen iets met de kleuren te maken heeft. Dus voordat er iets wordt weergegeven, de legende controleert of deze dimensie de kleuren verklaart:

  • elke categorie wordt omgezet in precies één kleur;
  • er zijn minstens twee verschillende kleuren (anders zijn de kleuren niet duidelijk de categorieën uit elkaar);
  • er zijn maximaal 24 categorieën — een id-achtige dimensie levert één waarde per knooppunt, elk met een eigen kleur, die anders door de bovenstaande controle zou komen.

Als een van deze dingen niet lukt, verschijnt er geen legenda en wordt er niets vastgelegd: je hebt er niet om gevraagd. De automatische legenda wordt ook overgeslagen voorbij 5000 knooppunten, waarbij de kleur is niet de moeite waard om onuitgenodigd voor te betalen – dat waarschuwt men, dus de afwezigheid is dat wel verklaarbaar. Als u UI.legend (of true) declareert, worden beide opgeheven.

ts
// nothing declared → a legend appears iff `type` explains the colours
render: { nodeTypeAccessor: (node) => node.getData().type, nodeStyleMap: { … } }

UI: { legend: false }   // never
UI: { legend: true }    // derive from nodeTypeAccessor, check or no check
UI: { legend: { position: 'top-right' } }   // automatic entries, your placement

Een automatische legendasleutel op een accessor in plaats van op een gegevenssleutel, dus dat kan niet deel een filter met een gedeclareerd facet — geef het een expliciet key daarvoor.

Waar de inzendingen vandaan komen ​

Afgeleid van een gegevenssleutel ​

key is de gehele configuratie in het algemene geval: de verschillende waarden van node.getData()[key] worden de rijen, in de volgorde van het eerst gezien, gelabeld met de waarde zelf.

ts
UI: { legend: { key: 'type' } }

Een sleutel met een matrixwaarde array-waarde draagt één rij per element bij, en een knooppunt telt mee onder elk van hen (tags: ['public', 'critical'] verschijnt onder beide).

Er zijn twee dingen die de moeite waard zijn om te weten over afgeleide rijen:

  • Knooppunten zonder waarde voor de sleutel (null, undefined, '') krijgen geen rij, en de Legend kan ze nooit verbergen - het werkt alleen op de categorieën die het vermeldt. Een ontwikkeltijd waarschuwing noemt de sleutel en hoeveel knooppunten niet vertegenwoordigd zijn.
  • Een categorie die in meer dan één kleur is geschilderd behoudt de eerste gevonden kleur, met een waarschuwing: één rij kan slechts één staal weergeven. Geef de boekingen zelf aan als de groeperen is niet echt één kleur.

Aangegeven inzendingen ​

Geef entries door als de categorieën geen gewone gegevenssleutel zijn: berekende groeperingen, vertaalde labels, een vaste kleurenschaal. Elke invoer heeft zijn eigen predicate, dat is waar de schakelaar op filtert.

ts
UI: {
    legend: {
        title: 'Tier',
        entries: [
            { id: 'edge', label: 'Edge', color: '#0072B2',
              predicate: (node) => node.getData().type === 'web' },
            { id: 'storage', label: 'Storage', color: '#009E73',
              predicate: (node) => ['database', 'cache'].includes(node.getData().type) },
        ],
    },
}

entries kan ook een functie van de grafiek zijn, die opnieuw wordt opgelost wanneer de gegevens verandert - dus de lijst volgt de gegevens zonder dat de aangifte karnt:

ts
UI: {
    legend: {
        key: 'type',
        entries: (graph) => distinct(graph, 'type').map((type) => ({
            id: type,
            label: t(`type.${type}`),        // translated, used verbatim
            color: palette.getColor(type),
        })),
    },
}

Het declareren van zowel entries als key is de nuttige middenweg die hierboven wordt weergegeven: de vermeldingen geven de labels en kleuren, en key levert het standaardpredikaat (data[key] === id) voor vermeldingen die er geen hebben. Een vermelding zonder waarschuwingen en komt met niets overeen.

De schakelstatus van een rij overleeft een herresolutie; een vermelding die uit de gegevens verdwijnt verliest het in plaats van te blijven hangen als een verborgen geest.

Meerdere sleutels tegelijk ​

Een grafiek die drie dingen codeert: soort in de vulling, herkomst in de behuizing, relatie in één slag – heeft drie sleutels nodig, niet één. Geef sections door en iedereen krijgt zijn eigen blok met de titel, van boven naar beneden gestapeld in declaratievolgorde in één gekoppeld kaart:

ts
UI: {
    legend: {
        position: 'bottom-left',        // the card docks; sections don't
        sections: [
            { key: 'type',  title: 'Element' },
            { key: 'scope', title: 'Provenance' },
            { key: 'tlp',   title: 'Sharing', filterable: false },
        ],
    },
}

Een sectie bevat alles wat een enkele legenda bevat, behalve position, waartoe behoort de kaart. Secties zijn in elk ander opzicht onafhankelijk: hun eigen inzendingen, hun eigen tellingen, hun eigen vouwstatus, hun eigen filter.

Filters en samen ​

Elke filterbare sectie stuurt zijn eigen filter aan, en de query-engine stuurt deze aan: schakel attribute uit in het eerste deel en self uit in het tweede, en wat dat op het canvas blijft staan, zijn de knooppunten die geen van beide zijn. De show all van elke sectie wist alleen dat gedeelte.

Een sectie schrijft naar __legend:<id>, waarbij de id de id van de sectie is, anders is key, anders zijn plaats in de stapel (section-0). Een single-key legenda — het object vorm — behoudt de gewone __legend die hij altijd heeft gebruikt. Zoals bij een enkele legende, een sectie waarvan key een verklaard select / multiselect facet noemt stuurt in plaats daarvan dat facet, en zijn broers en zussen zijn onaangetast.

Randen in plaats van knooppunten sleutelen ​

Een sectie waarin scope: 'edge' wordt gedeclareerd, vermeldt de relatiesoorten van de grafiek met een lijn staal – lijnkleur, streepje en markering zoals de renderer ze heeft opgelost – en de bijbehorende schakelaars verberg randlagen in plaats van knooppunten. Het bevindt zich naast secties met een knooppuntbereik op dezelfde kaart en laat ze onaangeroerd. Zie Randlagen voor het hele object.

ts
UI: {
    legend: {
        sections: [
            { key: 'type', title: 'Element' },
            { key: 'kind', title: 'Relationship', scope: 'edge' },
        ],
    },
}

De dimensie benoemen waarop u stijlt ​

Een sectie zonder key noch entries is de dimensie die u al heeft aangegeven render.nodeTypeAccessor — de enige spelling voor een stijldimensie die geen a is gewone gegevenssleutel. De kleurcontrole wordt overgeslagen: in een lijst sections je vroeg erom. Slechts één sectie mag dit doen; een seconde valt weg met een waarschuwing.

ts
UI: { legend: { sections: [{}, { key: 'scope', title: 'Provenance' }] } }
//                         ↑ whatever nodeTypeAccessor returns, headed "Type"

Een sectie sloot de kleurdimensie af

Stalen worden bemonsterd uit de kleuren die de renderer heeft opgelost, en dat is de enige kanaal dat de legende kan lezen. Een sectie die is afgestemd op een dimensie die de kleuren niet coderen — herkomst, wanneer de herkomst als bijlage wordt getekend — krijgt de kleur van de eerste node in elke categorie, en waarschuwt dat de categorie er meer dan één oplevert. Verklaar entries met uw eigen color in dat gedeelte om er stalen van te maken die betekenen iets.

Ruimte ​

Secties vouwen afzonderlijk; alt-klik op een punthaak om het geheel te vouwen of uit te vouwen stapel in één keer. Elke sectie scrollt nog steeds door zijn eigen lijst voorbij maxVisibleEntries, en de kaart als geheel wordt tegen de hoogte van het canvas geplaatst en scrollt in plaats van groeit er voorbij - zodat zes secties binnen de viewport blijven.

Een sectie die resulteert in geen vermeldingen (een sleutel die geen knooppunt bevat, een lege declaratie) wordt volledig overgeslagen in plaats van weergegeven als een leeg vak met een titel; een kaart waarvan de secties allemaal leeg zijn, levert helemaal niets op.

Een categorie aanwijzen ​

Wijs een rij aan en het canvas antwoordt: de elementen waar die categorie voor staat, behouden de Kijk, al het andere wordt gedimd totdat de wijzer weggaat. Niets wordt gefilterd en er beweegt niets, dus het is de goedkope manier om uit te vinden waar een categorie zich bevindt voordat u een beslissing neemt of u deze wilt uitschakelen.

Een rij in een sectie scope: 'edge' verlicht zijn lijnen, waarbij de knooppunten zich samen met de andere lagen terugtrekken. Een rand gevouwen tot een een gesloten cluster of een simplify groep verlicht de lijn die op zijn plaats is getrokken.

Als u naar een categorie wijst die al is uitgeschakeld, wordt niets gedimd: er is niets op het canvas gelaten om het te laten oplichten.

highlightOnHover: false schakelt het uit voor een sectie. Een filterable: false-toets hoogtepunten ook, waar dit het enige is wat een rij doet.

Dezelfde set kan worden verlicht vanuit code en blijft behouden totdat deze wordt gewist:

js
graph.emphasiseElements(graph.getMutableNodes().filter((node) => node.getData()?.type === 'md5'))
graph.clearEmphasis()

Beide nemen de elementen die de renderer heeft getekend, dus lezen ze getMutableNodes() / getMutableEdges() in plaats van de kloneringsgetters.

Filteren ​

Als u een rij omschakelt, wordt een filter naar graph.queryEngine geschreven — dezelfde engine als de filterpaneel schijven — dus niets ervan is een tweede, parallelle mechanisme:

  • Knooppunten toegevoegd na een schakelaar, in een verborgen categorie, komen verborgen aan.
  • Een verborgen categorie blijft verborgen in de subgrafiek van een uitgevouwen cluster.
  • resetFilters(), of de Reset van het paneel, verlicht elke rij opnieuw.
  • Bij elke getoonde rij is het filter removed, dus het aantal actieve filters van de header rapporteert geen legende die niets verbergt.

Standaard bezit de legenda een gereserveerde filtersleutel (__legend) die overeenkomt via een predikaat — één per sectie, met de naamruimte __legend:<id>, in de gestapelde vorm.

Een filter delen met het paneel ​

Wanneer key een aangegeven select / multiselect noemt facet, de legenda stuurt in plaats daarvan de sleutel van dat facet aan. De legenda en het paneel worden dan twee weergaven van één filter: schakel een staal uit en de multiselect van het paneel verlaagt die waarde; kies waarden in het paneel en de legenda wordt overeenkomstig opnieuw verlicht.

ts
UI: {
    filter: { facets: [{ key: 'type', label: 'Type', type: 'multiselect', options: … }] },
    legend: { key: 'type' },   // ⇒ writes setFilter('type', …)
}

Twee gevolgen van het spreken van de taal van het panel:

  • Een lege multiselect betekent geen beperking voor het paneel, dus de legenda kan dat niet express "alles verbergen": de laatst getoonde rij is uitgeschakeld in plaats van a te schrijven waarde die de hele grafiek terug zou brengen. Een legenda op zijn eigen toonsoort heeft zoiets niet limiet.
  • Knooppunten met geen waarde voor de sleutel worden door elke selectie verborgen, precies zoals ze zijn wanneer u vanuit het paneel filtert.

Als key een facet van een ander type (text, regex, numberRange, boolean) benoemt, legenda behoudt zijn eigen sleutel en waarschuwt: een waardenlijst heeft daar geen betekenis.

Het lezen van de schakelaars ​

Elke schakelaar wordt aangekondigd op de data-gebeurtenisbus:

ts
graph.on('legendToggle', ({ section, hidden, visible }) => {
    localStorage.setItem(`legend.hidden.${section}`, JSON.stringify(hidden))
})

section is de id van de sectie die is omgeschakeld, en hidden / visible is dat rijen van sectie. Een legenda voor één sleutel rapporteert zijn eigen afgeleide ID (zijn key, else section-0).

Herstellen is dezelfde oproep die de legende doet:

ts
graph.queryEngine.setFilter('__legend', { value: visible, matchMode: 'exact' })

De legenda tijdens runtime wijzigen ​

graph.setLegend(config) vervangt UI.legend live. Een grafiek die begon zonder a legende laat er ter plekke een bouwen, en false verwijdert deze — het filter wordt gewist met zodat niets verborgen blijft achter een legende die verdwenen is.

ts
graph.setLegend({ key: 'zone', title: 'Region' })
graph.setLegend({ sections: [{ key: 'zone' }, { key: 'tier' }] })
graph.setLegend(false)        // remove it
graph.setLegend(true)         // back to the derived one

Als u tussen de twee formulieren wisselt, worden de filtersleutels hernoemd, zodat u de filters van het formulier kunt gebruiken links vallen weg: niets blijft verborgen achter een gedeelte dat verdwenen is.

Opties ​

UI.legend neemt ook een boolean: false onderdrukt de legenda, true leidt er een af vanaf render.nodeTypeAccessor zonder eerst de kleuren te controleren. Alles hieronder is de objectvorm.

De vorm gestapeld is { enabled?, position?, sections }: sections is de lijst hieronder minus position, en enabled / position beschrijven de hele kaart.

OptieTypStandaardWat het doet
enabledbooleantruefalse behoudt de declaratie maar toont niets (hetzelfde als legend: false).
idstringkey, anders section-<index>Sectie-identiteit: de filtersleutel (__legend:<id>) en het veld legendToggle section.
titlestringmooier key, anders 'Legend'Koptekst, woordelijk gebruikt (zodat deze kan worden vertaald).
keystring—Gegevenssleutel waarvan de rijen zijn afgeleid, en het standaardpredikaat voor gedeclareerde vermeldingen. Laat zowel dit als entries weg voor de legenda automatische.
entriesLegendEntry[] | (graph) => LegendEntry[]—Gedeclareerde rijen; een functie wordt opnieuw opgelost bij gegevenswijziging.
position'bottom-left' | 'bottom-right' | 'top-left' | 'top-right''bottom-right' in full-modus, anders 'bottom-left'In welke canvashoek hij vastklikt. Hoort bij de kaart, dus het is niet een sectieoptie. 'top-left' deelt zijn anker met het contextuele gereedschapspaneel, dat de legenda bedekt terwijl het geopend is.
collapsiblebooleantrueLaat de chevron zien die hem naar zijn titel vouwt.
collapsedbooleanfalseBegin gevouwen.
showCountsbooleantrueToon het aantal knooppunten per categorie (over de hele grafiek, zodat deze niet flikkert als u schakelt).
filterablebooleantruefalse geeft een gewone, niet-interactieve sleutel weer.
highlightOnHoverbooleantrueAls u over een rij beweegt, wordt die categorie op het canvas verlicht en de rest gedimd.
maxVisibleEntriesnumber12Rijen die worden weergegeven voordat de lijst binnen de legenda schuift.

Een LegendEntry is { id, label?, color, badge?, predicate?, order? }. id is die van de rij identiteit, de waarde die naar het filter wordt geschreven en de terugval van het label.

Wanneer knooppunten van elkaar worden onderscheiden door een badge in plaats van door hun vulling, geef het item dat badge en de rij toont het merkteken in plaats van een punt. Het is getekend zoals de canvas tekent het, en een badge met de naam nr. color neemt de inzending. Het filteren is ongewijzigd.

js
{ id: 'enriched', label: 'From enrichment', color: '#8b5cf6',
  badge: { svgIcon: sparkle }, predicate: (node) => node.getData().enriched }

maxVisibleEntries is één plafond op de hoogte van de legende; het canvas is het andere.

In de modus full wordt de legenda standaard rechtsonder gedockt en boven de minikaart gestapeld die mode wordt ook gemonteerd: de linkerkolom hoort bij de moderail en zijn panelen, en a railmodus waarvan het paneel een werkruimte is in plaats van een instellingenblad, reikt ver genoeg omlaag om de legenda één rij te laten. Waar een minimap de gekozen hoek deelt, wordt de de legende bevindt zich er bovenop en volgt deze terwijl deze inklapt, vergroot of verkleint of wordt ontkoppeld.

Een bottom-left-legenda deelt zijn kolom met de moderail, dus op een korte viewport krimpt in de ruimte ertussen en scrollt liever naar de rij die erop terechtkomt dan opgroeien onder de rail. Het beweegt nooit uit zichzelf een hoek.

Interactie ​

GebaarEffect
Beweeg de muis over een rijVerlicht die categorie op het canvas, dim al het andere
Klik op een rijVerberg/toon die categorie
Alt-klik op een rijToon alleen die categorie
Koptekst toon allesElke rij opnieuw aansteken (wist het filter van de legenda)
Koptekst omkerenWissel welke categorieën worden weergegeven
Koptekst chevronVouw dat gedeelte naar de titel
Alt-klik op de punthaakVouw of ontvouw elke sectie in één keer

Rijen zijn echte knoppen: bereikbaar via tabblad, Enter / Space schakelen en aria-pressed draagt de staat. Er wordt een verborgen rij getekend met een holle staal en gedimde tekst, kleur is nooit het enige signaal.

Zie de galerijkaart Filterbare legenda voor een levend voorbeeld, en LegendOptions / LegendGroupOptions voor de volledige soorten.