Metabase Embedding SDK `InteractiveQuestion` 组件 API 全解析:从默认布局到自定义组合
2026/9/10 13:00:54 网站建设 项目流程

Metabase Embedding SDKInteractiveQuestion组件 API 全解析:从默认布局到自定义组合

【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase

导读

InteractiveQuestion是 Metabase Embedding SDK 中最具开放性的嵌入式组件:它不仅渲染一个可交互的问题(Question),更将问题编辑器拆解为 20+ 个可独立使用的子组件(过滤、汇总、分组、图表类型、可视化、保存等),让你在 React 应用中完全掌控"提问—编辑—可视化—保存"的完整链路。本文以官方 API 文档 InteractiveQuestionComponents.md 为骨架,结合仓库源码逐一对齐每个子组件的签名、参数与行为,并给出自定义布局与默认布局的实践路径。

一、InteractiveQuestion是什么:一个组件,一套命名空间

InteractiveQuestion在 SDK 中同时承担两种角色:

  • 一个函数组件:接收 InteractiveQuestionProps,渲染一个完整可用的交互式问题(含工具栏、可视化与编辑能力)。
  • 一组命名空间子组件:通过InteractiveQuestion.FilterInteractiveQuestion.Editor这类点语法访问,用于在自定义布局中按需组装 UI。

从源码看,这个双重身份是显式构造出来的。InteractiveQuestion.tsx 中,InteractiveQuestion通过Object.assign将 20+ 个子组件挂载到函数组件本体上,同时挂载schema(用于 Storybook 等场景的 schema 描述),再包一层withPublicComponentWrappersupportsGuestEmbed: false,即该组件不面向 Guest 匿名嵌入)。组件内部只是把card/query反序列化后透传给底层 SdkQuestion.tsx,真正的问题加载、执行与上下文管理由SdkQuestionProvider提供。

import { InteractiveQuestion } from "@metabase/embedding-sdk-react"; // 默认布局:开箱即用 <InteractiveQuestion questionId={42} />; // 自定义布局:用命名空间子组件自由组合 <InteractiveQuestion questionId={42}> <InteractiveQuestion.Title /> <InteractiveQuestion.Filter /> <InteractiveQuestion.Summarize /> <InteractiveQuestion.QuestionVisualization /> </InteractiveQuestion>;

注意:源码中SdkQuestionwithDownloadswithAlerts默认值均为false(见 SdkQuestion.tsx),需要下载与预警能力时请显式开启。

二、编辑与保存类组件:Editor、EditorButton、SaveButton、SaveQuestionForm

这一组组件覆盖"修改问题定义"与"落库保存"两个环节,是自定义分析工作流的核心。

Editor()(原Notebook(),已弃用)

Editor: (props: InteractiveQuestionEditorProps) => Element | null;

高级查询编辑器,提供对问题配置的完整访问,包括:

  • 过滤(filtering)
  • 聚合(aggregation)
  • 自定义表达式(custom expressions)
  • 表连接(joins)

Notebook()NotebookButton()已被标记弃用,官方明确要求改用InteractiveQuestion.Editor/EditorButton。在源码 SdkQuestion.tsx 中,NotebookEditor指向同一个Editor实现,NotebookButtonEditorButton同样同源,保证向后兼容。

EditorButton()

EditorButton: (props: InteractiveQuestionEditorButtonProps) => Element | null;

用于显示/隐藏Editor的切换按钮。官方文档特别强调了一个关键约束:

在自定义布局中,EditorButton必须提供 InteractiveQuestionEditorButtonProps.onClick 处理器,否则点击按钮不会有任何效果。

这是因为 SDK 不会替你在自定义布局里自动接线:onClick需要由宿主应用自己实现(通常是切换编辑器显隐的 state),这与默认布局中 SDK 内部自动管理编辑器开关的行为不同。

SaveButton()

SaveButton: (props?: InteractiveQuestionSaveButtonProps) => Element;

保存问题修改的按钮,仅当问题存在未保存的修改时处于可用状态。文档同时给出一个注意事项:在当前版本的自定义布局中,SaveButton同样必须提供onClick处理器,否则点击无效。默认布局中 SDK 已接线,无需额外处理。

SaveQuestionForm()

SaveQuestionForm: (props: InteractiveQuestionSaveQuestionFormProps) => Element | null;

保存问题的表单,包含标题(title)与描述(description)。保存时的行为(文档明确列出的三条):

  • 对已存在的问题:调用 SdkQuestionProps.onSave
  • 两类回调(新问题与已有问题)都会收到更新后的问题对象
  • 表单可通过 InteractiveQuestionSaveQuestionFormProps.onCancel 取消

配合 InteractiveQuestionProps 中的isSaveEnabled(是否显示保存按钮)、onBeforeSave(保存前回调,可做校验/拦截)、onSave(保存成功回调),可以完整接管保存链路。

三、数据探索类组件:Filter、Summarize、Breakout 与下拉变体

