用途
协调数据视图(Coordinated Data Views)用于处理同一份数据同时具有两种自然表示形式的场景。一组位置既有地图也有列表;一个依赖网络既有关系图也有节点表格;一个数据集既有图表也有原始表格。当两种表示形式对不同任务都真正有用时,应当同时展示它们并保持同步——这就是所谓的协调视图。
核心规则是:在任意一个视图中做出的选择或高亮,都会立即反映到另一个视图中。
何时使用
当满足以下条件时使用协调视图:
- 两种表示形式服务于不同任务——表格用于查找与扫描,可视化视图用于理解排列或关系。
- 用户会频繁在两个视图之间来回切换,而不仅仅是偶尔瞥一眼。
- 数据集足够大,单靠可视化视图无法识别单个项目,单靠表格又无法传达它们之间的关系。
不要纯粹为了视觉丰富度而添加协调视图。如果用户只看表格而忽略可视化视图,它只会增加复杂度而没有收益。
同步选中模型
选中状态由单一共享存储拥有,而非由任一视图持有。两个视图都读写同一份状态。
- 点击表格行 → 更新共享高亮状态 → 两个视图重新渲染
- 点击可视化元素 → 更新共享高亮状态 → 两个视图重新渲染
同步覆盖的交互包括:
- 点击行:行高亮,对应元素高亮。
- 点击可视化元素:对应行高亮并滚动进入视野,元素高亮。
- 悬停行:行的细微高亮,元素的细微高亮。
- 悬停可视化元素:行的细微高亮,元素的细微高亮。
- 清除选择:行恢复默认,元素恢复默认。
滚动进入视野:当点击一个可视化元素时,表格必须滚动以将对应行带入视野。一个已高亮但位于屏幕之外的行是没有用的。
一致的颜色编码
颜色的含义在两个视图中必须完全一致。如果某个类别在表格徽章中是橙色,那么在可视化视图中也应是橙色。绝不要对同一数据在不同表示中使用不同的颜色分配。
集中定义颜色:
const CATEGORY_COLORS = {
groupA: 'hsl(24, 80%, 55%)',
groupB: 'hsl(210, 70%, 55%)',
} as const;
两个渲染器从同一来源导入。共享图例在布局中只出现一次,而不是每个视图各一份。
颜色编码状态,标签编码身份。当每个项目已经显示自己的名称时,给同一类型的项目赋予相同颜色,把颜色只用于状态:计划中、部分使用、空闲、不可用。同一色相的深浅读起来是量级,而不是不同的事物;一个灰色项目会与表示空白的灰色冲突。通过在悬停或选中时高亮某个项目的所有出现位置,来表明该项目重复出现。这样图例只需解释状态,而永远不列出项目,因为标签已经承担了这一点。
布局
视图之间的划分取决于哪个是主要的:
- 表格为主(探索、数据管理):表格占 60–70% 宽度;可视化视图是右侧或底部的伴随面板。
- 可视化为主(理解排列与关系):可视化视图占 60–70%;表格是辅助面板。
- 等权重:50/50 分割,带可拖动分隔条。持久化用户偏好的分割比例。
在移动端,一次只显示一个视图,用标签页或切换按钮切换。不要尝试在小屏幕上同时显示两个视图。
时间线与日历网格
将每个标记按其覆盖的时间放置在时间轴上,而不是按单位数量。当每天的单位数量变化时,给每天相同宽度,并把当天实际拥有的单位在其中均分,这样一个以当天最后一个单位结束的标记就结束在当天的时间缝上。由单位计数占比推导出的宽度,一旦每天数量不同就会漂移,条形随即与旁边的网格相矛盾,读者便对两者都不信任。
用同一个单位——一个方格加一个间隙——构建日历或矩阵,并让每一行都按这个节奏排列,包括标签。当窗口变化时,改变显示的列数,而不是单元格的尺寸。让网格紧贴其行标签,把多余宽度留在远端;宽屏上的弹性标签列会把网格推离它所标注的对象。
可视化视图控件
仅影响可视化表示的控件应放在可视化视图面板中,而不是表格区域。常见的可视化专属控件包括:缩放/平移(导航,通常由渲染库处理)、图层透明度(在密集地图或图表上揭示重叠区域)、图层开关(显示/隐藏类别或类型)、重置视图(将所有元素适配进视野;地图则重置范围)。这些控件不影响表格。不要把它们放在表格工具栏中。
影响共享数据(筛选、时间范围、类别选择)的控件应放在两个视图之外,位于布局上方或旁边,因为它们影响两个视图中显示的内容。
高亮与选中
这是两种不同的状态:
- 高亮(悬停):瞬态,指针位于元素上时显示。不持久。两个视图都显示细微版本(例如 50% 不透明度覆盖层,或浅淡的行背景)。无需交互即可清除——移开指针即清除。
- 选中(点击):持续存在,直到显式清除。两个视图都显示强烈、明确无歧义的视觉(例如亮边框、饱和色、选中行背景)。通过点击其他位置或按 Escape 清除。
不要混淆这两者。指针离开后仍持续存在的悬停高亮会造成困惑。
数据旁的分析
一个解释或总结屏幕上数据的面板属于协调视图,而不是对话框。把它打开在表格旁边,非模态,页面仍可滚动。用户可以逐条对照其来源行进行核对。模态框恰恰会隐藏这些行。
性能考量
如果管理不当,协调视图可能触发昂贵的重新渲染。
- 对悬停高亮做防抖——不要在每个指针移动事件上都更新,只在目标元素变化时更新。
- 为项目使用稳定身份(一致的 ID),以便 React(或等价框架)可以在不重新创建元素的情况下进行协调。
- 对于大数据集(1000+ 项目),无论可视化视图如何,都要虚拟化表格。
- 对于 canvas 或 WebGL 渲染的视图,避免在每次高亮时重新创建元素——改为更新现有元素的样式属性。
审查清单
- 选中状态是否通过单一存储在两个视图之间共享——而非重复?
- 点击行是否会高亮对应的可视化元素,反之亦然?
- 点击可视化元素是否会让表格滚动到对应行?
- 两个视图中的颜色分配是否完全一致,且来自单一来源?
- 共享图例是否只显示一次,而不是每个视图重复?
- 可视化专属控件(缩放、透明度、图层开关)是否在可视化面板中,而非表格中?
- 分析或总结面板是否位于数据旁边、非模态、页面仍可滚动?
- 悬停高亮与点击选中是否为视觉上可区分的状态?
- 在移动端,是否有清晰的方式在视图之间切换?
- 悬停事件是否做了防抖,以避免不必要的重新渲染?