CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-grafana--data

Core data manipulation and type system library for Grafana, providing DataFrame operations, field processing, transformations, and visualization utilities.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

event-system.mddocs/

Event System

Type-safe event bus system for application-wide communication with built-in events, custom event support, and React integration for decoupled component communication.

Capabilities

Event Bus Service

Core event bus implementation for publishing and subscribing to events.

/**
 * Event bus service implementation
 */
class EventBusSrv implements EventBus {
  /**
   * Publishes an event to all subscribers
   * @param event - Event instance to publish
   */
  publish<T extends BusEvent>(event: T): void;
  
  /**
   * Subscribes to events of a specific type
   * @param typeInfo - Event type information
   * @param handler - Event handler function
   * @returns Unsubscribable for cleanup
   */
  subscribe<T extends BusEvent>(
    typeInfo: BusEventType<T>, 
    handler: BusEventHandler<T>
  ): Unsubscribable;
  
  /**
   * Gets all subscribers for event type (for debugging)
   * @param typeInfo - Event type information
   * @returns Array of event handlers
   */
  getEventCount<T extends BusEvent>(typeInfo: BusEventType<T>): number;
  
  /**
   * Removes all subscribers
   */
  removeAllListeners(): void;
}

Usage Examples:

import { EventBusSrv, DataHoverEvent } from "@grafana/data";

// Create event bus instance
const eventBus = new EventBusSrv();

// Subscribe to events
const unsubscribe = eventBus.subscribe(DataHoverEvent, (event) => {
  console.log('Data hover:', event.payload);
});

// Publish events
eventBus.publish(new DataHoverEvent({
  point: { x: 100, y: 200 },
  data: someDataFrame
}));

// Cleanup subscription
unsubscribe.unsubscribe();

Event Factory

Factory function for creating custom event types.

/**
 * Creates event type factory for custom events
 * @param name - Event name identifier
 * @returns Event type factory function
 */
function eventFactory<TPayload = undefined>(name: string): BusEventType<BusEventWithPayload<TPayload>>;

Usage Examples:

import { eventFactory } from "@grafana/data";

// Create custom event type
interface UserLoginPayload {
  userId: string;
  timestamp: number;
}

const UserLoginEvent = eventFactory<UserLoginPayload>('user-login');

// Use custom event
eventBus.subscribe(UserLoginEvent, (event) => {
  console.log(`User ${event.payload.userId} logged in at ${event.payload.timestamp}`);
});

eventBus.publish(new UserLoginEvent({
  userId: 'user123',
  timestamp: Date.now()
}));

Base Event Classes

Foundation classes for creating events with and without payloads.

/**
 * Base class for events without payload
 */
class BusEventBase implements BusEvent {
  /** Event type information */
  readonly type: string;
  /** Event origin information */
  readonly origin?: any;
  
  constructor(origin?: any);
}

/**
 * Base class for events with payload
 */
class BusEventWithPayload<T> extends BusEventBase {
  /** Event payload data */
  readonly payload: T;
  
  constructor(payload: T, origin?: any);
}

Built-in Events

Pre-defined events for common Grafana operations.

/**
 * Data hover event for chart interactions
 */
class DataHoverEvent extends BusEventWithPayload<DataHoverPayload> {
  static type = 'data-hover';
}

/**
 * Data hover clear event
 */
class DataHoverClearEvent extends BusEventBase {
  static type = 'data-hover-clear';
}

/**
 * Data selection event for chart interactions
 */
class DataSelectEvent extends BusEventWithPayload<any> {
  static type = 'data-select';
}

/**
 * Annotation change event
 */
class AnnotationChangeEvent extends BusEventWithPayload<any> {
  static type = 'annotation-changed';
}

/**
 * Dashboard loaded event
 */
class DashboardLoadedEvent extends BusEventWithPayload<DashboardLoadedEventPayload> {
  static type = 'dashboard-loaded';
}

/**
 * Data source update success event
 */
class DataSourceUpdatedSuccessfully extends BusEventWithPayload<any> {
  static type = 'ds-updated-successfully';
}

/**
 * Data source test success event
 */
class DataSourceTestSucceeded extends BusEventWithPayload<any> {
  static type = 'ds-test-succeeded';
}

/**
 * Data source test failure event
 */
class DataSourceTestFailed extends BusEventWithPayload<any> {
  static type = 'ds-test-failed';
}

/**
 * Panel attention event
 */
class SetPanelAttentionEvent extends BusEventWithPayload<any> {
  static type = 'set-panel-attention';
}

Type Definitions

/**
 * Base event interface
 */
interface BusEvent {
  /** Event type identifier */
  readonly type: string;
  /** Event origin information */
  readonly origin?: any;
}

/**
 * Event type information
 */
interface BusEventType<T extends BusEvent> {
  /** Event type identifier */
  readonly type: string;
  /** Event constructor */
  new (...args: any[]): T;
}

/**
 * Event handler function type
 */
type BusEventHandler<T extends BusEvent> = (event: T) => void;

/**
 * Event filtering options
 */
interface EventFilterOptions {
  /** Only handle events from specific origin */
  onlyLocal?: boolean;
}

/**
 * Event bus interface
 */