这组组件负责"从数据中提炼信息"的三种基本操作:过滤、汇总、分组。

Filter()FilterDropdown()

Filter: (props: InteractiveQuestionFilterProps) => Element; FilterDropdown: (props: InteractiveQuestionFilterDropdownProps) => Element | null;

Filter渲染一组交互式过滤徽章(badges),支持添加、编辑、移除过滤器;当前过滤器以徽章形式展示,并提供"Add another filter"(添加另一个过滤器)入口。FilterDropdownFilter的下拉按钮形态,适合工具栏空间有限的布局。

Summarize()SummarizeDropdown()

Summarize: () => Element; SummarizeDropdown: (props: InteractiveQuestionSummarizeDropdownProps) => Element | null;

Summarize提供添加与管理数据汇总(如计数 count、求和 sum、平均值 average)的界面,同样以一组徽章呈现,文档说明其"使用问题上下文(question context)实现汇总功能"。SummarizeDropdown是它的下拉按钮形态。

Breakout()BreakoutDropdown()

Breakout: () => Element | null; BreakoutDropdown: (props: InteractiveQuestionBreakoutDropdownProps) => Element | null;

Breakout是管理数据分组(groupings / breakouts)的徽章组,例如按"月份"或"地区"分组后再看指标。BreakoutDropdown是其下拉按钮形态。三者共享问题上下文,因此对某个组件的操作会即时反映到其余组件与可视化上。

四、可视化类组件:QuestionVisualization、ChartTypeDropdown、ChartTypeSelector、QuestionSettings

这一组决定了"数据最终以什么形态呈现"。

QuestionVisualization()

QuestionVisualization: (props: { className?: string; style?: CSSProperties; } & { height?: Height<string | number>; width?: Width<string | number>; } & {}) => Element;

主可视化组件,将问题结果渲染为图表、表格或其他可视化类型。参数分两层:

  • className/style:挂到根元素上的自定义类名与样式对象
  • height/width:CSS 尺寸值(数字或字符串),用于控制组件宽高

ChartTypeDropdown()ChartTypeSelector()

ChartTypeDropdown: (props: InteractiveQuestionChartTypeDropdownProps) => Element; ChartTypeSelector: (props: StackProps) => Element;
  • ChartTypeDropdown:选择可视化类型的下拉框(柱状图 bar、折线图 line、表格 table 等),文档明确它会根据当前数据自动更新为推荐的可视化类型
  • ChartTypeSelector:更详细的图表类型选择界面,同样带推荐选项。其props类型为 Mantine 的StackProps(Mantine v7 的 Stack 布局属性)。

QuestionSettings()QuestionSettingsDropdown()

QuestionSettings: (props: StackProps) => Element | null; QuestionSettingsDropdown: (props?: InteractiveQuestionQuestionSettingsDropdownProps) => Element;

QuestionSettings是配置可视化选项的设置面板,覆盖坐标轴(axes)、颜色(colors)、格式(formatting)等;文档同样说明其"使用问题上下文"。QuestionSettingsDropdown是包含QuestionSettings的下拉按钮,注意它的props是可选参数。

ResetButton()

ResetButton: (props?: ButtonProps) => Element | null;

重置问题修改的按钮,仅在存在未保存的修改时出现(与SaveButton的可用态逻辑互补)。props类型为 ButtonProps,可选。

五、结果输出与下载类组件:DownloadWidget、DownloadWidgetDropdown、VisualizationButton

DownloadWidget()DownloadWidgetDropdown()

DownloadWidget: (props: StackProps) => Element | null; DownloadWidgetDropdown: (props: PopoverProps) => Element | null;

DownloadWidget提供数据下载 UI,支持格式依可视化类型而定:CSVXLSXJSON以及PNG(图片导出仅对部分图表有效)。DownloadWidgetDropdown是一个按钮,点击后弹出的 Popover 中展示DownloadWidget;其props类型为 Mantine 的PopoverProps

VisualizationButton()

VisualizationButton: () => Element | null;

触发"可视化"动作的按钮——即运行当前问题并渲染结果。在InteractiveQuestionProps.onRun的文档说明中提到:当问题被更新(包括用户点击编辑器中的 Visualize 按钮)时会触发onRun回调,与这里的VisualizationButton行为对应。

六、信息与导航类组件:Title、BackButton、NavigationBackButton、AlertsButton、SqlParametersList

Title()

Title: (props: { className?: string; style?: CSSProperties }) => Element | undefined;

根据问题状态显示标题:

  • 问题已保存:显示问题的显示名称(display name)
  • 临时问题(ad-hoc,非原生 SQL 查询):显示自动生成的描述文本

classNamestyle均为可选,用于定制根元素样式。

BackButton()(已弃用)与NavigationBackButton()

