业务故事站
P4 Gotham

多视图联动:图、地图、时间轴一条线

情报分析最怕"三处数据对不上"。多视图联动把图、地图、时间轴装进同一个会话:在一个视图框选或点选,筛选表达式会沿 EventBus 同步广播到其他视图,多条件按 intersect(交集)组合。看完这 4 个故事,你就能自己搭一个"框一个区域、点一个人、看一条线索"的联动分析台。

情报分析师 风控分析师 交叉筛选 EventBus 时间轴 共 4 个故事

能 / 不能速览

✅ 这个主题能做
  • 创建图(graph)/地图(map)/时间轴(timeline)/列表(list)/实体(entity)视图会话,同屏并行
  • 在一个视图框选区域 / 点选实体,筛选表达式(SelectionExpr)经 EventBus 广播到其他视图同步收窄
  • 多条件按 intersect 语义(AND 交集)组合,逐条去重,可随时清空还原
  • 会话间建立 cross_filter 联动关系,filter 沿链接广播,带 TraceID 全程可追溯
  • 按当前筛选联动过滤图节点、融合实体与属性记录,limit 支持 1~1000
⛔ 这个主题做不了
  • 联动载荷是筛选表达式而非任意 SQL:非法算子 / 空字段返回 GOTHAM_SELECTION_INVALID
  • 联动查询有硬上限:limit 超过 1000 返回 GOTHAM_VIEW_LIMIT_EXCEEDED,不是静默截断
  • 地图是要素叠加(点 / 线 + 经纬度框选),未接真实底图与瓦片服务
  • 时间轴是事件列表 + 直方图,未接真实时序数据库,海量点不支持
  • 组合模式以 intersect 为准,union(并集)/ overwrite(替换)仅预留

适用角色

本主题面向两个角色:

  • 情报分析师(核心):在多视图会话里做交叉分析,框选 / 点选触发联动,是"图 + 地图 + 时间轴"三视图的主使用者。
  • 风控分析师:复用同一套联动机制核查资金、人员、事件的时间与空间关系,属于高价值进阶用户。

平台管理员负责数据接入与权限;决策者消费最终报告,不直接操作联动台。

能力速览(能做什么)

多视图会话

graph / map / timeline / list / entity 五种视图会话,名称全局唯一,当前筛选状态持久化保存。

筛选表达式 SelectionExpr

维度 + 算子 + 值的组合(eq / in / between / within / contains 等白名单算子),多条件按 intersect(AND)求交集。

EventBus 联动广播

进程内发布订阅:ApplyFilter 沿 cross_filter 链接广播 global:cross_filter 事件,携带 source / target / exprs / TraceID。

联动查询

按当前筛选联动过滤图节点、融合实体与通用属性记录,一次查询返回 target_type + count + 数据。

会话间联动关系

cross_filter 链接(source → target)支持启停开关,Enabled=false 时广播自动跳过。

调整指南(怎么调整)

  • 改筛选范围:追加新表达式后系统与旧条件求交集(intersect),同一条件按 JSON 去重;想回到全量就调 DELETE filter 清空并广播空筛选。
  • 改联动目标:给会话建 / 删 cross_filter 链接决定广播去哪;目标会话 Enabled=false 时该链路被跳过。
  • 改查询粒度:地图框选用 within(包围盒 {north,south,east,west}),时间轴范围用 between(恰好 2 个端点值),属性收窄用 eq / in / contains。
  • 改返回量:QueryLinked 的 limit 参数 0 视为默认 100,最大 1000;结果多就分页取。
  • 改视图元信息:会话可改名(不能与他人重名)、改描述、改 view_type,config 里放渲染参数。

做得好的场景

多视图联动把"空间 + 时间 + 关系"三种视角收进同一套系统,特别适合以下场景:
  • 态势全景感知:图、地图、时间轴同屏,一次看全"谁在哪、什么时间、和谁有关",替代以前三处软件来回切。
  • 秒级收窄:框一个区域 / 点一个人,其他视图立即同步,分析节奏从"半天对数据"变成"几秒切视角"。
  • 交叉锁定:region + event_type + 时间范围多条件求交集,把"华东的 incident"这类跨维度问题一步问清。
  • 分析过程可复现:会话与筛选状态持久化,联动广播带 TraceID,谁触发、广播到哪都有据可查。

限制与不足

