coordinated-data-views

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Coordinated Data Views

协调数据视图

Some data has more than one natural representation. A set of locations has both a map and a list. A dependency network has both a diagram and a node table. A dataset has both a chart and a raw table. When both representations are genuinely useful for different tasks, show them simultaneously and keep them synchronized — this is called a coordinated view.
The core rule: any selection or highlight made in one view is immediately reflected in the other.

有些数据拥有多种天然的呈现形式。一组地点信息可以同时用地图和列表展示;一个依赖网络可以同时用图形和节点表格展示;一个数据集可以同时用图表和原始表格展示。当这两种形式对于不同任务都真正有用时,应同时展示它们并保持同步——这就是所谓的协调视图。
核心规则:在任一视图中进行的选择或高亮操作,都应立即反映在另一个视图中。

When to Use Coordinated Views

何时使用协调视图

Use coordinated views when:
  1. The two representations serve different tasks — the table is for finding/scanning; the visual view is for understanding arrangement or relationships
  2. Users will frequently move between the two — not just glance at one occasionally
  3. The dataset is large enough that the visual view alone doesn't identify individual items, and the table alone doesn't communicate how they relate
Do not add a coordinated view purely for visual richness. If users only ever look at the table and ignore the visual view, it adds complexity without benefit.

在以下场景中使用协调视图:
  1. 两种形式服务于不同任务——表格用于查找/浏览;可视化视图用于理解布局或关系
  2. 用户需要频繁在两种形式间切换——而非偶尔瞥一眼其中一种
  3. 数据集规模足够大,仅靠可视化视图无法识别单个条目,仅靠表格无法传达条目间的关联
不要单纯为了视觉丰富度而添加协调视图。如果用户只看表格而忽略可视化视图,那么它只会增加复杂度而无实际益处。

The Synchronized Selection Model

同步选择模型

Selection state is owned by a single shared store, not by either view. Both views read from and write to the same state.
Table row clicked → shared highlight state updated → both views re-render

Visual element clicked → shared highlight state updated → both views re-render
What synchronization covers:
InteractionEffect in tableEffect in visual view
Click rowRow highlightsCorresponding element highlighted
Click visual elementCorresponding row highlighted, scrolled into viewElement highlighted
Hover rowSubtle row highlightSubtle element highlight
Hover visual elementSubtle row highlightSubtle element highlight
Clear selectionRow returns to defaultElement returns to default
Scroll-into-view: When a visual element is clicked, the table must scroll to bring the corresponding row into view. A row that is highlighted but off-screen is useless.

选择状态由单一共享存储管理,而非任一视图单独拥有。两个视图均读取并写入同一状态。
点击表格行 → 更新共享高亮状态 → 两个视图重新渲染

点击可视化元素 → 更新共享高亮状态 → 两个视图重新渲染
同步覆盖的交互操作:
交互操作表格中的效果可视化视图中的效果
点击行行高亮对应元素高亮
点击可视化元素对应行高亮并滚动至可见区域元素高亮
悬停行行轻微高亮对应元素轻微高亮
悬停可视化元素对应行轻微高亮元素轻微高亮
清除选择行恢复默认状态元素恢复默认状态
滚动至可见区域: 当点击可视化元素时,表格必须滚动以将对应行带入视野。高亮但处于屏幕外的行毫无用处。

Consistent Colour Coding

一致的颜色编码

Colour meaning must be identical in both views. If a category is orange in the table badge, it is orange in the visual view. Never use different colour assignments for the same data in different representations.
Define colours centrally:
ts
const CATEGORY_COLORS = {
  groupA: 'hsl(24, 80%, 55%)',
  groupB: 'hsl(210, 70%, 55%)',
  groupC: 'hsl(145, 60%, 45%)',
} as const;
Both the table cell renderer and the visual element renderer import from the same source.
A shared legend appears once in the layout — not duplicated in each view.

两种视图中的颜色含义必须完全一致。如果表格中的某类标签是橙色,那么它在可视化视图中也必须是橙色。绝不能对同一数据在不同形式中使用不同的颜色分配。
集中定义颜色:
ts
const CATEGORY_COLORS = {
  groupA: 'hsl(24, 80%, 55%)',
  groupB: 'hsl(210, 70%, 55%)',
  groupC: 'hsl(145, 60%, 45%)',
} as const;
表格单元格渲染器和可视化元素渲染器均从同一来源导入颜色定义。
布局中只需显示一个共享图例——不要在每个视图中重复显示。

Layout

布局

The split between views depends on which is primary:
Table-primary (exploration, data management): Table takes 60–70% of the width; visual view is a companion panel on the right or bottom.
Visual-primary (understanding arrangement and relationships): Visual view takes 60–70%; table is a supporting panel.
Equal weight: A 50/50 split with a draggable divider. Persist the user's preferred split.
┌─────────────────────┬────────────────┐
│                     │                │
│   Table (primary)   │  Visual view   │
│                     │                │
└─────────────────────┴────────────────┘
On mobile, show one view at a time with a tab or toggle to switch. Do not attempt to show both on a small screen.

