Filteroptionen
Im full-Modus enthält die Kopfzeile ein Bedienfeld Grafikfilter (das Trichtersymbol oder Umschalt+K), dessen Formular für Sie erstellt wird. Standardmäßig leitet die Bibliothek dieses Formular durch Scannen von Knotendaten ab; Mit UI.filter können Sie das übernehmen.
const options = {
UI: {
filter: {
facets: [ /* … */ ], // declare the facets — the form follows
excludeKeys: ['uuid'], // or just prune the derived ones
},
},
}UI.filter.enabled: false entfernt das Panel, seine Pille und Umschalt+K insgesamt; graph.queryEngine filtert immer noch aus Code.
Die Form wird angewendet: Eine Auswahl oder ein Häkchen wird in dem Moment übernommen, in dem Sie es treffen, ein Text- oder Musterfeld einen Schlag, nachdem Sie mit der Eingabe aufgehört haben. Da es keine Schaltfläche „Anwenden“ gibt, kann das Bedienfeld niemals einen Filter anzeigen, über den die Arbeitsfläche nicht verfügt. Zurücksetzen neben der Abschnittsbezeichnung löscht alle Attributfilter auf einmal.
Kanten filtern, keine Knoten
Alles auf dieser Seite wählt Knoten aus. Um Kanten zu filtern – eine ganze Beziehungsart auszublenden, ohne den Graphen zu verschieben – deklarieren Sie stattdessen UI.filter.edgeFacets; Sie verwenden dasselbe Facettenvokabular und sind unter Randschichten dokumentiert.
Automatische Ableitung (Standard)
Ohne UI.filter durchsucht das Panel die Datenschlüssel jedes Knotens, sammelt die unterschiedlichen Werte pro Schlüssel und wählt aus dem, was es findet, ein Widget aus:
| Wie die Werte aussehen | Widget |
|---|---|
| alle Zahlen | numberRange (min./max.) |
| 3+ kurze Saiten | multiselect |
| 1–2 kurze Saiten | select |
| Boolesche Werte | select (wahr / falsch) |
| irgendetwas anderes | text |
Beschriftungen werden anhand des Schlüssels (attr-type → Attr Type) verschönert. Dies ist eine gute Null-Konfigurations-Standardeinstellung für explorative Daten, aber es gibt keine Möglichkeit zu wissen, welche Schlüssel Facetten und welche Interna sind – eine uuid wird zu einem Dropdown mit einer Option pro Knoten, und ein langes Freitextfeld degradiert zu einem Textfeld.
excludeKeys
Die billige Lösung, wenn die Ableitung fast richtig ist: Lassen Sie die Schlüssel weg, die Rauschen verursachen.
UI: { filter: { excludeKeys: ['uuid', 'imageUrl', 'description'] } }Deklarierte Facetten
Setzen Sie facets und das Formular wird stattdessen aus Ihrer Erklärung generiert – genau die Felder, die Sie auflisten, in der Reihenfolge, in der Sie sie auflisten, mit Ihren Beschriftungen. Die automatische Ableitung wird vollständig übersprungen, sodass sich bei Datenänderungen nichts ändert.
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' },
],
},
}Die key einer Facette ist auch der Schlüssel, den queryEngine.setFilter(key, …) verwendet, sodass die programmatische Filterung und das Panel auf dem gleichen Stand bleiben.
Facettentypen
text– Teilzeichenfolge oder genaue Übereinstimmung gemäßmatchMode.regex– ein Muster, zusammengestellt ohne Berücksichtigung der Groß- und Kleinschreibung. Ein nicht kompilierbares Muster wird im Feld gemeldet und lässt die aktiven Filter unberührt.select/multiselect– wählen Sie ausoptions. Übergeben Sie ein Array oder eine Funktion, die anhand des Live-Diagramms aufgelöst wird, sodass Optionslisten den Daten folgen, ohne dass sich der Facettensatz selbst ändert.numberRange– ein Min/Max-Paar.boolean– ein Dropdown-Menü „Wahr/Falsch/Nicht gesetzt“.
Etiketten
Eine deklarierte label wird wörtlich verwendet, sodass sie aus Ihrer Übersetzungsebene stammen kann. Wenn Sie es weglassen, wird der Schlüssel wie bei der automatischen Ableitung verschönert.
Berechnete Facetten: accessor
Standardmäßig lautet eine Facette node.getData()[key]. Ein accessor liest, was Sie wollen – auch Dinge, die sich überhaupt nicht auf dem Knoten befinden:
// "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']) }Die Rückgabe eines Arrays ist in Ordnung – siehe passende Arrays weiter unten.
Volle Kontrolle: predicate
Eine predicate entscheidet selbst über die Mitgliedschaft und gewinnt über accessor / matchMode. Es läuft pro Knoten pro Filteranwendung, also halten Sie es günstig.
{ key: 'busy', label: 'Busy services', type: 'text',
predicate: (node, value) => node.getData().load >= Number(value) }Eine Facette, deren accessor- oder predicate-Würfe nicht mehr übereinstimmen (und einmal warnt), anstatt das Rendering mitzunehmen.
Bestellen
Die Felder folgen der Deklarationsreihenfolge. Setzen Sie order auf eine Facette, um sie explizit zu platzieren – praktisch, wenn Facetten an mehreren Stellen zusammengesetzt werden.
Passend
matchMode entscheidet, wie ein Filterwert verglichen wird:
'exact'Standard – strikte Gleichheit. Für eine Mehrfachauswahl (ein Array von Picks) ist dies die Mitgliedschaft: any-of.'partial'– Teilstring-Übereinstimmung,String(nodeValue).includes(value).'all'– Und-Semantik: Jeder ausgewählte Wert muss vorhanden sein.
Passende Arrays
Wenn der Wert eines Knotens ein Array – data.tags = ['tlp:amber', 'malware'] ist, testet ein Filter die Mitgliedschaft, nicht die Gleichheit:
// 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' })Mit 'partial' kann jedes einzelne Element einer Teilzeichenfolge entsprechen. Ein numberRange gegen ein Array stimmt überein, wenn ein Element in den Bereich fällt.
Verhaltensänderung
Bevor dies unterstützt wurde, fiel der Wert eines Array-Knotens auf String(nodeValue).includes(value) – ein Filter für malware stimmte also versehentlich mit einem Knoten mit der Markierung not-malware überein, und ein Array-Filterwert stimmte überhaupt nicht überein. Beide verhalten sich nun wie oben beschrieben.
Negation
negate: true behält, was der Filter sonst verbergen würde. Jedes Feld im Bedienfeld verfügt über einen ist/ist nicht-Schalter in seiner Beschriftungszeile, der es festlegt; ein auf nicht geschaltetes Feld wird rot gezeichnet, seine Picks sind durchgestrichen.
// 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 })Für jedes Widget liest es sich umgekehrt: Eine Liste ist nichts von, ein Textfeld enthält nicht (mit 'partial'), ein Muster passt nicht, ein Bereich außerhalb. Mit 'all' ist es *nicht alles von *. Die Antwort einer predicate-Facette ist invertiert.
Ein Knoten mit kein Wert für den Schlüssel wird beibehalten, da es sich auch nicht um eine Domäne handelt. Ein Filter und seine Negation teilen den Graphen also immer in zwei Teile, wobei sich jeder Knoten auf genau einer Seite befindet. Ein Wert, der nichts einschränkt (eine leere Liste, eine leere Zeichenfolge, ein offener Bereich, ein unbrauchbares Muster), schränkt immer noch nichts ein.
Wahr/Falsch-Felder haben keinen Schalter: ist nicht wahr ist ist falsch. Kantenfilter (setEdgeFilter) benötigen auch negate. Ein legend-Abschnitt, der den Schlüssel einer Facette teilt, behält einen negierten Filter bei, wenn Sie darauf klicken.
Nicht verbundene Knoten ausblenden
Das Wegfiltern von Beziehungen lässt Knoten zurück. Schalten Sie einRandschichtaus und ein Knoten, dessen einzige Beziehung darin bestand, bleibt auf der Arbeitsfläche, ohne dass etwas daran befestigt ist – was beabsichtigt ist, da eine Ebene eine Linse ist. Wenn duTunmöchte, dass diese Knoten verschwinden, das ist eine knotenseitige Regel:
const options = {
UI: {
filter: { hideDisconnected: true },
},
}Ein Knoten ist ausgeblendet, wenn er keine sichtbare Kante mehr hat, gezählt, nachdem die Ebenen und die Knotenfilter zu Wort gekommen sind. Eine Selbstschleife gilt als Relation; Eine an einen Knoten angeheftete Notiz gilt nicht.
Im Flyout Ansicht befindet sich derselbe Schalter wie Unverbunden ausblenden, in jedem Diagramm, deaktiviert, es sei denn, die Option aktiviert ihn – so kann ein Benutzer die verwaisten Objekte eine Ebene nach links bereinigen oder diejenigen zurücksetzen, die Sie ausgeblendet haben. Während es ausgeblendet ist, wird in der Zeile angegeben, wie viele es sind.
Dieser verschiebt den Graphen
Alles andere auf dieser Seite und jede Randebene verlässt das Layout. Ein versteckter Knoten verlässt die Simulation, sodass sich der Rest neu beruhigt. Das ist der Tausch gegen eine aufgeräumte Arbeitsfläche, und deshalb ist die Regel standardmäßig deaktiviert.
Zwei Dinge werden bewusst nicht gemacht:
- Cluster-Innenräume werden in Ruhe gelassen. Cluster gruppieren routinemäßig Knoten ohne Beziehungen zwischen ihnen, sodass die Anwendung der Regel innerhalb eines Clusters ein leeres Feld öffnen würde.
- Nichts ist geschützt. Schalten Sie jede Ebene aus und nichts ist verbunden, also wird nichts gezeichnet. Der Schalter ist der Weg zurück.
graph.queryEngine.setHideDisconnected(true) // same as the switch
graph.queryEngine.isHideDisconnected()
graph.queryEngine.getDisconnectedNodeCount() // what the switch row reportsErneute Bewerbung nach Datenänderungen
Filter werden angewendet, wenn sich ein Filter ändert – nicht, wenn sich die Daten des Diagramms ändern. Fügen Sie die Kante hinzu, die einem Knoten fehlte, und sie bleibt verborgen, bis etwas neu berechnet wird:
graph.updateData(newNodes, newEdges)
graph.queryEngine.reapply() // recompute nowWissenswertes, bevor Sie es aufrufen: Das erneute Ableiten der Sichtbarkeit ** macht ein Handbuch graph.hideNode()** rückgängig, an das sich nichts erinnert. queryEngine.excludeNode() ist das Ausblenden, das überlebt – es wird vom Kontextmenü und den Massenaktionen verwendet, und nur Knoten anzeigen kehrt es um.
Woher das Panel seine Werte bezieht
Filter-Werte fließen immer durch graph.queryEngine, unabhängig davon, wie das Formular aufgebaut ist – die Anzahl der aktiven Filter des Headers, die Liste der Versteckten Knoten und die Weitergabe an den Untergraphen eines erweiterten Clusters funktionieren also weiterhin. Deklarierte Facetten werden auch an den Untergraphen eines Clusters weitergegeben, sodass eine accessor / predicate-Facette untergeordnete Elemente genau so filtert, wie sie Knoten der obersten Ebene filtert.
Die Arbeitsfläche Legende ist ein dritter Weg in dieselbe Engine: Durch Klicken auf eine Legendenzeile wird diese Kategorie ausgeblendet. Geben Sie der Legende die key einer deklarierten select / multiselect-Facette und den beiden Laufwerken einen-Filter, damit die Steuerung des Panels und die Legende im Gleichschritt bleiben.
DerDatentabelleist ein Viertel: esAuf Diagramm anwendenDie Schaltfläche blendet die Elemente aus, die ihre Spaltenfilter auslassen. Dieser Push landet unter einem eigenen reservierten Schlüssel, sodass er alles überlebt, was die Form dieses Panels anwendet, und mit allem kombiniert wird, was dieses Panel filtert, anstatt es zu ersetzen. Da das Formular strukturell keinen reservierten Schlüssel anzeigen kann, wächst das PanelVom TischZeile, die benennt, was der Schieber verbirgt – und den einzigen anderen Ort, von dem er befreit werden kann, sobald das Dock weggeklappt ist.
Ein Live-Beispiel finden Sie in der Galeriekarte Filter-/Abfrage-Engine und in FilterFacet den vollständigen Typ.