以下是明确的边界,使用前先知道:
  • intersect 语义:多条件必须同时满足(AND),union / overwrite 组合模式仅预留,MVP 没有"或"。
  • limit 硬上限:联动查询 1~1000,超限报错而非截断;内部取数上限 10000 条后再过滤。
  • 简化底图与时间轴:地图无真实底图 / 瓦片,时间轴无真实时序库,海量时空数据不在能力范围。
  • 图联动按节点属性:筛选作用于节点属性,边不直接参与表达式匹配,边的联动要靠两端节点体现。
  • 单机 EventBus:进程内同步广播,不跨实例;协同工作流属 V2 范围。

场景故事

故事 1 苏分析师建三视图会话,把"玄武集团关联网络"装进一个分析台
背景
苏分析师是玄武集团情报组的商业情报分析师,负责盯关联企业与人员的动态。2026 年 7 月,她要把"玄武集团关联网络"做成一个常驻分析台:左边看关系图,中间看地图要素,下边看时间轴事件,三个视角同一份数据、同屏切换。今天的第一步:把三视图会话建出来。
传统做法对比
以前她要开三个软件:画图工具放关系、外部地图标地点、表格拉时间线,光对齐"哪个人在哪个地点"就要花掉半个上午;每周汇总一次关联动态大约 4 小时。现在三个视图共用一个会话,建好即同屏。
角色
情报分析师(苏分析师),拥有图、地图、时间轴视图的访问与联动权限。
操作步骤
  1. 登录平台(admin / admin1,端口 18083 或经 5173 的 /gotham-api 前缀)
  2. 进入"多视图联动"页面,打开"新建视图会话"
  3. 依次创建三个会话:图视图(graph,名称"玄武关系图")、地图视图(map,名称"玄武落点地图")、时间轴视图(timeline,名称"玄武事件时间轴")
  4. 在"联动关系"里把三张会话两两建 cross_filter 链接(图→地图、图→时间轴、地图→时间轴)
系统响应
每个会话创建成功返回会话 id,例如:
{ "code": 0, "data": { "id": 1 } }
GET /views/sessions 按 id 升序返回三张会话;GET /views/links 返回已建联动关系(source_session_id / target_session_id / link_type=cross_filter / enabled=true)。
结果洞察
同屏后图上有 10 个节点 + 8 条边(玄武集团为 org 型、密级 secret;张远 / 李四 / 王敏 / 吴刚 / 赵敏为人员;泰和轮、远航号为船舶),地图有 6 个要素(北京联络点 / 上海货栈 / 广州港口 / 青岛锚地 / 深圳观察点 / 华北-华东航线),时间轴有 9 条 2026-07~08 事件。三份数据互相能对上,苏分析师第一次不用手工对齐坐标。
调整建议
用 Description 区分会话用途;想长期保留就固定会话名,重名会报"已存在";视图渲染参数(如初始缩放)放进 config,改动不影响筛选状态。
动手试一试
登录:http://127.0.0.1:18083(或 Vite 5173),账号 admin / admin1。页面路径:多视图联动 → 新建视图会话。输入内容:graph / map / timeline 三个会话,再建 cross_filter 链接。预期结果:GET /views/sessions 返回 3 条,/views/links 返回若干条 link。
限制提示
视图会话 name 全局唯一,重复创建同名会话会报错;联动关系同 source+target+link_type 去重,重复建会提示"该会话间联动关系已存在";删除会话会级联删除其出边与入边联动关系。
故事 2 地图上框选华东区域,图和时间轴同步收窄
背景
2026 年 7 月 12 日,天河贸易发生一笔单笔大额资金划转(transferred_to,金额 50 万,关联玄武集团),苏分析师要把视角收窄到华东区域——上海货栈、青岛锚地都在这一带,她想看看华东到底牵扯了哪些节点和事件。
传统做法对比
以前她要在图上手动圈节点,再回表格逐条筛事件,两轮下来 40 分钟起步,还容易漏掉"有地图要素但没画进图"的关联。现在框选一次,图与时间轴自动跟着收窄,几秒完成。
角色
情报分析师(苏分析师),以地图视图为触发源,联动图与时间轴两个目标会话。
操作步骤
  1. 打开"玄武落点地图"会话,用框选工具圈出华东区域(上海、青岛一带)
  2. 页面把框选转成筛选表达式并 POST /views/sessions/:id/filter
  3. 系统校验表达式后合并进会话筛选(intersect),并沿 cross_filter 链接广播
  4. 切换到图会话与时间轴会话,观察节点与事件收窄
