跳转到内容

数据表 ​

UI.table 从画布底部分割出数据停靠点:图形的节点和边作为可排序、可选择的网格。它的存在是因为部队布局在结构上不利于人们经常做的三件事——读取精确值、大规模选择以及确定从哪里开始。

预期的循环是表格查找,画布理解,侧边栏阅读:按程度排序以发现中心,按住Shift键单击前二十个,然后使用侧边栏的批量操作对其进行操作。

ts
const options = {
    UI: { mode: 'full' },
}

这就是所需要的一切。在full模式下,停靠栏位于底部折叠到其标题栏;单击其 V 形符号 — 或按 Shift+T — 显示表格。 UI.table: false 将其完全删除。

故意没有工具栏按钮。栏是控件:顶部栏中的药丸都会在画布上打开一些**,而停靠栏是一个分割区域,已经向您显示了自己的V形图标。

停靠栏仅适用于 full 模式 - 它是侧边栏旁边的网格行,其他模式承诺画布没有那么多镶边。

该表不会更改您未要求的任何内容

码头不会改变任何东西。它反映图表并驱动选择;隐藏和固定留在侧边栏的批量操作,恢复隐藏节点留在过滤器面板。码头添加的是一个更好的工具,用于构建这些操作的选择。

它可以改变的一件事是画布显示,并且仅根据请求:应用于图表按钮隐藏列过滤器遗漏的元素。在您按下它之前,缩小列的范围是阅读,而不是过滤。

它列出了整个图 ​

该桌子不是镜像画布。它列出了每个节点 - 以及“边”选项卡上的每条边 - 包括当前隐藏的节点,并且前导 Visibility 列显示了每个节点的位置:

价值样式含义
visible安静、无色现在在画布上
filtered琥珀碎片被过滤器隐藏 - 节点过滤器,或者对于边缘,其 layer 被关闭。更换过滤器以恢复原状
excluded红筹手工隐藏的节点;从过滤器面板的隐藏节点列表中恢复它
nested虚线轮廓画布已关闭的簇内的节点,或一端为一的边:其线被绘制到簇。没有任何东西过滤它;打开集群就可以看到
endpoint中性轮廓末端被过滤掉的边。边缘本身没有做任何事情

每个州的粗细、边框以及颜色都不同,因此该栏的阅读不依赖于色调。隐藏元素的整行也会后退,将注意力集中在实际绘制的内容上。

边优先读取 endpoint 而不是 filtered,因为这就是您必须首先修复的原因:当它接触的节点消失时,重新打开其层无法使边恢复。

那是故意的。 “隐藏 23 个节点”是您应该能够检查的声明,而一个悄悄删除您正在查找的行的表比没有表更糟糕。按 Visibility 排序以查看过滤器到底拿走了什么。

集群内的节点 ​

集群的内容也获取行,作为图自身节点的 peers,其中 Cluster 列给出它们来自的路径(Team B / Squad,最外层的第一个),以及 Children 列说明每个集群有多大。只要图表有簇,就会出现两列。如果您只想要顶层,标头的 嵌套节点 开关会再次取出这些行,而 UI.table.nested: false 根本不会提供它们。

它们是平列的,而不是故意在簇下缩进的:该表的存在是为了回答画布无法回答的问题——哪些节点是中心,哪些节点超过阈值——并且只有在排序或过滤器平等地到达每一行时才继续工作。一棵树只能对兄弟姐妹进行排序。

值得注意的是,嵌套节点不是由该图绘制的。开簇呈现其自己的单独子图,因此:

  • Visibility读nested当节点上方的任何集群关闭时,并且visible一旦它们全部打开。从来都不是filtered— 没有过滤器放在那里。
  • Degree 计算节点的真实边。当其集群关闭时,画布会将它们绘制到集群中,因此这是节点自己的计数,而不是图片的描述。
  • 单击该行会选择该节点,因此侧边栏可以显示它——通常是到达该节点的唯一方法。画布环绕着代表它的封闭簇。 双击打开该簇,每按一次一级。使用 render.enableNodeExpansion: false 集群保持关闭状态,视图以它为中心。

排序和缩小 ​

单击任意列标题进行排序;再次单击可反转。可过滤的列在标题中增加一个控件缩小行数— 中的每一列派生集有一个,并且您声明自己的专栏可以通过询问获得一个filterable: true.

您获得的控件遵循列的 type,因此您可以询问列它实际上能够回答什么:

type控制火柴
numberRangeMin / Max 对区间内;两端都可以留空
select · multiselect · boolean列所保存值的 dropdown确切的值,或当单元格是列表时的成员资格
text · regex · 无类型文本框不区分大小写的子字符串

