Grafana Scenes

作者 grafana1ccacf29049fApache-2.0279 个星标收录于 2026年10月8日更新于 2026年10月8日仓库今天更新

Build Grafana plugin pages using the @grafana/scenes framework. Use when creating new scene pages, adding panels/visualizations, setting up drilldown navigation, defining variables, configuring query runners, building table/timeseries/stat panels, or extending SceneObjectBase for custom scene objects. Triggers on any work involving SceneApp, SceneAppPage, EmbeddedScene, SceneQueryRunner, SceneDataTransformer, PanelBuilders, SceneFlexLayout, QueryVariable, or drilldown/tab configuration in Grafana plugins.

AI 生成的概览

使用 @grafana/scenes 框架构建 Grafana 插件页面,涵盖场景、面板、变量与下钻导航。

功能
该技能提供使用 @grafana/scenes 框架构建 Grafana 插件页面的指导和代码模式。它说明如何组合 SceneApp、SceneAppPage、EmbeddedScene 等场景树,添加面板与可视化,定义查询运行器和数据转换器,设置变量,并配置下钻导航与标签页。它还介绍如何扩展 SceneObjectBase 以创建自定义场景对象,并列出常见陷阱。
适用场景
适用于创建新的 Grafana 场景页面,或为 Grafana 插件添加面板、可视化、变量、查询运行器或下钻导航时。也适用于扩展 SceneObjectBase 以创建自定义场景对象,或使用 SceneApp、SceneAppPage、EmbeddedScene、PanelBuilders 等相关场景 API 的场景。
运行要求
需要一个使用 @grafana/scenes 包并具备 TypeScript/React 工具链的 Grafana 插件项目。该技能不附带脚本,仅包含说明和代码示例。

@grafana/scenes Framework

Build reactive, data-driven Grafana plugin pages with declarative scene objects.

Core Concepts

Scenes composes a tree of objects: SceneApp → SceneAppPage → EmbeddedScene → layouts → panels. Each node can own data ($data), variables ($variables), time ranges ($timeRange), and behaviors ($behaviors) that propagate down the tree.

Quick Start: New Scene Page

1. Create the scene file

typescript
// src/components/scenes/MyFeature/scene.tsximport {  EmbeddedScene, SceneFlexLayout, SceneFlexItem,  SceneQueryRunner, SceneVariableSet, QueryVariable,  PanelBuilders, VariableValueSelectors, SceneControlsSpacer,} from '@grafana/scenes';
export function getMyFeatureScene(params: { datasource: DataSourceRef }) {  const queryRunner = new SceneQueryRunner({    datasource: params.datasource,    queries: [{ refId: 'A', expr: 'up{cluster=~"$cluster"}', instant: true, format: 'table' }],  });
  const panel = PanelBuilders.table()    .setData(queryRunner)    .setTitle('My Table')    .build();
  return new EmbeddedScene({    $variables: new SceneVariableSet({      variables: [        new QueryVariable({          name: 'cluster',          query: 'label_values(up, cluster)',          datasource: params.datasource,          isMulti: true, includeAll: true, defaultToAll: true,        }),      ],    }),    controls: [new VariableValueSelectors({}), new SceneControlsSpacer()],    body: new SceneFlexLayout({      direction: 'column',      children: [new SceneFlexItem({ body: panel })],    }),  });}

2. Create the page

typescript
// src/components/scenes/MyFeature/MyFeature.tsximport { SceneAppPage, SceneTimeRange } from '@grafana/scenes';
export function getMyFeaturePage(params) {  return new SceneAppPage({    title: 'My Feature',    url: '/a/my-plugin-id/my-feature',    routePath: 'my-feature/*',    $timeRange: new SceneTimeRange({ from: 'now-1h', to: 'now' }),    getScene: () => getMyFeatureScene(params),    drilldowns: [],  });}

3. Register in SceneApp

Add the page to the SceneApp pages array in the root scene file.

Key Patterns

Drilldowns (click-through navigation)

typescript
drilldowns: [{  routePath: ':cluster/*',  getPage: (match, parent) => new SceneAppPage({    title: decodeURIComponent(match.params.cluster),    url: `${parent.state.url}/${match.params.cluster}`,    routePath: `${match.params.cluster}/*`,    getScene: () => detailScene(decodeURIComponent(match.params.cluster)),  }),}]

Tabs (sub-pages within a detail view)

Pass tabs: [SceneAppPage, ...] instead of getScene on a SceneAppPage. Each tab is itself a SceneAppPage with its own scene.

Query with transformations

Wrap a SceneQueryRunner in SceneDataTransformer to apply Grafana transforms or custom RxJS operators:

typescript
new SceneDataTransformer({  $data: queryRunner,  transformations: [    { id: 'organize', options: { renameByName: { 'Value #A': 'CPU' } } },    (ctx) => (source) => source.pipe(map((frames) => /* custom transform */)),  ],})

Custom scene object

Extend SceneObjectBase with a static Component for custom interactive UI:

typescript
class MyWidget extends SceneObjectBase<MyWidgetState> {  static Component = ({ model }: SceneComponentProps<MyWidget>) => {    const state = model.useState();    return <div>{state.value}</div>;  };}

Table column overrides

Build ConfigOverrideRule objects for drill-down links, filtering, units, widths, custom cells.

Panel types

PanelBuilders.table(), .timeseries(), .stat(), .gauge(), .barchart() — chain .setData(), .setTitle(), .setUnit(), .setOption(), .setOverrides(), then .build().

Common Pitfalls

  • Always use routePath: 'path/*' (with wildcard) on pages that have drilldowns or tabs
  • encodeURIComponent/decodeURIComponent URL params — K8s names can contain /
  • Variables referenced in queries as $varName must exist in an ancestor SceneVariableSet
  • getScene is called lazily; don't create side effects in the factory
  • For instant queries, set both instant: true and format: 'table'

Resources

来源与署名

来源:grafana/skills位于skills/grafana-plugins/grafana-scenes提交1ccacf2

许可证: Apache-2.0

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架

更多来自 grafana/skills 的技能

React 19 Plugin Migration

grafana

指导将 Grafana 插件迁移至 React 19 兼容,按顺序完成构建、依赖与源码修改步骤。

Software Development279今天更新

Plugin Bundle Size

grafana

指导使用 React.lazy、Suspense 和 webpack 代码分割来优化 Grafana 应用插件包体积。

Software Development279今天更新

Check Npm

grafana

对 JS/TS 仓库的 npm、yarn 或 pnpm 配置进行只读供应链加固审计。

Security279今天更新

Mimir

grafana

指导搭建和运维 Grafana Mimir,用于可扩展、多租户、长期的 Prometheus 与 OTLP 指标存储。

DevOps & Cloud279今天更新

K6 Trend Analysis

grafana

Analyze Grafana Cloud k6 test run trends over time. Detects slow metric drift (e.g., P95 latency creeping up while still passing thresholds), computes headroom to thresholds, flags anomalies, and recommends threshold tightening. Use when the user asks about test performance trends, wants to know if metrics are degrading, asks whether thresholds should be tightened, or wants a health check across recent runs for a specific test. Trigger on phrases like "how is my test trending", "is P95 getting worse", "check for performance regression", "should I tighten thresholds", "are my tests degrading", "show me trends for test X", "analyze my k6 test runs", or "is my test getting slower". Also trigger when a user asks to check all tests in a project -- run this skill once per test and synthesize.

待分类279今天更新

K6 Test Maintenance

grafana

维护和改进现有 k6 负载测试脚本:收紧阈值、版本迁移、重构以及最佳实践审计。

Software Development279今天更新