How to subscribe to Grafana application events

If you’re building a panel plugin, Grafana already provides the data you need to configure and render your panel. If not, you can retrieve the information you need from any of the runtime services, like BackendSrv and TemplateSrv. In some cases though, you want your plugin to react to changes outside of your plugin. For example, when the user hovers their cursor over data in another panel. In this post, you’ll learn how to make your plugin react to events in Grafana.

Note: If you’ve previously built plugins using Angular, note that you don’t need to subscribe to render events to update your visualization in React. React components automatically re-renders whenever any of its dependencies has changed.

Grafana uses an event bus to publish application events to notify different parts of Grafana when the user performs an action. Your plugin can react to these actions by subscribing to one or more events.

Events are identified by a unique string, and can have an optional payload. In the following example the ZoomOutEvent is identified by the zoom-out string and carries a number as a payload.

class ZoomOutEvent extends BusEventWithPayload<number> {
  static type = 'zoom-out';
}

Here are a few other events you can subscribe to:

You can access the event bus available from the panel props, and subscribe to events of a certain type using the getStream() method. The callback passed to the subscribe method will be called for every new event.

import React, { useEffect } from 'react';
import { RefreshEvent } from '@grafana/runtime';

// ...

interface Props extends PanelProps<MyOptions> {}

export const MyPanel: React.FC<Props> = ({ eventBus }) => {
  useEffect(() => {
    const subscriber = eventBus.getStream(RefreshEvent).subscribe(event => {
      console.log(`Received event: ${event.type}`);
    })

    return () => {
      subscriber.unsubscribe();
    }
  }, [eventBus]);

  return <div>Event bus example</div>;
}

Important: Remember to call unsubscribe() your subscriber to avoid memory leaks.

Note that while many event types are available but not yet exported, such as the PanelEditEnteredEvent, you can still subscribe to them by re-implementing the event type yourself:

class MyPanelEditEnteredEvent extends BusEventWithPayload<number> {
  static type = 'panel-edit-started';
}

While there’s no official documentation of the supported events, you can figure out the available events by searching for static type = '.*'; in the Grafana repository.

We’ll be improving the event bus and adding more events in the future. Let me know how you’re using the event bus, and any events you think would be useful to your plugin!

2 Likes