BackButton: (props: InteractiveQuestionBackButtonProps) => Element | null; // @deprecated NavigationBackButton: (props: { className?: string; style?: CSSProperties }) => ReactNode;
  • BackButton是返回上一视图的导航按钮,仅在 InteractiveDashboardProps.renderDrillThroughQuestion 渲染的钻取问题(drill-through question)中可见。它已被标记弃用,官方建议改用NavigationBackButton
  • NavigationBackButton是钻取与内部导航后的返回按钮;当没有可返回的历史时会渲染null。源码中该按钮指向SdkInternalNavigationBackButton(见 InteractiveQuestion.tsx),与 SDK 内部的导航状态机集成。

AlertsButton()SqlParametersList()

AlertsButton: () => Element; SqlParametersList: () => Element | null;
  • AlertsButton:开启/管理问题预警(alerts)的入口,需配合InteractiveQuestionProps.withAlerts使用。
  • SqlParametersList:SQL 问题的参数列表,用于展示与编辑原生查询中的变量参数。该组件与InteractiveQuestionProps.initialSqlParameters/sqlParameters/onSqlParametersChange一组受控参数配合使用:sqlParameters是受控值(每次渲染都会替换问题参数值),onSqlParametersChange的 payload 通过source区分初始状态(initial-state)、用户手动修改(manual-change)与自动更新(auto-change)。

七、组件 API 速查表

组件签名要点关键行为/约束
BackButton(弃用)(props) => Element \| null钻取问题中返回上一视图;改用NavigationBackButton
NavigationBackButton(props) => ReactNode钻取/内部导航后返回;无历史时渲染null
Filter(props) => Element过滤徽章组,可增删改过滤器
FilterDropdown(props) => Element \| nullFilter的下拉按钮形态
Summarize() => Element汇总徽章组(计数/求和/平均等)
SummarizeDropdown(props) => Element \| nullSummarize的下拉按钮形态
Breakout() => Element \| null分组徽章组
BreakoutDropdown(props) => Element \| nullBreakout的下拉按钮形态
Editor(原Notebook,弃用)(props) => Element \| null高级查询编辑器:过滤/聚合/表达式/连接
EditorButton(原NotebookButton,弃用)(props) => Element \| null自定义布局中必须传onClick
QuestionVisualization(props) => Element渲染结果图表/表格;支持className/style/height/width
VisualizationButton() => Element \| null触发问题运行与可视化
ChartTypeDropdown(props) => Element图表类型下拉;自动推荐
ChartTypeSelector(props: StackProps) => Element详细图表类型选择界面
QuestionSettings(props: StackProps) => Element \| null坐标轴/颜色/格式等可视化设置面板
QuestionSettingsDropdown(props?) => Element包含QuestionSettings的下拉按钮
ResetButton(props?) => Element \| null有未保存修改时才出现
SaveButton(props?) => Element有未保存修改才可用;自定义布局中必须传onClick
SaveQuestionForm(props) => Element \| null保存表单;触发onSave,支持onCancel
DownloadWidget(props: StackProps) => Element \| null下载CSV/XLSX/JSON/PNG
DownloadWidgetDropdown(props: PopoverProps) => Element \| nullDownloadWidget的下拉按钮
AlertsButton() => Element预警入口,需配合withAlerts
SqlParametersList() => Element \| nullSQL 问题参数列表

八、默认布局与自定义布局的取舍

从源码与文档可以提炼出两种使用模式(注意以下属于对官方文档与源码结构的归纳,具体取舍以你的产品场景为准):

  1. 默认布局(开箱即用):直接渲染<InteractiveQuestion questionId={...} />,SDK 会通过 SdkQuestionDefaultView.tsx 组装一套完整界面。此时部分行为是 SDK 自动接线的,例如EditorButton无需手动onClick
  2. 自定义布局(children 组合):通过命名空间子组件自行编排。此时需要特别注意文档标注的手动接线要求:EditorButtonSaveButton都必须提供onClick处理器;同时可配合InteractiveQuestionProps上的withChartTypeSelector(是否显示图表类型选择器与设置按钮,仅默认布局生效)、withEditorButton(是否显示编辑器按钮,仅默认布局生效)、withDownloads(是否允许下载结果)等开关微调行为。

对于需要把"问答式探索"能力嵌入自身产品的场景,官方相关文档(docs/embedding/sdk 目录)还提供了StaticQuestion(静态只读问题,见 StaticQuestionComponents.md)作为对照——InteractiveQuestion面向需要完整编辑能力的场景,而StaticQuestion面向仅展示结果的场景,二者对应不同的开放层级。

九、延伸阅读

  • InteractiveQuestionProps:questionIdcardqueryonSaveonRunsqlParameters等全部属性
  • InteractiveQuestion.md:InteractiveQuestion函数组件本身
  • InteractiveDashboardProps:renderDrillThroughQuestion(钻取问题渲染入口,BackButton的生效场景)
  • 组件实现:InteractiveQuestion.tsx、SdkQuestion.tsx、SdkQuestionDefaultView.tsx

【免费下载链接】metabaseThe easy-to-use open source Business Intelligence and Embedded Analytics tool that lets everyone work with data :bar_chart:项目地址: https://gitcode.com/GitHub_Trending/me/metabase

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询