系统响应
POST /views/sessions/:id/filter 返回当前状态:
{
  "session_id": 2,
  "view_type": "map",
  "filters": [{ "field": "region", "op": "eq", "value": "华东" }],
  "target_count": 2
}
广播事件 topic=global:cross_filter,payload 含 source / target / exprs 与 TraceID;图会话联动查询 target=graph 返回华东节点(李四、赵敏、天河贸易、泰和轮),时间轴 target=timeline 收窄为上海 / 青岛事件。
结果洞察
华东收窄后,图上只剩 4 个节点(李四·玄武集团、赵敏·天河贸易、天河贸易、泰和轮)与相关边(transferred_to、shipped_to),时间轴只剩 3 条:7-05 泰和轮离港、7-12 天河大宗交易、8-01 远航号靠泊青岛。苏分析师一眼看出"华东是资金与货物的中转走廊"。
调整建议
想一次圈多个区域用 in 算子(values 数组);想限定事件类型再追加一条 event_type 表达式(intersect 交集);框选区域用 within 包围盒更贴合地图手绘轨迹。
动手试一试
登录:admin / admin1。页面路径:多视图联动 → 地图视图框选华东。输入内容:POST /views/sessions/:id/filter,exprs=[{"field":"region","op":"eq","value":"华东"}]。预期结果:返回 ViewState 且 target_count=2;图视图只剩华东节点,时间轴只剩上海 / 青岛事件。
限制提示
筛选表达式须过算子白名单,未知算子 / 空字段返回 GOTHAM_SELECTION_INVALID(400);intersect 语义下新增条件与旧条件必须同时满足;地图框选依赖经纬度要素,无坐标的节点不会出现在地图上。
故事 3 图上点选"张远",联动到地图位置与时间轴事件
背景
2026 年 8 月 11 日时间轴标记了一条"华北联络点集会"(meeting,高严重度),关联实体是张远。苏分析师想在图上点一下张远,看他在地图上的落点、在时间轴上的活动轨迹,把"这个人最近都在干什么"一次问清。
传统做法对比
以前查一个人要从关系表、通讯记录、出差报表里各翻一遍,平均 30 分钟才能拼出"人 + 地点 + 时间";现在点一下节点,三视图同时把这个人高亮出来,2 分钟成稿。
角色
情报分析师(苏分析师),以图视图为触发源,联动地图与时间轴。
操作步骤
  1. 在"玄武关系图"会话中点选张远节点(graph:person:zhy)
  2. 页面生成实体筛选表达式 entity_id = graph:person:zhy,POST /views/sessions/:id/filter 并广播
  3. 地图会话按表达式联动:定位北京联络点(116.40, 39.90)
  4. 时间轴会话按表达式联动:列出张远关联事件
系统响应
GET /views/sessions/:id/linked?target=graph 返回联动结果:
{
  "target_type": "graph",
  "count": 1,
  "nodes": [{ "id": "graph:person:zhy", "type": "person", "label": "张远",
    "properties": { "name": "张远", "region": "华北", "organization": "玄武集团" } }]
}
时间轴联动 target=timeline 返回"华北联络点集会"(2026-08-11,meeting,北京);地图要素"北京联络点"同步高亮。
结果洞察
张远的三条线索在交叉点合拢:他是玄武集团 member_of 成员(关系视角)、落点在北京联络点(空间视角)、8-11 参加了高严重度集会(时间视角)。苏分析师据此把他标为重点关注人物,并把"8-11 集会"纳入后续模式识别观察。
调整建议
想对比多个对象用 in 表达式同时选中张远 + 李四;张远与李四之间还有一条 associated_with 双向边(weight=2),点选后展开邻居即可看到两人直接关联;联动后保留当前会话便于回看。
动手试一试
登录:admin / admin1。页面路径:多视图联动 → 图视图点选张远。输入内容:exprs=[{"field":"entity_id","op":"eq","value":"graph:person:zhy"}]。预期结果:地图高亮北京联络点,时间轴显示 8-11 华北联络点集会,linked 查询 count=1 返回张远节点。
限制提示
图联动匹配节点属性(含 entity_id / entity_type 别名),边不直接参与筛选;时间轴里未挂 entity_id 的事件(如 8-15 华南航线异常)不会被实体筛选命中;limit 超 1000 返回 GOTHAM_VIEW_LIMIT_EXCEEDED。
故事 4 linked 结果合并交叉分析:华东的 incident 到底有几起
背景
风控小何是玄武集团的风控分析师,2026 年 8 月中旬她被问到:"华东区域的 incident(事件异常)最近有几起?"她需要把 region=华东 与 event_type=incident 两个条件同时命中——这正是 intersect 语义的典型用法。
传统做法对比
以前要从两份表各筛一次再手工取交集,表格操作加核对约 20 分钟;要是忘了 AND 语义很容易把"华东的所有记录 + 全国的所有 incident"两张表错误相加。现在表达式一叠加,交集结果一次返回。
角色
风控分析师(风控小何),在时间轴会话上叠加两条筛选表达式,交叉验证联动机制。
操作步骤
  1. 在时间轴会话上先应用一条表达式 region = 华东
  2. 再追加一条表达式 event_type = incident,系统按 intersect 与旧条件求交集
  3. 调 GET /views/sessions/:id/linked?target=timeline 查看时间轴联动结果
  4. 对照 GET /views/sessions/:id/filter 返回的 filters 列表,确认两条表达式都在
