CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-finos--perspective-workspace

Perspective Workspace - A Custom Element for coordinating multiple perspective-viewer instances with docking, tabbing, filtering, and state management capabilities for interactive analytics dashboards

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

viewer-management.mddocs/

Viewer Management

System for adding, configuring, and managing individual perspective-viewer instances within the workspace.

Capabilities

Adding Viewers

Core functionality for creating and configuring new perspective-viewer instances in the workspace.

/**
 * Viewer management operations for adding and configuring viewers
 */
interface ViewerManager {
  /** Add new viewer to workspace with configuration */
  addViewer(config: ViewerConfigUpdateExt, is_global_filter?: boolean): Promise<void>;
  
  /** Await all async tasks for all viewers to complete */
  flush(): Promise<void>;
}

/**
 * Extended viewer configuration including table reference
 * Extends the standard perspective-viewer configuration
 */
interface ViewerConfigUpdateExt extends ViewerConfigUpdate {
  /** Name of the table this viewer should display */
  table: string;
}

Usage Examples:

import { HTMLPerspectiveWorkspaceElement } from "@finos/perspective-workspace";

const workspace = document.createElement("perspective-workspace") as HTMLPerspectiveWorkspaceElement;

// Add a basic table viewer
await workspace.addViewer({
  table: "salesData",
  columns: ["product", "sales", "region"],
  group_by: ["region"]
});

// Add a chart viewer
await workspace.addViewer({
  table: "salesData",
  plugin: "d3_bar",
  columns: ["sales"],
  group_by: ["product"],
  aggregates: { sales: "sum" }
});

// Add a viewer as a global filter (master view)
await workspace.addViewer({
  table: "salesData",
  columns: ["region", "product"],
  group_by: ["region"]
}, true); // is_global_filter = true

// Wait for all viewers to complete loading
await workspace.flush();

Viewer Widget Management

Individual viewer instances are wrapped in widgets that provide additional functionality.

/**
 * Widget wrapper for perspective-viewer instances
 * Extends Lumino Widget with perspective-specific functionality
 */
class PerspectiveViewerWidget extends Widget {
  /** Toggle configuration panel visibility */
  toggleConfig(): Promise<void>;
  
  /** Load table into the viewer */
  load(table: psp.Table | Promise<psp.Table>): Promise<void>;
  
  /** Restore viewer configuration from saved state */
  restore(config: psp_viewer.ViewerConfigUpdate & { table: string }): void;
  
  /** Save current viewer configuration */
  save(): Promise<psp_viewer.ViewerConfigUpdate & { table: string }>;
  
  /** Remove CSS class from widget */
  removeClass(name: string): void;
  
  /** The underlying perspective-viewer element */
  readonly viewer: HTMLPerspectiveViewerElement;
  
  /** Widget name for identification */
  readonly name: string;
  
  /** Optional Promise for async operations */
  task?: Promise<void>;
}

Usage Examples:

import { PerspectiveWorkspace } from "@finos/perspective-workspace";

const workspace = new PerspectiveWorkspace();

// Get widget by name after adding viewer
const widget = workspace.getWidgetByName("myViewer");
if (widget) {
  // Toggle configuration panel
  await widget.toggleConfig();
  
  // Save widget configuration
  const config = widget.save();
  
  // Restore configuration later
  await widget.restore(config);
  
  // Access underlying viewer element
  const viewerElement = widget.viewer;
  console.log("Viewer plugin:", viewerElement.plugin);
}

Global Filtering (Master-Detail)

System for creating relationships where one viewer's selection filters other viewers.

/**
 * Master-detail functionality for global filtering
 */
interface GlobalFilterManager {
  /** Make widget a global filter source (master view) */
  makeMaster(widget: PerspectiveViewerWidget): void;
  
  /** Make widget a detail view that responds to global filters */
  makeDetail(widget: PerspectiveViewerWidget): void;
  
  /** Toggle global filter mode for widget */
  toggleMasterDetail(widget: PerspectiveViewerWidget): void;
}

Usage Examples:

const workspace = new PerspectiveWorkspace();

// Add master viewer (will act as filter)
await workspace.addViewer({
  table: "salesData",
  columns: ["region", "totalSales"],
  group_by: ["region"],
  aggregates: { totalSales: "sum" }
});

// Add detail viewers (will be filtered by master)
await workspace.addViewer({
  table: "salesData", 
  columns: ["product", "sales", "date"],
  group_by: ["product"]
});

await workspace.addViewer({
  table: "salesData",
  plugin: "d3_line",
  columns: ["sales"],
  group_by: ["date"]
});

// Set up master-detail relationships
const masterWidget = workspace.getWidgetByName("region-summary");
const detailWidgets = workspace.getAllWidgets().filter(w => w !== masterWidget);

if (masterWidget) {
  workspace.makeMaster(masterWidget);
  detailWidgets.forEach(widget => workspace.makeDetail(widget));
}

// Now selections in master will filter detail views

Widget Duplication

Create copies of existing viewers with the same configuration.

Usage Examples:

const workspace = new PerspectiveWorkspace();

// Add initial viewer
await workspace.addViewer({
  table: "salesData",
  columns: ["product", "sales"],
  group_by: ["product"],
  plugin: "d3_bar"
});

// Duplicate the viewer
const originalWidget = workspace.getAllWidgets()[0];
await workspace.duplicate(originalWidget);
// Creates an identical viewer with same table and configuration

Single Document Mode

Toggle between multi-panel layout and single maximized viewer.

/**
 * Single document interface functionality
 */
interface SingleDocumentManager {
  /** Toggle maximize mode for widget (single document interface) */
  toggleSingleDocument(widget: PerspectiveViewerWidget): void;
}

Usage Examples:

const workspace = new PerspectiveWorkspace();

// Toggle single document mode for a widget
const widget = workspace.getAllWidgets()[0];
if (widget) {
  // Maximize widget to full workspace
  workspace.toggleSingleDocument(widget);
  
  // Call again to restore multi-panel layout
  workspace.toggleSingleDocument(widget);
}

docs

index.md

layout-sizing.md

table-management.md

viewer-management.md

workspace-management.md

tile.json