Metabase 嵌入 SDK 点击行为定制:MetabaseClickAction 类型与 mapQuestionClickActions 插件完全指南

原创2026-09-09 20:54:541,722 阅读
文章标签:数据分析数据可视化后端前端

Metabase 嵌入 SDK 点击行为定制:MetabaseClickAction 类型与 mapQuestionClickActions 插件完全指南

Metabase 的模块化嵌入 SDK(Modular Embedding SDK)允许你在自己的 React 应用中直接嵌入交互式图表与仪表盘。当用户点击图表中的数据点时,Metabase 默认会弹出一个操作菜单(如"查看详情""钻取""自动洞察"等)。MetabaseClickAction 就是描述这些菜单操作项(以及自定义操作项)的核心类型,而 mapQuestionClickActions 插件则是对其进行接管、追加或替换的入口。读完本文,你将理解 MetabaseClickAction 的类型骨架与 name 字段的含义、MetabaseClickActionPluginsConfig 的函数签名,并掌握如何在 MetabaseProvider 全局或 InteractiveQuestion 组件级别定制点击行为。

一、MetabaseClickAction 类型定义解析

该类型定义位于 docs/embedding/sdk/api/snippets/MetabaseClickAction.md,其完整声明如下:

type MetabaseClickAction = {
  name: string;
} & Record<string, any>;

类型声明表:

Name Type
name string

这是一个非常"宽松"的类型:唯一强制字段是 name,其余字段全部通过 Record<string, any> 放开。这种设计带来的两个直接推论:

  • 每个点击操作项都必须有一个字符串类型的 name,用于在操作项集合中标识该动作;
  • 其余属性(如标题、图标、按钮形态、点击回调等)均不强制,可按需附加,SDK 不会在类型层面阻止你扩展任何字段。

与源码 ClickAction 的关系

从 SDK 源码看,SDK 暴露给应用侧的 MetabaseClickActionPluginsConfig 实际操作的是来自 metabase/visualizations/types 的 ClickAction(见 frontend/src/metabase/embedding-sdk/types/plugins.ts)。MetabaseClickAction 可以理解为面向 SDK 使用者的、对外文档化的简化视图:它以 name 为强制锚点,其余信息对应用开放。因此在实际代码中,一个操作项通常还会携带 title(菜单标题)、onClick(点击回调)等字段,这些字段正是通过 Record<string, any> 部分被接纳的。

二、name 字段:操作项的标识锚点

name 是 MetabaseClickAction 唯一强制字段,其作用主要有三点:

  1. 唯一标识:在 clickActions 数组中区分不同的操作项,便于插件对既有操作做增删改;
  2. 保证可扩展性:有了 name 这个稳定的锚点,其余字段可以被自由扩展而不破坏类型结构;
  3. 序列化友好:string 类型保证操作项可以被安全地序列化、比对与记录。

三、使用场景:mapQuestionClickActions 插件

MetabaseClickAction 不会独立出现,它总是作为 mapQuestionClickActions 插件的输入与输出类型被消费。该插件的类型定义见 MetabaseClickActionPluginsConfig.md:

type MetabaseClickActionPluginsConfig = (
  clickActions: MetabaseClickAction[],
  clickedDataPoint: MetabaseDataPointObject,
) =>
  | MetabaseClickAction[]
  | {
      onClick: () => void;
    };

参数表:

Parameter Type
clickActions MetabaseClickAction[]
clickedDataPoint MetabaseDataPointObject

返回值:

  • MetabaseClickAction[]:返回一组操作项(可原样返回、追加或替换);
  • { onClick: () => void }:返回一个立即执行的回调对象,表示"不弹菜单,直接执行"。

官方文档(docs/embedding/sdk/plugins.md)对它的定位是:自定义用户点击仪表盘或图表数据点时发生的行为;既可以在全局使用,也可以在组件级别使用。

四、clickedDataPoint 参数:被点击数据点的完整信息

第二个参数 clickedDataPoint 的类型是 MetabaseDataPointObject(见 MetabaseDataPointObject.md),它把"用户点到了哪里"完整地带给插件:

type MetabaseDataPointObject = {
  column?: {
    display_name?: string;
    name?: string;
  };
  data?: Record<string, string | number | null | boolean | object>;
  event?: MouseEvent;
  question?: MetabaseQuestion;
  raw?: {
    column?: Record<string, any>;
    data?: {
      col: Record<string, any> | null;
      value: string | number | null | boolean;
    }[];
    event?: MouseEvent;
    value?: string | number | null | boolean;
  };
  value?: string | number | null | boolean | object;
};

关键字段速览:

字段 含义
value 被点击单元格的值(字符串/数字/布尔/对象等)
column 被点击列的信息,含 name(列名)与 display_name(显示名)
data 以列名为键的整行数据记录
event 触发点击的原生 MouseEvent
question 当前查询对应的 MetabaseQuestion 对象
raw 底层未加工的数据与事件信息,data 为 { col, value }[] 数组