下拉列表是根据列自己的值而不是声明的选项列表构建的,因此它永远不会提供返回空的选项。当超过 50 个不同的值时,它会为文本框留出空间——这么长的下拉菜单不是任何人都可以使用的控件。

行过滤器不是图表的过滤器。它改变了你正在阅读的内容阅读:画布保持不变,而Visibility专栏继续报道旁边的真相,因此两者可以存在分歧而不会出错。将缩小范围推到画布上是一个单独且明确的行为 - 见下文。

码头的计数反映了两者:一旦缩小,40 nodes就变成12 of 40 nodes。

将过滤器应用于图表 ​

应用于图表,在扩展坞的工具栏中,隐藏列过滤器遗漏的元素。它是两种过滤之间的桥梁:缩小行范围,直到表格列出您关心的内容,然后按一次,画布会显示相同的内容。

这是一次性推送,而不是实时链接,按钮会显示您处于三种状态中的哪一种:

按钮含义
Apply to graph,未点亮没有什么被推动。禁用直到列过滤器实际缩小某些范围。
Clear、点亮该图已被过滤,并且与您的过滤器一致。按 即可恢复。
Apply to graph、点亮该图表已通过 earlier 推送进行过滤,并且您的过滤器已继续。按 使其更新。

有两个属性值得了解,因为它们使推送保持可预测性:

  • 它隐藏了 ** 过滤器遗漏的行** — 永远不会“仅显示这些”。因此,推送后添加的节点保留在画布上。你所提出的只是一个关于某个时刻的陈述,而不是一个长期的疑问。疏散星团的内部只有当它自己的行位于被遗漏的行中时才会变窄。当嵌套行关闭时,没有任何东西命名它们,内部也没有改变。
  • Visibility列是从不推送的一部分,尽管它仍然像其他任何列一样缩小行。它的值是图表的过滤器状态,因此推动它们将隐藏画布上当前的任何内容,然后与自身不一致。

当推送处于活动状态时,计数会报告两半 - 12 of 40 nodes · 28 hidden - 并且过滤器面板会从表行中增长一个命名它并可以清除它,因此推送永远不会是一旦扩展坞折叠起来就找不到的过滤器。

推送作为保留键下的单个过滤器落地,这意味着它与过滤器面板组合而不是与之竞争:您在该面板自己的形式中设置的任何内容都不会破坏推送,并且推送永远不会清除面板的过滤器。两者结合在一起,因此一个节点必须同时生存。

为控件传递 filterGraph: false ,其控件根本无法接触画布:

ts
const options = {
    UI: { mode: 'full', table: { filterGraph: false } },
}

选择 ​

手势效果
单击一行选择该元素
按住 Ctrl / Cmd 键并单击添加或删除一行
按住 Shift 键并单击按照当前列出的顺序取一个范围
全选当前列出的每一行 - 后排序、后过滤
双击选择和将画布居中
悬停突出显示画布上的元素
右键单击元素的上下文菜单;多项选择的一行打开选择的

它可以双向工作:在画布上用橡皮筋绑住一组,然后标记并滚动到匹配的行。该选择与侧边栏的批量操作读取的选择相同,因此循环无需任何额外接线即可关闭。

隐藏行的选择与其他行一样——这就是列出它们的要点。

列 ​

如果没有声明 columns,码头会分三层为您解决问题:

  1. 宣布 — UI.table.columns 彻底获胜。
  2. 从你的方面 — 否则,如果你声明了UI.filter.facets,列将从它们构建。描述一次您的数据,过滤器面板和表格就同意它。
  3. Scanned — 否则读取数据,按 coverage 排序,因此填充良好的键位于最前面,稀疏的尾部位于最右侧。

无论哪种方式,图形感知列都会包装数据。对于节点,Visibility和Label引导——状态槽和名称,这两个东西你可以向下扫描找到一行——在具有集群的图上通过Cluster连接,因为嵌套row 需要它说明它来自哪里。计数将其关闭:Degree,加上具有聚类的图上的 Children。计数位于末尾,因为它们是图形的算术而不是元素自己的数据,并且它们是窄的、固定宽度的列,因此几个数字永远不会占据名称所需的行份额。边缘保持相同的Visibility装订线,然后读作一个句子 - Source / Label / Target。

默认排序是 Label 列,而不是前导列:打开时按 Visibility 排序不会告诉您任何信息,而每行仍然读取 visible。

