Skip to content

Dashboard Implementation #6

Open
@caioricciuti

Description

@caioricciuti

GigAPI Dashboard

Architecture

  • State Management: React Context API
  • Persistence: IndexedDB for client-side storage
  • Visualizations: ECharts for charts and graphs
  • Layout: react-grid-layout for resizable/draggable panels

File Structure

src/
├── components/dashboard/
│   ├── DashboardGrid.tsx          # Main grid layout component
│   ├── DashboardHeader.tsx        # Dashboard controls and metadata
│   ├── DashboardPanel.tsx         # Individual panel wrapper
│   ├── panels/                    # Panel type implementations
│   │   ├── TimeSeriesPanel.tsx    # Line/area charts
│   │   ├── StatPanel.tsx          # Single value displays
│   │   ├── GaugePanel.tsx         # Circular gauge charts
│   │   ├── TablePanel.tsx         # Data tables
│   │   └── index.ts               # Panel registry
│   └── editors/                   # Configuration editors
│       ├── QueryEditor.tsx        # Monaco SQL editor
│       ├── DataMappingEditor.tsx  # Column mapping
│       └── VisualizationEditor.tsx # Chart settings
├── contexts/
│   └── DashboardContext.tsx       # Dashboard state management
├── lib/dashboard/
│   ├── storage.ts                 # IndexedDB operations
│   └── data-transformers.ts       # Data processing utilities
├── pages/
│   ├── DashboardView.tsx          # Dashboard view page
│   ├── DashboardList.tsx          # Dashboard listing
│   └── PanelEdit.tsx              # Panel editing page
└── types/dashboard.types.ts       # TypeScript definitions

Data Flow

1. Dashboard Lifecycle

Dashboard Creation → Panel Addition → Query Configuration → Data Visualization → Export/Import

2. Data Processing Pipeline

SQL Query → GigaAPI Execution → NDJSON Response → Data Transformation → Chart Rendering

3. State Management Flow

User Action → Context Update → Storage Persistence → UI Re-render

Core Components

Dashboard System

DashboardContext

File: src/contexts/DashboardContext.tsx

Central state management for the entire dashboard system.

State Structure:

interface DashboardContextType {
  // Core State
  currentDashboard: Dashboard | null
  panels: Map<string, PanelConfig>
  panelData: Map<string, PanelData>
  isEditMode: boolean
  selectedPanelId: string | null
  
  // Operations
  createDashboard: (data: Omit<Dashboard, 'id' | 'metadata'>) => Promise<Dashboard>
  updateDashboard: (id: string, updates: Partial<Dashboard>) => Promise<void>
  loadDashboard: (id: string) => Promise<void>
  addPanel: (panelData: Omit<PanelConfig, 'id'>) => Promise<string>
  updatePanel: (id: string, updates: Partial<PanelConfig>) => Promise<void>
  deletePanel: (id: string) => Promise<void>
  refreshPanelData: (panelId: string) => Promise<void>
}

Dashboard Grid

File: src/components/dashboard/DashboardGrid.tsx

Responsive grid layout using react-grid-layout for drag-and-drop panel management.

Features:

  • Resizable and draggable panels
  • Multi-breakpoint responsive design
  • Edit mode with visual controls
  • Panel selection and actions

Panel System

File: src/components/dashboard/panels/

Modular panel architecture supporting multiple visualization types.

Supported Panel Types:

  • TimeSeries: Line charts with time-based data
  • Stat: Single value displays with trends and thresholds
  • Gauge: Circular gauge visualizations
  • Table: Sortable, searchable data tables
  • Bar: Bar charts for categorical data
  • Line: Line charts for continuous data
  • Area: Area charts with filled regions
  • Scatter: Scatter plots for correlation analysis

Data Schema

Dashboard Schema

interface Dashboard {
  id: string
  name: string
  description?: string
  timeRange: TimeRange
  refreshInterval: number // seconds
  layout: {
    panels: PanelLayout[]
    gridSettings: {
      columns: number
      rowHeight: number
      margin: [number, number]
    }
  }
  metadata: {
    createdAt: Date
    updatedAt: Date
    tags: string[]
  }
}

Panel Configuration Schema

interface PanelConfig {
  id: string
  type: PanelType
  title: string
  query: string
  dataMapping: DataMapping
  visualization: VisualizationConfig
  timeOverride?: TimeRange
}

interface DataMapping {
  valueColumn: string
  timeColumn?: string
  seriesColumn?: string
  displayColumns?: string[]
  labelColumns?: string[]
  minColumn?: string
  maxColumn?: string
}

interface VisualizationConfig {
  showLegend?: boolean
  xAxisLabel?: string
  yAxisLabel?: string
  colors?: string[]
  unit?: string
  decimals?: number
  min?: number
  max?: number
  threshold?: {
    value: number
    operator: 'gt' | 'lt' | 'eq'
    color: string
  }
  pageSize?: number
  sortColumn?: string
  sortDirection?: 'asc' | 'desc'
}

Data Processing Schema

interface PanelData {
  panelId: string
  data: NDJSONRecord[]
  lastUpdated: Date
  error?: string
}

interface NDJSONRecord {
  [key: string]: any
}

Storage System

IndexedDB Implementation

File: src/lib/dashboard/storage.ts