interface EventBus {
  /** Publish event */
  publish<T extends BusEvent>(event: T): void;
  /** Subscribe to events */
  subscribe<T extends BusEvent>(typeInfo: BusEventType<T>, handler: BusEventHandler<T>): Unsubscribable;
  /** Get subscriber count */
  getEventCount?<T extends BusEvent>(typeInfo: BusEventType<T>): number;
  /** Remove all listeners */
  removeAllListeners?(): void;
}

/**
 * Extended event bus with additional features
 */
interface EventBusExtended extends EventBus {
  /** Publish with options */
  publishWithOptions<T extends BusEvent>(event: T, options?: EventFilterOptions): void;
  /** Subscribe with filtering */
  subscribeWithFilter<T extends BusEvent>(
    typeInfo: BusEventType<T>, 
    handler: BusEventHandler<T>,
    filter?: EventFilterOptions
  ): Unsubscribable;
}

/**
 * Application event type
 */
type AppEvent<T = any> = BusEventType<BusEventWithPayload<T>>;

/**
 * Legacy emitter interface for backward compatibility
 */
interface LegacyEmitter {
  emit(name: string, ...args: any[]): void;
  on(name: string, handler: LegacyEventHandler<any>): void;
  off(name: string, handler?: LegacyEventHandler<any>): void;
}

/**
 * Legacy event handler type
 */
type LegacyEventHandler<T> = (payload?: T, ...args: any[]) => void;

/**
 * Unsubscribable interface for cleanup
 */
interface Unsubscribable {
  unsubscribe(): void;
}

Event Payload Types

/**
 * Data hover event payload
 */
interface DataHoverPayload {
  /** Hover point coordinates */
  point: {
    x: number;
    y: number;
  };
  /** Related data frame */
  data?: DataFrame;
  /** Row index */
  rowIndex?: number;
  /** Field index */
  columnIndex?: number;
}

/**
 * Dashboard loaded event payload
 */
interface DashboardLoadedEventPayload {
  /** Dashboard UID */
  dashboardId: string;
  /** Dashboard title */
  title: string;
  /** Loading time in milliseconds */
  loadTime?: number;
  /** Dashboard metadata */
  meta?: any;
}

Event Usage Patterns

Publisher-Subscriber Pattern

import { EventBusSrv, eventFactory } from "@grafana/data";

// Create global event bus
const globalEventBus = new EventBusSrv();

// Define custom event
interface NotificationPayload {
  message: string;
  type: 'success' | 'error' | 'warning' | 'info';
}

const NotificationEvent = eventFactory<NotificationPayload>('notification');

// Publisher component
class NotificationService {
  constructor(private eventBus: EventBus) {}
  
  showSuccess(message: string) {
    this.eventBus.publish(new NotificationEvent({
      message,
      type: 'success'
    }));
  }
  
  showError(message: string) {
    this.eventBus.publish(new NotificationEvent({
      message,
      type: 'error'
    }));
  }
}

// Subscriber component
class NotificationDisplay {
  constructor(private eventBus: EventBus) {
    this.eventBus.subscribe(NotificationEvent, this.handleNotification);
  }
  
  private handleNotification = (event: BusEventWithPayload<NotificationPayload>) => {
    const { message, type } = event.payload;
    this.displayNotification(message, type);
  };
  
  private displayNotification(message: string, type: string) {
    // Display logic here
    console.log(`[${type.toUpperCase()}] ${message}`);
  }
}

React Integration

import React, { useEffect, useState } from 'react';
import { EventBus, DataHoverEvent } from "@grafana/data";

interface Props {
  eventBus: EventBus;
}

function DataHoverIndicator({ eventBus }: Props) {
  const [hoverData, setHoverData] = useState<DataHoverPayload | null>(null);
  
  useEffect(() => {
    const subscription = eventBus.subscribe(DataHoverEvent, (event) => {
      setHoverData(event.payload);
    });
    
    return () => subscription.unsubscribe();
  }, [eventBus]);
  
  if (!hoverData) {
    return null;
  }
  
  return (
    <div>
      Hovering at: ({hoverData.point.x}, {hoverData.point.y})
    </div>
  );
}

Error Handling

import { EventBusSrv, eventFactory } from "@grafana/data";

interface ErrorPayload {
  error: Error;
  context?: string;
  recoverable?: boolean;
}

const ErrorEvent = eventFactory<ErrorPayload>('error');

class ErrorHandler {
  constructor(private eventBus: EventBus) {
    this.eventBus.subscribe(ErrorEvent, this.handleError);
  }
  
  private handleError = (event: BusEventWithPayload<ErrorPayload>) => {
    const { error, context, recoverable } = event.payload;
    
    console.error(`Error in ${context || 'unknown context'}:`, error);
    
    if (!recoverable) {
      // Handle critical errors
      this.handleCriticalError(error);
    } else {
      // Handle recoverable errors
      this.handleRecoverableError(error);
    }
  };
  
  private handleCriticalError(error: Error) {
    // Critical error handling logic
  }
  
  private handleRecoverableError(error: Error) {
    // Recoverable error handling logic
  }
}

// Usage
const errorHandler = new ErrorHandler(globalEventBus);

// Publish error
try {
  // Some operation
} catch (error) {
  globalEventBus.publish(new ErrorEvent({
    error,
    context: 'data processing',
    recoverable: true
  }));
}

docs

data-transformations.md

dataframe-operations.md

datetime-operations.md

event-system.md

field-processing.md

index.md

plugin-system.md

theme-system.md

utility-functions.md

value-formatting.md

tile.json