在编写自定义逻辑时,最常见的判据就是 clicked?.column?.display_name(按列名区分行为)或 clicked?.value(按单元格值区分行为)。

五、三种返回形态:默认菜单、追加操作、立即执行

根据 docs/embedding/chart.md 的说明,mapQuestionClickActions 允许三种行为:

  1. 打开默认菜单:原样返回 clickActions,保持 Metabase 默认行为;
  2. 追加自定义操作:返回 [...clickActions, customAction],在默认菜单基础上增加自定义项;
  3. 立即执行:返回 { onClick: () => void },点击后不展示菜单,直接触发回调。

需要注意的是,该功能目前仅适用于模块化嵌入 SDK(Modular Embedding SDK)。

六、完整实战示例

仓库提供的可运行示例位于 docs/embedding/sdk/snippets/questions/interactive-question-click-actions.tsx,它演示了全部三种形态的组合使用:

import {
  defineMetabaseAuthConfig,
  InteractiveQuestion,
  MetabaseProvider,
} from "@metabase/embedding-sdk-react";

const authConfig = defineMetabaseAuthConfig({
  metabaseInstanceUrl: "http://localhost:3000",
});

const Example = () => {
  return (
    <MetabaseProvider
      authConfig={authConfig}
      pluginsConfig={{
        mapQuestionClickActions: (clickActions, clicked) => {
          if (clicked?.column?.display_name === "Last Name") {
            // 在 "Last Name" 列上追加一个自定义菜单项
            return [
              ...clickActions,
              {
                buttonType: "horizontal",
                name: "custom",
                title: "This is the Last Name column",
                onClick: () => alert("You clicked the Last Name column!"),
              },
            ];
          }

          if (clicked?.column?.display_name === "Plan") {
            // 在 "Plan" 列上不弹菜单,立即执行
            return {
              onClick: () => alert("You clicked the Plan column!"),
            };
          }
          // 其他列保持 Metabase 默认点击菜单
          return clickActions;
        },
      }}
    >
      <InteractiveQuestion questionId={1} />
    </MetabaseProvider>
  );
};

这个示例展示了 MetabaseClickAction 的实际形态:自定义操作项 { buttonType, name, title, onClick } 中,name 是强制字段,title 决定菜单中展示的文案,buttonType 控制按钮的布局形态,onClick 承载实际业务逻辑。以 name 为锚点、其余字段自由扩展的结构在这里体现得淋漓尽致。

七、源码级印证:插件类型在 SDK 中的真实定义

在 frontend/src/metabase/embedding-sdk/types/plugins.ts 中,插件的真实定义为:

export type MetabaseClickActionPluginsConfig = (
  clickActions: ClickAction[],
  clickedDataPoint: MetabaseDataPointObject,
) => ClickAction[] | { onClick: () => void };

可以确认:

  • 源码中的 MetabaseClickActionPluginsConfig 与文档 snippet 的签名完全一致,仅将对外文档化的 MetabaseClickAction 映射为内部的 ClickAction;
  • 该插件被挂在全局插件配置 MetabasePluginsConfig 的 mapQuestionClickActions 字段下(同文件 plugins.ts),与仪表盘卡片菜单 dashboard.dashboardCardMenu 并列,属于 SDK 全局插件体系的一部分。

在 SDK 内部,点击菜单由 frontend/src/metabase/querying/click-actions 模块驱动,mapQuestionClickActions 会在点击事件触发时被调用,从而在默认行为之前插入你的定制逻辑。

八、全局配置与组件级配置

mapQuestionClickActions 可以在两个层面注入:

  • 全局层面:通过 MetabaseProvider 的 pluginsConfig.mapQuestionClickActions 传入(如上面的示例),对所有嵌入组件生效;
  • 组件层面:通过 InteractiveQuestion 等组件的插件配置单独传入,仅对当前组件生效。

官方文档(docs/embedding/sdk/plugins.md)明确说明其"可以全局使用,也可以在组件级别使用",并进一步指向图表定制章节 docs/embedding/chart.md 获取更多示例。两种层级叠加时,组件级配置优先于全局配置,这为"全局兜底 + 局部特化"的嵌入场景提供了灵活的组合空间。

总结

MetabaseClickAction 以 { name: string } & Record<string, any> 这样极简而开放的类型,成为 Metabase 嵌入 SDK 点击行为定制体系的基石:name 保证每个操作项可被稳定标识,Record<string, any> 则允许你在不破坏类型结构的前提下自由扩展业务字段。配合 mapQuestionClickActions 插件,你可以对交互式图表与仪表盘的点击行为进行三种粒度的定制——保留默认菜单、追加自定义操作项、或完全绕过菜单立即执行,从而把嵌入应用的数据交互体验完全握在自己手中。

登录后查看全文
metabase