Database Structure:

  • Database Name: GigapiDashboards
  • Version: 1
  • Object Stores:
    • dashboards: Dashboard metadata and configuration
    • panels: Panel configurations with dashboard associations

Key Operations:

class DashboardStorage {
  // Dashboard Operations
  saveDashboard(dashboard: Dashboard): Promise<void>
  getDashboard(id: string): Promise<Dashboard | null>
  getAllDashboards(): Promise<DashboardListItem[]>
  deleteDashboard(id: string): Promise<void>
  
  // Panel Operations
  savePanel(panel: PanelConfig & { dashboardId: string }): Promise<void>
  getPanelsForDashboard(dashboardId: string): Promise<PanelConfig[]>
  deletePanel(panelId: string): Promise<void>
  
  // Import/Export
  exportDashboard(id: string): Promise<DashboardExport>
  importDashboard(data: DashboardExport): Promise<Dashboard>
}

Query System

SQL Query Processing

File: src/components/dashboard/editors/QueryEditor.tsx

Features:

  • Monaco Editor with SQL syntax highlighting
  • Auto-completion with GigaAPI-specific macros
  • $__timeFilter macro for automatic time filtering
  • Real-time query validation
  • Keyboard shortcuts (Ctrl+Enter to run, Ctrl+S to save)

Query Macros:

  • $__timeFilter: Automatically replaced with time range filter based on dashboard time settings

Data Transformation

File: src/lib/dashboard/data-transformers.ts

NDJSON Processing:

// Input: Raw NDJSON string from GigaAPI
// Output: Structured data for visualization

const processNDJSON = (rawJson: string): NDJSONRecord[] => {
  const records: NDJSONRecord[] = []
  const lines = rawJson.trim().split('\n')
  
  for (const line of lines) {
    if (line.trim()) {
      try {
        records.push(JSON.parse(line))
      } catch (error) {
        console.warn('Failed to parse NDJSON line:', line)
      }
    }
  }
  
  return records
}

User Interface

Dashboard View

Route: /dashboard/:id
File: src/pages/DashboardView.tsx

Layout:

  • Header: Dashboard title, time range controls, edit mode toggle
  • Grid: Resizable panel grid (full-width after removing sidebar)
  • Actions: Add panel, save dashboard, refresh data

User Actions:

  • View Mode: Read-only dashboard viewing
  • Edit Mode: Drag/resize panels, add/delete panels
  • Double-click Panel: Navigate to panel edit page

Panel Edit Page

Route: /dashboard/:dashboardId/panel/:panelId/edit
File: src/pages/PanelEdit.tsx

Layout:

  • Top (60%): Live visualization preview
  • Bottom (40%): Monaco SQL query editor
  • Right Sidebar (25%): Configuration panel

Configuration Sections:

  1. Basic Settings: Panel title and type selection
  2. Data Mapping: Column mapping with intelligent suggestions
  3. Visualization Settings: Chart-specific configuration options

Features:

  • Real-time preview of changes
  • Auto-save functionality
  • Query execution with immediate results
  • Back navigation to dashboard

API Integration

GigaAPI Connection

File: src/contexts/QueryContext.tsx

Query Execution Flow:

  1. Panel configuration contains SQL query
  2. Dashboard context calls refreshPanelData(panelId)
  3. Query context executes SQL against GigaAPI
  4. Response parsed as NDJSON format
  5. Data transformed and stored in panel data
  6. UI components re-render with new data

Error Handling:

  • Network errors are captured and displayed
  • SQL syntax errors shown in panel
  • Malformed NDJSON lines are logged and skipped

Chart System

ECharts Integration

File: src/lib/charts/echarts-configs.ts

Chart Configuration Generators:

// Time Series Configuration
export const createTimeSeriesConfig = (
  data: NDJSONRecord[],
  config: PanelConfig
): EChartsOption => {
  // Transform data and create ECharts configuration
  // Handles multiple series, time parsing, and styling
}

// Gauge Configuration
export const createGaugeConfig = (
  value: number,
  config: PanelConfig
): EChartsOption => {
  // Create circular gauge with thresholds and styling
}

Supported Chart Types:

  • Line charts with time series data
  • Area charts with filled regions
  • Bar charts for categorical data
  • Scatter plots for correlation analysis
  • Gauge charts for single values with ranges
  • Statistical displays with thresholds

Performance Optimizations

Data Management

  • Lazy Loading: Panels only load data when visible
  • Caching: Query results cached in memory
  • Debouncing: Configuration changes debounced to prevent excessive re-renders
  • Virtual Scrolling: Large datasets handled efficiently in tables

Memory Management

  • Map-based Storage: Efficient panel data storage with Map objects
  • Cleanup: Unused panel data automatically garbage collected
  • IndexedDB: Large datasets persisted to disk, not memory

Development Guidelines

Adding New Panel Types

  1. Create Panel Component:
// src/components/dashboard/panels/MyNewPanel.tsx
export default function MyNewPanel({
  config,
  data,
  isEditMode,
  onConfigChange
}: PanelProps) {
  // Implementation
}
  1. Register Panel Type:
// src/components/dashboard/panels/index.ts
export const PANEL_TYPES = {
  mynew: {
    type: 'mynew',
    name: 'My New Panel',
    description: 'Description of the new panel',
    component: MyNewPanel
  }
}

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions