Filteropties
In de modus full heeft de koptekst een paneel Grafiekfilters (het trechterpictogram, of Shift+K) waarvan het formulier voor u is gebouwd. Standaard leidt de bibliotheek dat formulier af door knooppuntgegevens te scannen; Met UI.filter kun je dat overnemen.
const options = {
UI: {
filter: {
facets: [ /* … */ ], // declare the facets — the form follows
excludeKeys: ['uuid'], // or just prune the derived ones
},
},
}UI.filter.enabled: false verwijdert het paneel, de pil en Shift+K in zijn geheel; graph.queryEngine filtert nog steeds uit code.
De vorm is van toepassing: een keuze of een vinkje legt vast op het moment dat je het maakt, een tekst of patroonveld een tel nadat u bent gestopt met typen. Er is geen sollicitatieknop, dus het paneel kan dat wel laat nooit een filter zien dat het canvas niet heeft. Reset, naast het sectielabel, wist elk attribuutfilter in één keer.
Randen filteren, geen knooppunten
Alles op deze pagina selecteert nodes. Om edges te filteren — een hele relatie verbergen soort zonder de grafiek te verplaatsen — declareer in plaats daarvan UI.filter.edgeFacets; ze hergebruiken de dezelfde facettenvocabulaire en zijn gedocumenteerd onder Randlagen.
Automatische afleiding (de standaard)
Als er helemaal geen UI.filter is, doorzoekt het paneel de datasleutels van elk knooppunt, verzamelt de verschillende waarden per sleutel, en kiest een widget uit wat hij vindt:
| Hoe de waarden eruit zien | Widget |
|---|---|
| alle cijfers | numberRange (min / max) |
| 3+ korte snaren | multiselect |
| 1 à 2 korte snaren | select |
| booleans | select (waar / onwaar) |
| iets anders | text |
Labels worden mooier gemaakt op basis van de sleutel (attr-type → Attr Type). Dit is een goede zero-config standaard voor verkennende gegevens, maar het kan niet weten welke sleutels zijn facetten en die interne onderdelen zijn — een uuid wordt een vervolgkeuzelijst met één optie per knooppunt, en een lang vrije-tekstveld degradeert tot een tekstvak.
excludeKeys
De goedkope oplossing als de afleiding bijna goed is: laat de toetsen vallen die ruis veroorzaken.
UI: { filter: { excludeKeys: ['uuid', 'imageUrl', 'description'] } }Aangegeven facetten
Stel facets in en het formulier wordt in plaats daarvan gegenereerd op basis van uw aangifte — precies de velden die u vermeldt, in de volgorde waarin u ze vermeldt, met uw labels. Automatische afleiding is volledig overgeslagen, zodat er niets verandert als de gegevens veranderen.
UI: {
filter: {
facets: [
{ key: 'category', label: 'Category', type: 'multiselect',
options: (graph) => distinct(graph, 'category') },
{ key: 'to_ids', label: 'IDS flag', type: 'boolean' },
{ key: 'value', label: 'Value', type: 'regex' },
],
},
}De key van een facet is ook de sleutel die queryEngine.setFilter(key, …) gebruikt, dus programmatische filtering en het paneel blijven op dezelfde voet.
Facettypen
text— subtekenreeks of exacte overeenkomst, permatchMode.regex— een patroon, niet hoofdlettergevoelig gecompileerd. Een niet-compileerbaar patroon wordt gerapporteerd op het veld en laat de actieve filters ongemoeid.select/multiselect— kies uitoptions. Geef een array door, of a functie opgelost ten opzichte van de livegrafiek, zodat optielijsten de gegevens volgen zonder dat het facet zichzelf verandert.numberRange— een min/max-paar.boolean— een vervolgkeuzelijst waar/onwaar/niet ingesteld.
Etiketten
Een gedeclareerde label wordt gebruikt verbatim, dus deze kan uit uw vertaling komen laag. Laat het weg en de sleutel wordt mooier gemaakt als bij automatische afleiding.
Berekende facetten: accessor
Standaard luidt een facet node.getData()[key]. Een accessor leest wat je ook bent like - inclusief dingen die helemaal niet op het knooppunt staan:
// "this object contains an attribute of type X" — reads the node's children
{ key: 'child_type', label: 'Contains attribute of type', type: 'multiselect',
options: () => ATTRIBUTE_TYPES,
accessor: (node) => node.children.map((child) => child.getData()['attr-type']) }Het retourneren van een array is prima — zie matching arrays hieronder.
Volledige controle: predicate
Een predicate beslist zelf over het lidmaatschap en wint van accessor / matchMode. Het draait per node per filtertoepassing, dus houd het goedkoop.
{ key: 'busy', label: 'Busy services', type: 'text',
predicate: (node, value) => node.getData().load >= Number(value) }Een facet waarvan accessor of predicate gooit, stopt met matchen (en waarschuwt één keer) in plaats van de render mee te nemen.
Bestellen
Velden volgen declaratievolgorde. Zet order op een facet om het expliciet te plaatsen — handig wanneer facetten vanaf meerdere plaatsen worden samengevoegd.
Passend
matchMode bepaalt hoe een filterwaarde wordt vergeleken:
'exact'standaard — strikte gelijkheid. Voor een multiselect (een reeks keuzes) dit is lidmaatschap: any-of.'partial'— overeenkomst van subtekenreeks,String(nodeValue).includes(value).'all'— en-semantiek: elke geselecteerde waarde moet aanwezig zijn.
Overeenkomende arrays
Wanneer de waarde van een knooppunt een array — data.tags = ['tlp:amber', 'malware'] — a is filtertests lidmaatschap, niet gelijkheid:
// matches nodes tagged 'malware'; does NOT match a node tagged 'not-malware'
graph.queryEngine.setFilter('tags', { value: 'malware' })
// any-of: amber OR green
graph.queryEngine.setFilter('tags', { value: ['tlp:amber', 'tlp:green'] })
// all: amber AND green
graph.queryEngine.setFilter('tags', { value: ['tlp:amber', 'tlp:green'], matchMode: 'all' })Met 'partial' kan elk afzonderlijk element overeenkomen met een substring. Een numberRange tegen een array komt overeen wanneer een element binnen het bereik valt.
Gedragsverandering
Voordat dit werd ondersteund, viel een waarde van een arrayknooppunt door String(nodeValue).includes(value) — dus per ongeluk een filter voor malware kwam overeen met een knooppunt met de tag not-malware, en een arrayfilterwaarde kwam nooit overeen met allemaal. Beide gedragen zich nu zoals hierboven beschreven.
Ontkenning
negate: true behoudt wat het filter anders zou verbergen. Elk veld in het paneel heeft een is / is not schakel de labelrij in die deze instelt; er wordt een veld getekend dat is geschakeld naar is not rood, de pikhouwelen zijn erdoorheen geslagen.
// every type but domain, including types added later
graph.queryEngine.setFilter('type', { value: ['domain'], negate: true })
// nothing tagged malware
graph.queryEngine.setFilter('tags', { value: ['malware'], negate: true })Voor elke widget geldt het andersom: een lijst is none of, een tekstveld bevat geen (met 'partial'), een patroon komt niet overeen met, een bereik buiten. Met 'all' het is niet alle. Het antwoord van een predicate facet is omgekeerd.
Een knooppunt met geen waarde voor de sleutel wordt behouden, aangezien het ook geen domein is. Een filtertje dus en de ontkenning ervan splitste de grafiek altijd in tweeën, elk knooppunt aan precies één kant. Een waarde dat niets beperkt (een lege lijst, een lege string, een open bereik, een onbruikbaar patroon) verkleint nog steeds niets.
Waar/onwaar-velden hebben geen schakelaar: is niet waar is is onwaar. Randfilters (setEdgeFilter) neem ook negate. Een sectie legende die een facet deelt -toets zorgt ervoor dat een genegeerd filter genegeerd wordt als u erop klikt.
Niet-verbonden knooppunten verbergen
Door relaties weg te filteren, blijven knooppunten achter. Schakel een randlaag uit en een knooppunt waarvan de enige relatie erin zat, blijft op de canvas waar niets aan vast zit – wat bewust is, want een laag is een lens. Wanneer jij do wil dat die knooppunten weg zijn, dat is een regel aan de knooppuntzijde:
const options = {
UI: {
filter: { hideDisconnected: true },
},
}Een knooppunt is verborgen als er geen zichtbare rand meer over is, geteld na de lagen en de knooppuntfilters hebben hun zegje gedaan. Een self-loop telt als een relatie; een briefje vastgemaakt aan een knooppunt niet.
Dezelfde schakelaar staat in de vervolgkeuzelijst Bekijken als Niet-verbonden verbergen, in elke grafiek, uit tenzij de optie dit inschakelt - zodat een gebruiker de weeskinderen kan opschonen met een laagschakelaar links, of leg degene terug die je verborgen hebt. Terwijl het zich verbergt, zegt de rij hoeveel.
Deze verplaatst de grafiek
Al het andere op deze pagina en elke randlaag laat de lay-out met rust. Een verborgen knooppunt verlaat de simulatie, zodat de rest zich opnieuw vestigt. Dat is de ruil voor een opgeruimd canvas, en daarom is de regel standaard uitgeschakeld.
Twee dingen die het bewust niet doet:
- Clusterinterieurs worden met rust gelaten. Clusters groeperen routinematig knooppunten zonder relaties tussen hen in, dus als je de regel in de ene zou toepassen, zou er een lege doos worden geopend.
- Niets is beveiligd. Schakel elke laag uit en niets is verbonden, dus niets wordt getekend. De schakelaar is de weg terug.
graph.queryEngine.setHideDisconnected(true) // same as the switch
graph.queryEngine.isHideDisconnected()
graph.queryEngine.getDisconnectedNodeCount() // what the switch row reportsOpnieuw solliciteren nadat de gegevens zijn gewijzigd
Filters worden toegepast wanneer een filter verandert, niet wanneer de gegevens van de grafiek dat doen. Voeg de rand toe er ontbrak een knooppunt en het blijft verborgen totdat iets opnieuw wordt berekend:
graph.updateData(newNodes, newEdges)
graph.queryEngine.reapply() // recompute nowNuttig om te weten voordat je het noemt: zichtbaarheid opnieuw afleiden maakt een handleiding ongedaan graph.hideNode(), wat niets onthoudt. queryEngine.excludeNode() is de huid dat overleeft — het is wat het contextmenu en de bulkacties gebruiken, en alleen Show knooppunt draait het om.
Waar het paneel zijn waarden krijgt
Filter waarden stroomt altijd door graph.queryEngine, hoe het formulier ook is gebouwd — dus het aantal actieve filters van de header, de lijst Verborgen knooppunten, en voortplanting naar de subgraaf van een uitgebreid cluster blijft allemaal werken. Aangegeven facetten worden ook doorgegeven aan de subgraaf van een cluster, dus een accessor / predicate facet filtert kinderen precies zoals het knooppunten op het hoogste niveau filtert.
Het canvas legende is een derde manier om in dezelfde engine te komen: klikken op een legendarij verbergt die categorie. Geef de legenda de key van een aangegeven select / multiselect facet en de twee sturen één filter aan, dus het paneel controle en de legende blijven in de pas.
De gegevenstabel is een vierde: de knop Toepassen op grafiek verbergt de elementen die de kolomfilters weglaten. Die push landt onder een gereserveerde sleutel van het is zijn eigen, dus het overleeft alles wat de vorm van dit paneel toepast en wordt gecombineerd met wat dan ook dit paneel filtert het in plaats van het te vervangen. Omdat het formulier structureel geen a gereserveerde sleutel, het paneel krijgt een rij From the table waarin wordt aangegeven wat de push verbergt — en de enige andere plaats waar het vandaan kan worden gehaald, zodra het dok is weggeklapt.
Zie de Filter-/query-engine galerijkaart voor een live voorbeeld, en FilterFacet voor de volledige soort.