过滤器选项
在full模式下,标题带有一个图形过滤器面板(漏斗图标,或Shift+K),其表单是为您构建的。默认情况下,库通过扫描节点数据派生该形式; UI.filter 让你接管它。
const options = {
UI: {
filter: {
facets: [ /* … */ ], // declare the facets — the form follows
excludeKeys: ['uuid'], // or just prune the derived ones
},
},
}UI.filter.enabled: false 一起移除面板、其药丸和Shift+K; graph.queryEngine 仍然从代码中过滤。
应用自身:选择或勾选在您做出它的那一刻就提交,文本或模式字段在您停止输入后立即提交。没有应用按钮,因此面板永远不会显示画布没有的过滤器。 重置,在部分标签旁边,一次性清除每个属性过滤器。
过滤边,而不是节点
此页面上的所有内容都选择nodes。要过滤 edges — 隐藏整个关系类型而不移动图形 — 改为声明 UI.filter.edgeFacets;它们重复使用相同的方面词汇,并记录在边缘层下。
自动推导(默认)
在根本没有 UI.filter 的情况下,面板会遍历每个节点的数据键,收集每个键的不同值,并从找到的内容中选择一个小部件:
| 价值观是什么样的 | 小工具 |
|---|---|
| 所有数字 | numberRange(最小/最大) |
| 3+短弦 | multiselect |
| 1–2 短弦 | select |
| 布尔值 | select(真/假) |
| 还有什么 | text |
标签根据键进行美化(attr-type → Attr Type)。对于探索性数据来说,这是一个很好的零配置默认值,但它无法知道哪些键是 facets 以及哪些是内部键 - uuid 成为每个节点一个选项的下拉菜单,并且长自由文本字段降级为文本框。
excludeKeys
当推导几乎正确时,廉价的修复方法是:丢弃噪声密钥。
UI: { filter: { excludeKeys: ['uuid', 'imageUrl', 'description'] } }声明的方面
设置 facets ,表单将根据您的声明生成 - 正是您列出的字段,按照您列出的顺序,以及您的标签。完全跳过自动推导,因此数据更改时不会发生任何变化。
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' },
],
},
}构面的 key 也是 queryEngine.setFilter(key, …) 使用的键,因此程序化过滤和面板保持相同的基础。
刻面类型
text— 子字符串或精确匹配,每个matchMode。regex— 一种模式,编译为 不区分大小写。现场报告了无法编译的模式,并且活动过滤器保持不变。select/multiselect— 从options中选择。传递一个数组或根据实时图表解析的函数,以便选项列表跟随数据,而不会改变构面集本身。numberRange— 最小/最大对。boolean— true / false / unset 下拉列表。
标签
声明的 label 使用 逐字,因此它可以来自您的翻译层。省略它,密钥将像自动推导一样被美化。
计算面:accessor
默认情况下,刻面读取为 node.getData()[key]。 accessor 可以读取您喜欢的任何内容,包括根本不在节点上的内容:
// "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']) }返回一个数组就可以了——参见下面的匹配数组。
完全控制:predicate
A predicate 自行决定成员资格,并胜过accessor / matchMode。它在每个过滤器应用程序的每个节点上运行,因此保持便宜。
{ key: 'busy', label: 'Busy services', type: 'text',
predicate: (node, value) => node.getData().load >= Number(value) }accessor 或 predicate 抛出的构面会停止匹配(并发出警告一次),而不是使渲染随之停止。
订购
字段遵循声明顺序。在面上设置 order 以明确放置它 - 当面从多个位置组装时很方便。
配套
matchMode 决定如何比较过滤器值:
'exact'默认 — 严格平等。对于多选(一系列选择),这是成员资格:任意。'partial'— 子字符串匹配,String(nodeValue).includes(value)。'all'— 与语义:每个选定的值都必须存在。
匹配数组
当节点的值是 array — data.tags = ['tlp:amber', 'malware'] — 过滤器测试 membership,而不是相等性:
// 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' })使用'partial',任何单个元素都可以进行子字符串匹配。当任何元素落入该范围内时,针对数组的 numberRange 就会匹配。
行为改变
在支持此功能之前,数组节点值会下降到 String(nodeValue).includes(value) — 因此 malware 的过滤器意外匹配标记为 not-malware 的节点,并且数组过滤器值根本不会匹配。现在两者的行为都如上所述。
否定
negate: true 保留过滤器原本隐藏的内容。面板中的每个字段在其标签行上都有一个 is / is not 开关来设置它;切换到而不是的字段被绘制为红色,其选秀权被击穿。
// 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 })对于每个小部件,它以相反的方式读取:列表是没有,文本字段不包含(与'partial'),模式不匹配,范围外部。对于'all',它是,而不是的全部。 predicate 面的答案是倒置的。
保留键具有无值的节点,因为它也不是域。因此,过滤器及其否定总是将图分成两部分,每个节点恰好位于一侧。不缩小任何范围的值(空列表、空白字符串、开放范围、不可用的模式)仍然不缩小任何范围。
真/假字段没有开关:不是真是是假。边缘过滤器 (setEdgeFilter) 也采用negate。共享构面键的 legend 部分会在您单击它时使否定过滤器保持否定状态。
隐藏未连接的节点
过滤掉关系会留下节点。关闭边缘层,并且其中唯一关系的节点保留在画布上而不附加任何东西 - 这是故意的,因为层是一个镜头。当你do希望这些节点消失时,这是一个节点端规则:
const options = {
UI: {
filter: { hideDisconnected: true },
},
}当节点没有 visible 剩余边缘时,节点被隐藏,在层和节点过滤器有发言权后进行计数。自循环算作关系;固定到节点的注释则不会。
与隐藏未连接的一样,在View弹出窗口中也有相同的开关,在每个图形上,除非该选项将其打开,否则将关闭 - 因此用户可以清理左侧图层切换的孤立项,或放回您隐藏的那些。当它隐藏时,该行显示有多少。
这个移动图表
此页面上的其他所有内容以及每个边缘层都保留布局。隐藏节点离开模拟,因此其余节点重新解决。这是为了换取整洁的画布,也是默认情况下关闭该规则的原因。
它故意不做两件事:
- 集群内部保持不变。集群通常对彼此之间没有关系的节点进行分组,因此在其中应用规则将打开一个空盒子。
- 没有任何内容受到保护。关闭每一层并且没有任何内容被连接,因此没有任何内容被绘制。开关就是回来的路。
graph.queryEngine.setHideDisconnected(true) // same as the switch
graph.queryEngine.isHideDisconnected()
graph.queryEngine.getDisconnectedNodeCount() // what the switch row reports数据变更后重新申请
当过滤器更改时应用过滤器,而不是当图表数据更改时应用过滤器。添加节点丢失的边,它会保持隐藏状态,直到重新计算:
graph.updateData(newNodes, newEdges)
graph.queryEngine.reapply() // recompute now在调用它之前值得了解一下:重新导出可见性撤消手册graph.hideNode(),没有任何东西记得。 queryEngine.excludeNode() 是幸存下来的隐藏 — 它是上下文菜单和批量操作所使用的,只有 显示节点 可以反转它。
面板获取其值的位置
无论表单以哪种方式构建,过滤器 values 始终流经 graph.queryEngine — 因此标头的活动过滤器计数、隐藏节点列表以及传播到扩展集群的子图都将继续工作。声明的分面也会传递给集群的子图,因此 accessor / predicate 分面过滤子节点的方式与过滤顶级节点的方式完全相同。
画布 legend 是进入同一引擎的第三种方式:单击图例行隐藏该类别。为图例指定声明的 select / multiselect 构面的 key 和两个驱动 one 过滤器,以便面板的控制和图例保持同步。
数据表是第四个:它的应用于图表按钮隐藏了列过滤器遗漏的元素。该推送位于其自己的保留键下,因此它可以在该面板的表单应用的任何内容中保留下来,并与该面板正在过滤而不是替换它的任何内容相结合。由于表单在结构上无法显示保留键,因此面板会从表中生成一个 ** ** 行,命名推送隐藏的内容 - 以及一旦扩展坞折叠起来后唯一可以清除的其他位置。
有关实例,请参阅 过滤器/查询引擎图库卡,有关完整类型,请参阅 FilterFacet。