系统响应
ApplyFilter 返回的 ViewState.filters 包含两条表达式:
[
  { "field": "region", "op": "eq", "value": "华东" },
  { "field": "event_type", "op": "eq", "value": "incident" }
]
linked?target=timeline 返回时间轴事件中同时满足两者的记录:上海货栈异常(2026-07-25,incident,上海,关联天河贸易)。
结果洞察
交集结果只有 1 起:上海货栈异常。风控小何确认了 intersect 的 AND 语义——8-06 广州港口检查虽也是 incident,但 region 是华南,被 region 条件排除;8-15 华南航线异常同样落在华南。交叉分析把"华东的 incident"精确锁定为 1 起。
调整建议
想排除某类用 not_in;想按时间范围筛选用 between(恰好 2 个端点);多套交叉条件可以分别存成不同会话切换,不必反复重建;清空筛选用 DELETE /views/sessions/:id/filter 并广播空筛选。
动手试一试
登录:admin / admin1。页面路径:多视图联动 → 时间轴会话。输入内容:先应用 region=华东,再应用 event_type=incident。预期结果:filters 含两条表达式,linked?target=timeline 返回 1 条(上海货栈异常 07-25)。
限制提示
union / overwrite 组合模式仅预留,MVP 只有 intersect(AND);字段缺失的记录按"不满足"处理(保守过滤),可能漏掉无 region 属性的实体;联动查询 limit 默认 100、最大 1000。

常见问题

联动是"实时"的吗?

是进程内的同步广播。会话间建好 cross_filter 链接后,ApplyFilter 会立即沿链接发布 global:cross_filter 事件,目标会话随即收到筛选表达式;广播带 TraceID,事件链路可追溯。它是单机 EventBus,不跨实例。

intersect(交集)是什么意思?

多条筛选表达式必须同时满足才保留记录,即 AND 逻辑。例如"region=华东 且 event_type=incident",最终只返回同时满足两条件的事件。同一条表达式重复追加会按 JSON 去重。

图联动能直接筛选"边"吗?

不能。筛选表达式作用于图节点的属性(含 id / type / label / entity_id / entity_type 别名),边不直接参与匹配。想按边找关联,就通过节点筛选后再展开邻居来看边。

为什么地图是"简化"的?

当前地图为要素叠加(点 / 线 + 经纬度框选),未接真实底图与瓦片服务,也没有 PostGIS 空间索引,属于 SQLite bbox 数值比较的降级实现。海量时空数据或真实制图需求不在 MVP 范围。

联动查询能返回多少条?

limit 参数 0 视为默认 100,硬上限 1000,超过返回 GOTHAM_VIEW_LIMIT_EXCEEDED(422)而不是静默截断;内部取数上限 10000 条后再做过滤。

主题小结

一句话:多视图联动的玩法是"建会话 → 框选 / 点选 → 表达式广播 → 全视图收窄"。记住三个边界:组合默认 intersect(AND)、联动查询 limit 1~1000、地图与时间轴是简化实现。会建会话、会加表达式、会看 linked 结果,你就掌握了多源情报的"空间 × 时间 × 关系"三维分析法。