默认情况下会显示所有内容,并且网格会横向滚动而不是掉落任何内容。在属性较多的节点上,使用 Columns 选择器来关闭不需要的内容 - 这也会将其过滤器控制从标题中删除。

派生列是可过滤的。 它们的标签、类型和对齐方式都已经推断出来,并且 行过滤器 是根据相同类型推断的 - 因此您从未配置的表仍然可以缩小范围。声明的列则相反:除非您另有说明,否则您将得到您所编写的集合,filterable: false。

内置列 ​

tableColumns 保存通用网格无法计算的列,因为它们与元素在图中的位置而不是其数据有关:

js
import { Pivotick, tableColumns } from 'pivotick'

new Pivotick(el, data, {
    UI: {
        mode: 'full',
        table: {
            open: true,
            // Reference a built-in's key through the object rather than typing it —
            // the key itself is namespaced so it can never clash with a data key.
            sort: { key: tableColumns.degree.key, direction: 'desc' },
            columns: [
                tableColumns.visibility,
                { ...tableColumns.degree, label: 'Links' },
                tableColumns.label,
                { key: 'severity', label: 'Severity', type: 'numberRange', filterable: true },
            ],
        },
    },
})

label·degree·degreeIn·degreeOut·visibility·pinned·children·cluster,加上source和target作为边缘。克隆一个来调整它,如上所述。

TableColumn 是一个 FilterFacet,带有一些表示附加功能(width、align、sortable、filterable、hidden、format),这就是为什么分面可以用作不改变的列。

正在导出 ​

CSV 和 JSON 按钮准确地写出您正在查看的内容:此选项卡、按此顺序排列的这些可见列、此排序、此行过滤器。原始值,绝不是列的 format 输出,因此文件保持机器可读。

不是整个图——对于任何有代码的人来说,这都是 graph.getNodes() 的事。通过 export: false 省略按钮。

嵌入页面中的下载

沙盒 iframe 可以完全阻止下载。当这种情况发生时,底座会这样说,而不是留下一个看起来什么也不做的按钮。

规模 ​

在 virtualizeAbove 行(默认为 200)之上,行为 windowed:只有适合视口加上边距的行位于 DOM 中,而滚动条仍然测量整个数据集。排序会重新排序底层数组,而不是 DOM,并且重建会保留滚动位置和选择。

低于阈值的每一行都会被渲染,这使得普通情况易于检查。

选项 ​

选项默认值它的作用
enabledtruefalse(或UI.table: false)完全删除码头
tabs['nodes', 'edges']表的 own 视图。一种不渲染内条
columns / edgeColumns导出的请参阅列
open未设置未设置开始折叠到栏; true开始扩展; false根本不离开码头(Shift+T仍然将其带入)
collapsed折叠的折叠到其标题栏。对于 open: true,'auto' 会遵循可用房间,直到您自己选择
height0.35像素数或画布的一部分。夹紧,使画布保持可用的最小值
sortLabel 列{ key, direction }
rowActivate'select''selectAndCenter' 也会移动画布; 'none' 使行变得惰性
filterGraphtrue优惠适用于图表。 false 用于永远无法过滤画布的底座
nestedtrue将集群的内容作为其自己的行列出。请参阅集群内的节点
export['csv', 'json']false 隐藏按钮
virtualizeAbove200行数高于该行时将被窗口化

底座比桌子容纳的东西还多 ​

该表是扩展坞中的一个窗格,您注册的其他任何内容都是另一个:

js
const dispose = graph.UIManager.addDockTab({
    label: 'Audit',
    render: () => myAuditPane(),        // called once, the first time the pane is opened
    toolbar: () => [clearButton],       // rebuilt on every activation
})

码头的条带上显示 Table │ Audit。切换会交换主体和标题控件,因为Select all、导出和Columns属于表,并且在另一个窗格中没有任何意义。一个窗格根本不渲染任何条带——没有任何东西应该指向具有一种设置的开关。

该表不是一个特殊情况:它来自相同的 addDockTab,因此您注册的窗格是它的平等窗格,而不是它的来宾窗格。 order 放置它(相同的顺序保持注册顺序,并且稍后注册的窗格 - 正如插件总是如此 - 放置在内置窗格之后)。返回的处理器将其移除。

有一个区域,因此无论有多少块玻璃,都有一种高度和一种折叠。两个窗格不能各自竖起一个可调整大小的条带并争夺画布。

因此,可以在不显示的情况下添加:它连接条带(包括折叠条),并等待单击。 activateDockTab 是将一个元素带到前面的单独操作,也是唯一展开码头的操作。