视图的分割比例取决于哪个是主视图:
表格为主(探索、数据管理): 表格占据60–70%的宽度;可视化视图作为辅助面板位于右侧或底部。
可视化视图为主(理解布局和关系): 可视化视图占据60–70%的宽度;表格作为辅助面板。
权重相等: 50/50的分割比例,搭配可拖动的分隔条。保存用户偏好的分割比例。
┌─────────────────────┬────────────────┐
│                     │                │
│   表格(主视图)     │  可视化视图     │
│                     │                │
└─────────────────────┴────────────────┘
在移动端,一次只显示一个视图,通过标签页或切换按钮进行切换。不要尝试在小屏幕上同时展示两个视图。

Visual View Controls

可视化视图控件

Controls that affect only the visual representation belong in the visual view panel, not in the table area.
Common visual-specific controls:
  • Zoom / pan — navigation (usually handled by the rendering library)
  • Layer opacity — reveal overlapping regions on a dense map or diagram
  • Layer toggle — show/hide categories or types
  • Reset view — fit all elements into view; extent reset for maps
These controls do not affect the table. Do not put them in the table toolbar.
Controls that affect the shared data (filters, time range, category selection) belong outside both views, above or beside the layout, since they affect what appears in both.

仅影响可视化呈现的控件应放在可视化视图面板中,而非表格区域。
常见的可视化专属控件:
  • 缩放/平移 —— 导航(通常由渲染库处理)
  • 图层透明度 —— 在密集地图或图形中显示重叠区域
  • 图层切换 —— 显示/隐藏类别或类型
  • 重置视图 —— 将所有元素适配到视图中;重置地图范围
这些控件不影响表格。不要将它们放在表格工具栏中。
影响共享数据的控件(过滤器、时间范围、类别选择)应放在两个视图之外,位于布局上方或旁边,因为它们会影响两个视图中的内容。

Highlighting vs. Selection

高亮与选择

These are distinct states:
Highlight (hover): Transient, shown while the pointer is over an element. Does not persist. Both views show a subtle version (e.g. 50% opacity overlay, or a faint row background). No interaction required to clear it — moving the pointer clears it.
Selection (click): Persistent until explicitly cleared. Both views show a strong, unambiguous visual (e.g. bright border, saturated colour, selected row background). Cleared by clicking elsewhere or pressing Escape.
Do not conflate these. A hover highlight that persists after the pointer leaves is confusing.

这是两种截然不同的状态:
高亮(悬停): 临时状态,仅在指针悬停在元素上时显示,不会持久保留。两个视图均显示轻微的视觉效果(例如50%透明度的覆盖层,或淡淡的行背景色)。无需手动清除——移动指针即可清除。
选择(点击): 持久状态,直到显式清除为止。两个视图均显示清晰明确的视觉效果(例如明亮的边框、饱和的颜色、选中的行背景色)。可通过点击其他区域或按下Escape键清除。
不要混淆这两种状态。如果悬停高亮在指针移开后仍然保留,会造成用户困惑。

Performance Considerations

性能考量

Coordinated views can trigger expensive re-renders if not carefully managed.
  • Debounce hover highlights — do not update on every pointer-move event, only when the target element changes
  • Use stable identity for items (a consistent ID) so React (or equivalent) can reconcile without re-creating elements
  • For large datasets (1000+ items), virtualize the table regardless of the visual view
  • For canvas- or WebGL-rendered views, avoid re-creating elements on each highlight — update style properties on the existing ones instead

如果管理不当,协调视图可能会触发昂贵的重新渲染操作。
  • 防抖悬停高亮——不要在每次指针移动事件时都更新,仅在目标元素变化时更新
  • 为条目使用稳定的标识(一致的ID),以便React(或类似框架)可以在不重新创建元素的情况下进行协调
  • 对于大型数据集(1000+条目),无论可视化视图如何,都要对表格进行虚拟化处理
  • 对于基于Canvas或WebGL渲染的视图,避免在每次高亮时重新创建元素——而是更新现有元素的样式属性

Review Checklist

审核清单

  • Is selection state shared between views via a single store — not duplicated?
  • Does clicking a row highlight the corresponding visual element, and vice versa?
  • Does clicking a visual element scroll the table to the corresponding row?
  • Are colour assignments identical in both views, defined from a single source?
  • Is the shared legend shown once, not duplicated per view?
  • Are visual-specific controls (zoom, transparency, layer toggle) in the visual panel, not the table?
  • Are hover highlight and click selection visually distinct states?
  • On mobile, is there a clear way to switch between views?
  • Are hover events debounced to avoid unnecessary re-renders?
  • 选择状态是否通过单一共享存储在视图间共享——而非重复存储?
  • 点击表格行是否会高亮对应的可视化元素,反之亦然?
  • 点击可视化元素是否会使表格滚动至对应行?
  • 两个视图中的颜色分配是否一致,且源自单一来源?
  • 共享图例是否只显示一次,而非在每个视图中重复显示?
  • 可视化专属控件(缩放、透明度、图层切换)是否位于可视化面板中,而非表格区域?
  • 悬停高亮和点击选择是否为视觉上截然不同的状态?
  • 在移动端,是否有清晰的方式在视图间切换?
  • 悬停事件是否已防抖以避免不必要的重新渲染?