Ir al contenido

Opciones de filtro ​

En el modo full, el encabezado lleva un panel Filtros de gráficos (el ícono del embudo, o Shift+K) cuyo formulario está diseñado para usted. Por defecto, la biblioteca deriva esa forma. escaneando datos de nodos; UI.filter te permite hacerte cargo de eso.

ts
const options = {
    UI: {
        filter: {
            facets: [ /* … */ ],   // declare the facets — the form follows
            excludeKeys: ['uuid'], // or just prune the derived ones
        },
    },
}

UI.filter.enabled: false elimina el panel, su pastilla y Shift+K por completo; graph.queryEngine todavía filtra del código.

La forma se aplica sola: una selección o un tick se confirma en el momento en que lo haces, un mensaje de texto o campo de patrón un latido después de dejar de escribir. No hay un botón de aplicar, por lo que el panel puede Nunca muestres un filtro que el lienzo no tenga. Restablecer, al lado de la etiqueta de la sección, borra todos los filtros de atributos a la vez.

Bordes de filtrado, no nodos

Todo en esta página selecciona nodos. Para filtrar edges: ocultar una relación completa kind sin mover el gráfico; declara UI.filter.edgeFacets en su lugar; ellos reutilizan el mismo vocabulario de facetas y están documentados en Capas de borde.

Derivación automática (el valor predeterminado) ​

Sin ningún UI.filter, el panel recorre las claves de datos de cada nodo, recopila el valores distintos por clave y elige un widget de lo que encuentra:

Cómo se ven los valoreswidget
todos los numerosnumberRange (mín./máx.)
3+ cuerdas cortasmultiselect
1 o 2 hilos cortosselect
booleanosselect (verdadero/falso)
cualquier otra cosatext

Las etiquetas están embellecidas a partir de la clave (attr-type → Tipo de atributo). Este es un buen valor predeterminado de configuración cero para datos exploratorios, pero no tiene forma de saber qué claves son facetas y cuáles son internas: un uuid se convierte en un menú desplegable con una opción por nodo, y un campo largo de texto libre se degrada a un cuadro de texto.

excludeKeys ​

La solución barata cuando la derivación es casi correcta: suelte las claves que hacen ruido.

ts
UI: { filter: { excludeKeys: ['uuid', 'imageUrl', 'description'] } }

Facetas declaradas ​

Establezca facets y el formulario se generará a partir de su declaración, exactamente el campos que enumere, en el orden en que los enumere, con sus etiquetas. La autoderivación es se omitió por completo, por lo que nada se agita cuando cambian los datos.

ts
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' },
        ],
    },
}

El key de una faceta también es la clave que usa el queryEngine.setFilter(key, …), por lo que El filtrado programático y el panel se mantienen en pie de igualdad.

Tipos de facetas ​

  • text: subcadena o coincidencia exacta, según matchMode.
  • regex: un patrón, compilado sin distinguir entre mayúsculas y minúsculas. Un patrón no compilable se reporta en el campo y deja los filtros activos intactos.
  • select / multiselect - elige entre options. Pasar una matriz, o un función resuelta contra el gráfico en vivo para que las listas de opciones sigan los datos sin que el conjunto de facetas cambie.
  • numberRange — un par mínimo/máximo.
  • boolean: un menú desplegable verdadero/falso/no configurado.

Etiquetas ​

Un label declarado se usa verbatim, por lo que puede provenir de su traducción capa. Si se omite, la clave quedará embellecida como en la derivación automática.

Facetas calculadas: accessor ​

De forma predeterminada, una faceta dice node.getData()[key]. Un accessor lee lo que quieras como, incluidas cosas que no están en el nodo en absoluto:

ts
// "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']) }

Devolver una matriz está bien; consulte matrices coincidentes a continuación.

Control total: predicate ​

A predicate decide la membresía y gana a accessor / matchMode. Se ejecuta por nodo por aplicación de filtro, así que manténgalo económico.

ts
{ key: 'busy', label: 'Busy services', type: 'text',
  predicate: (node, value) => node.getData().load >= Number(value) }

Una faceta cuyos lanzamientos accessor o predicate deja de coincidir (y avisa una vez) en lugar de eliminar el renderizado con él.

Realizar pedidos ​

Los campos siguen el orden de declaración. Establezca order en una faceta para colocarla explícitamente: útil cuando las facetas se ensamblan desde varios lugares.

Coincidencia ​

matchMode decide cómo se compara un valor de filtro:

  • 'exact' predeterminado — igualdad estricta. por un selección múltiple (una serie de selecciones) esto es membresía: cualquiera de.
  • 'partial' - coincidencia de subcadena, String(nodeValue).includes(value).
  • 'all' - and-semantics: cada valor seleccionado debe estar presente.

Matrices coincidentes ​

Cuando el valor de un nodo es un array — data.tags = ['tlp:amber', 'malware'] — a pruebas de filtro membresía, no igualdad:

ts
// 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' })

Con 'partial', cualquier elemento puede coincidir con una subcadena. Un numberRange en contra una matriz coincide cuando cualquier elemento cae dentro del rango.

Cambio de comportamiento