两个级别的切换,以及为什么它们看起来不同 ​

Nodes 和 Edges 是 ** 表格自己的 ** 选项卡,而不是 Dock 的选项卡。它们是单个窗格的两个视图,因此它们没有列在 Audit 旁边 - 这会声称表的视图和单独的窗格是同一类东西。

这两个层次的绘制方式不同,因此它们可以彼此相邻,但仍然可以理解为外部和内部:

看起来像类
Table │ Audit全高选项卡,活动时加下划线,按规则关闭pvt-dock-tabs / pvt-dock-tab
Nodes │ Edges一个小的分段药丸组pvt-dock-views / pvt-dock-view

具有自己视图的窗格执行表格的操作:在其 toolbar 中绘制开关,并在其句柄上调用 refresh() 来更改主体。内部类是公共的,因此您的开关是内置的,而不是对其的重述:

js
function viewSwitch(current, pick) {
    const strip = document.createElement('div')
    strip.className = 'pvt-dock-views'
    for (const view of VIEWS) {
        const button = document.createElement('button')
        button.className = 'pvt-dock-view'
        button.textContent = view.label
        button.classList.toggle('active', view.key === current)
        button.addEventListener('click', () => pick(view.key))
        strip.appendChild(button)
    }
    return strip
}

graph.UIManager.addDockTab({
    label: 'Audit',
    toolbar: (pane) => [viewSwitch(current, (key) => { current = key; pane.refresh() })],
    render: () => renderCurrentView(),
})

这两个级别都从 --pvt-theme-primary 获取主动重音,因此重新设计主题的消费者也会重新设计底座;覆盖任一类以更进一步。

refresh() 不是可选的礼貌 — 停靠栏保留元素 render 交给它,因此交换其自己 DOM 的窗格将使停靠栏在下次到达前台时重新附加旧节点。

请参阅 添加停靠窗格 图库卡以了解实时情况,以及 插件 以了解插件路线。

UI.dock — 地区自己的设置 ​

open、collapsed 和 height 描述的是 region,而不是表,UI.dock 是它们所属的位置:

js
// A dock holding only a plugin's pane, open on load
UI: { mode: 'full', table: false, dock: { open: true, height: 0.3 } }

UI.table 仍然具有相同的三个设置并且始终如此;这些都是荣幸的,并且在两者都设置的情况下UI.dock获胜。当桌子关闭时,到达UI.dock——这是插件选项卡带来的唯一通往码头的门。

程序控制 ​

js
graph.openTable()
graph.closeTable()
graph.toggleTable()

当没有停靠时,每个都是无操作(除 full 或 UI.table: false 之外的任何模式)。 openTable() 还将表的窗格带到前面,因此以表命名的调用会显示一个。要在没有该区域的情况下驱动该区域:

js
graph.UIManager.dock?.setOpen(true)        // the region
graph.UIManager.activateDockTab('table')   // a pane, unfolding the dock if need be
graph.UIManager.getDockTabs()              // what is registered, in strip order

Dock 驱动普通的选择 API,因此任何读取选择的内容都会看到表构建的内容:

js
graph.selectElements([nodeA, nodeB])   // replaces the selection
graph.addToSelection([nodeC])          // nodes only
graph.removeFromSelection([nodeA])

调整大小和折叠 ​

沿着扩展坞的顶部边缘拖动分隔线以调整其大小。无论你要求什么,画布都会保持地板——没有高度的画布不是图表。

折叠 V 形将码头折叠到其标题栏。独自一人,collapsed: 'auto' 会为您做出决定,并将扩展坞折叠起来,布局太短,无法容纳它和可用的画布;当您第一次手动折叠或展开它,或者拖动分隔线时,它会停止决定并将其留给您。

折叠栏仍然为其窗格命名,活动窗格的控件保留在其中 - 表的行数,拓展评论说它正在获取。这就是让面板在扩展坞折叠时到达并被注意到的原因,而无需通过屏幕来说明。单击那里的窗格将打开其上的停靠栏。

展开坞站以显示自身的窗格在其被移除时将区域交回,因此来来往往的窗格会使关闭的坞站保持关闭状态。折叠它、调整它的大小或切换到另一个窗格的结果是:每一个都是您自己对该区域的决定,没有任何东西可以代表您撤消它。

打开扩展坞永远不会移动图表

模拟根据 container 进行调整,而不是画布,因此 chrome 打开和关闭无法更改布局。根据您的喜好调整扩展坞的大小:图表保持不变,并且重新布局在扩展坞打开或关闭时给出相同的结果。