Complete configuration interface for managing viewer state, including view settings, plugin configuration, and column styling.
The main configuration interface that encompasses all viewer settings.
/**
* Complete viewer configuration including plugin, theme, and view settings
*/
interface ViewerConfigUpdate {
/** Configuration version for compatibility */
version?: string | null;
/** Active plugin name */
plugin?: string | null;
/** Viewer title */
title?: string | null;
/** Active theme name */
theme?: string | null;
/** Whether settings panel is open */
settings?: boolean | null;
/** Plugin-specific configuration */
plugin_config?: any | null;
/** Column styling and formatting configuration */
columns_config?: Record<string, ColumnConfigValues> | null;
// ViewConfig properties (flattened from core Perspective)
/** Columns to group by */
group_by?: Array<string> | null;
/** Columns to split by */
split_by?: Array<string> | null;
/** Visible columns (null = show all) */
columns?: Array<string | null> | null;
/** Applied filters */
filter?: Array<Filter> | null;
/** Sort configuration */
sort?: Array<Sort> | null;
/** Custom expression columns */
expressions?: Record<string, string> | null;
/** Aggregation functions by column */
aggregates?: Record<string, Aggregate> | null;
/** Group by depth limit */
group_by_depth?: number | null;
/** Filter combination operator */
filter_op?: FilterReducer | null;
}Configuration for individual column styling and formatting.
/**
* Column-specific styling and configuration values
*/
interface ColumnConfigValues {
/** Symbol mappings for categorical data visualization */
symbols?: Record<string, string>;
/** Number column styling configuration */
datagrid_number_style?: NumberColumnStyleConfig;
/** String column styling configuration */
datagrid_string_style?: StringColumnStyleConfig;
/** Datetime column styling configuration */
datagrid_datetime_style?: DatetimeColumnStyleConfig;
/** Custom number formatting */
number_format?: CustomNumberFormatConfig | null;
/** Aggregation depth for hierarchical data */
aggregate_depth?: number;
}
interface NumberColumnStyleConfig {
color?: string;
gradient?: number;
pos_color?: string;
neg_color?: string;
format?: string;
}
interface StringColumnStyleConfig {
color?: string;
format?: string;
}
interface DatetimeColumnStyleConfig {
color?: string;
format?: string;
datetime_format?: string;
}
interface CustomNumberFormatConfig {
style?: "decimal" | "currency" | "percent";
currency?: string;
minimumFractionDigits?: number;
maximumFractionDigits?: number;
}Define data filtering rules and operators.
/**
* Filter definition as [column, operator, value]
*/
type Filter = [string, string, FilterTerm];
/**
* Filter value - can be single value or array of values
*/
type FilterTerm = Array<Scalar> | Scalar;
/**
* Basic data types supported in filters
*/
type Scalar = number | string | boolean | null;
/**
* Filter combination operator
*/
type FilterReducer = "and" | "or";Define sorting rules for data columns.
/**
* Sort configuration as [column, direction]
*/
type Sort = [string, "asc" | "desc"];Define aggregation functions for grouped data.
/**
* Aggregation function types
*/
type Aggregate =
| "sum"
| "mean"
| "count"
| "distinct count"
| "min"
| "max"
| "median"
| "first"
| "last"
| "std"
| "var";import "@finos/perspective-viewer";
const viewer = document.createElement("perspective-viewer");
// Configure basic view settings
await viewer.restore({
plugin: "d3_y_bar",
columns: ["sales", "profit"],
group_by: ["region"],
sort: [["sales", "desc"]],
theme: "Pro Dark"
});// Complex configuration with filtering and multiple grouping levels
await viewer.restore({
plugin: "d3_treemap",
group_by: ["category", "subcategory"],
columns: ["sales"],
filter: [
["date", ">=", "2023-01-01"],
["region", "in", ["North", "South", "East"]],
["sales", ">", 1000]
],
filter_op: "and",
sort: [["sales", "desc"]],
group_by_depth: 2
});// Configure column-specific styling
await viewer.restore({
plugin: "datagrid",
columns: ["product", "sales", "profit", "date"],
columns_config: {
sales: {
datagrid_number_style: {
color: "#1f77b4",
format: "currency",
pos_color: "#2ca02c",
neg_color: "#d62728"
},
number_format: {
style: "currency",
currency: "USD",
minimumFractionDigits: 2
}
},
profit: {
datagrid_number_style: {
gradient: 1,
pos_color: "#2ca02c",
neg_color: "#d62728"
}
},
date: {
datagrid_datetime_style: {
format: "YYYY-MM-DD",
color: "#666666"
}
}
}
});// Add computed columns with expressions
await viewer.restore({
plugin: "d3_xy_scatter",
columns: ["sales", "profit", "profit_margin"],
expressions: {
"profit_margin": '"profit" / "sales" * 100',
"total_value": '"quantity" * "unit_price"',
"growth_rate": '("current_sales" - "previous_sales") / "previous_sales" * 100'
},
group_by: ["region"]
});// Configuration with plugin-specific settings
await viewer.restore({
plugin: "d3_candlestick",
columns: ["open", "high", "low", "close"],
group_by: ["date"],
plugin_config: {
// Plugin-specific configuration
colorScheme: "viridis",
showVolume: true,
candleWidth: 0.8,
showMovingAverage: true,
movingAveragePeriod: 20
}
});// Configure theme and UI state
await viewer.restore({
theme: "Material Dark",
settings: true, // Show settings panel
title: "Sales Dashboard",
plugin: "d3_y_line",
columns: ["date", "sales"],
group_by: ["date"]
});// Save current configuration
const config = await viewer.save("json");
// Save as different formats
const configString = await viewer.save("string");
const configBuffer = await viewer.save("arraybuffer");
// Store configuration
localStorage.setItem("viewerConfig", JSON.stringify(config));// Restore from saved configuration
const savedConfig = JSON.parse(localStorage.getItem("viewerConfig"));
await viewer.restore(savedConfig);
// Partial configuration updates
await viewer.restore({
plugin: "d3_y_bar", // Only change the plugin
theme: "Pro Light" // And theme
});// Validate configuration before applying
function validateConfig(config: ViewerConfigUpdate): boolean {
// Check required fields
if (config.plugin && typeof config.plugin !== 'string') {
return false;
}
// Validate filter format
if (config.filter) {
for (const filter of config.filter) {
if (!Array.isArray(filter) || filter.length !== 3) {
return false;
}
}
}
// Validate sort format
if (config.sort) {
for (const sort of config.sort) {
if (!Array.isArray(sort) || sort.length !== 2) {
return false;
}
if (!["asc", "desc"].includes(sort[1])) {
return false;
}
}
}
return true;
}
// Use validation before restore
if (validateConfig(userConfig)) {
await viewer.restore(userConfig);
} else {
console.error("Invalid configuration");
}// Listen for configuration changes
viewer.addEventListener("perspective-config-update", (event) => {
const config: ViewerConfigUpdate = event.detail;
console.log("Configuration updated:", config);
// Save configuration on changes
localStorage.setItem("autoSaveConfig", JSON.stringify(config));
});
// Apply configuration updates dynamically
async function updateVisualization(newSettings: Partial<ViewerConfigUpdate>) {
const currentConfig = await viewer.save();
const updatedConfig = { ...currentConfig, ...newSettings };
await viewer.restore(updatedConfig);
}
// Example: Switch to different view
await updateVisualization({
plugin: "d3_heatmap",
group_by: ["row_category"],
split_by: ["col_category"],
columns: ["value"]
});// Reset to defaults
await viewer.reset();
// Reset including expressions and column settings
await viewer.reset(true);
// Reset specific aspects
await viewer.restore({
plugin: undefined, // Reset to default plugin
group_by: [], // Clear grouping
filter: [], // Clear filters
sort: [] // Clear sorting
});