Antes de que esto fuera compatible, un valor de nodo de matriz no se transmitía a String(nodeValue).includes(value) - entonces un filtro para malware accidentalmente coincidió con un nodo etiquetado not-malware, y un valor de filtro de matriz nunca coincidió en todos. Ahora ambos se comportan como se describe arriba.

Negación ​

negate: true mantiene lo que de otro modo el filtro ocultaría. Cada campo del panel tiene un is/not activa la fila de etiquetas que lo configura; se dibuja un campo cambiado a no rojo, sus púas perforadas.

ts
// 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 })

Se lee al revés para cada widget: una lista es ninguno de, un campo de texto no contiene (con 'partial'), un patrón no coincide, un rango fuera. con 'all' es no todo. La respuesta de una faceta predicate está invertida.

Se mantiene un nodo con sin valor para la clave, ya que tampoco es un dominio. entonces un filtro y su negación siempre divide el gráfico en dos, cada nodo exactamente en un lado. un valor que no limita nada (una lista vacía, una cadena en blanco, un rango abierto, un patrón inutilizable) todavía no reduce nada.

Los campos Verdadero/falso no tienen interruptor: no es verdadero es es falso. Filtros de borde (setEdgeFilter) toma negate también. Una sección leyenda que comparte una faceta La tecla mantiene un filtro negado negado cuando haces clic en él.

Ocultar nodos no conectados ​

Filtrar las relaciones deja atrás los nodos. Cambiar un capa de borde desactivada y un nodo cuya única relación estaba en ella permanece en la lienzo sin nada adherido, lo cual es deliberado, porque una capa es una lente. cuando tu do quiere que esos nodos desaparezcan, esa es una regla del lado de los nodos:

ts
const options = {
    UI: {
        filter: { hideDisconnected: true },
    },
}

Un nodo está oculto cuando no le queda ningún borde visible, contado después de las capas y el Los filtros de nodo han dado su opinión. Un bucle propio cuenta como una relación; una nota clavada en un el nodo no.

El mismo interruptor está en el menú lateral Ver que Ocultar desconectado, en cada gráfico, apagado a menos que la opción la active, para que un usuario pueda limpiar los huérfanos una capa alternar hacia la izquierda, o devolver los que escondiste. Mientras se esconde, la fila dice cuántos.

Éste mueve la gráfica.

Todo lo demás en esta página, y cada capa de borde, deja el diseño como está. Un escondido El nodo abandona la simulación, por lo que el resto se reubica. Ese es el trato por un lienzo ordenado, y es por eso que la regla está desactivada de forma predeterminada.

Dos cosas que deliberadamente no hace:

  • Los interiores de los clústeres se dejan solos. Los clústeres habitualmente agrupan nodos sin relaciones entre ellos, por lo que aplicar la regla dentro de uno abriría una caja vacía.
  • No hay nada protegido. Apague todas las capas y no hay nada conectado, por lo que nada está dibujado. El cambio es el camino de regreso.
ts
graph.queryEngine.setHideDisconnected(true)  // same as the switch
graph.queryEngine.isHideDisconnected()
graph.queryEngine.getDisconnectedNodeCount() // what the switch row reports

Volver a aplicar después de que los datos cambien ​

Los filtros se aplican cuando cambia un filtro, no cuando lo hacen los datos del gráfico. Agrega el borde faltaba un nodo y permanece oculto hasta que algo se vuelve a calcular:

ts
graph.updateData(newNodes, newEdges)
graph.queryEngine.reapply()   // recompute now

Vale la pena saberlo antes de llamar: volver a derivar la visibilidad ** deshace un manual graph.hideNode()**, que nada recuerda. queryEngine.excludeNode() es la piel que sobrevive: es lo que usan el menú contextual y las acciones masivas, y solo Mostrar nodo lo invierte.

De dónde obtiene el panel sus valores ​

El filtro valores siempre fluye a través de graph.queryEngine, sea cual sea la forma en que esté el formulario construido, por lo que el recuento de filtros activos del encabezado, la lista Nodos ocultos y la propagación al subgrafo de un clúster expandido sigue funcionando. Facetas declaradas también se transmiten al subgrafo de un grupo, por lo que una faceta accessor / predicate filtra los niños exactamente como filtra los nodos de nivel superior.

El lienzo legend es una tercera forma de acceder al mismo motor: hacer clic en un La fila de leyenda oculta esa categoría. Dale a la leyenda el key de un declarado select / multiselect faceta y las dos unidades one filtro, por lo que el panel El control y la leyenda se mantienen al día.

La tabla de datos es una cuarta: su botón Aplicar al gráfico Oculta los elementos que sus filtros de columna omiten. Ese impulso aterriza bajo una clave reservada de propio, por lo que sobrevive a cualquier aplicación de la forma de este panel y se combina con cualquier este panel lo filtra en lugar de reemplazarlo. Debido a que la forma estructuralmente no puede mostrar una clave reservada, el panel crece en una fila De la tabla que nombra lo que oculta la inserción: y el único otro lugar desde el que se puede retirar, una vez que se pliega el muelle.

Ver el Motor de filtro/consulta tarjeta de galería para un ejemplo en vivo, y FilterFacet para el tipo completo.