✅ You are viewing documentation for the latest version of Compose SDK.
Version:

# Building a Visualization

The visualization component is the core of your plugin. It receives structured props from the SDK and renders your custom UI.

# Component Signature

import type { CustomVisualization, CustomVisualizationProps } from '@sisense/sdk-ui';

import type { DataOptions, StyleOptions } from '../types';

type VisualizationProps = CustomVisualizationProps<DataOptions, StyleOptions>;

const Visualization: CustomVisualization<VisualizationProps> = (props) => {
  return <div>...</div>;
};

# Props Overview

Your component receives VisualizationProps (i.e. CustomVisualizationProps<DataOptions, StyleOptions>DataPoint defaults to AbstractDataPointWithEntries):

Prop Type Description
dataSource DataSource Data model to query. Pass to query hooks.
dataOptions DataOptions Structured data config matching your data panel inputs.
styleOptions StyleOptions Style config from the design panel.
filters Filter[] | FilterRelations Active filters from the dashboard context.
highlights Filter[] Cross-widget highlight filters. Matching data is visually emphasized.
onDataPointClick CustomVisualizationDataPointEventHandler Single data point click. See Event Handling.
onDataPointContextMenu CustomVisualizationDataPointContextMenuHandler Right-click handler. See Event Handling.
onDataPointsSelected CustomVisualizationDataPointsEventHandler Multi-selection handler. See Event Handling.

Both filters and highlights are passed to query hooks when fetching data (covered in Fetching Data).

Always define defaults for styleOptions so the widget renders correctly when no styles are configured:

const Visualization: CustomVisualization<VisualizationProps> = ({ styleOptions }) => {
  const colorScheme = styleOptions?.colorScheme ?? 'warm';
  const showLegend = styleOptions?.showLegend ?? true;
  // ...
};

# Type Parameterization

CustomVisualizationProps accepts three type parameters:

CustomVisualizationProps<DataOptions, StyleOptions, DataPoint>;
Parameter Default Description
DataOptions GenericDataOptions Shape of data options matching data panel inputs
StyleOptions CustomVisualizationStyleOptions Shape of style options from design panel
DataPoint AbstractDataPointWithEntries Shape of data points in event handlers

# Rendering Environment

Your component renders inside:

  1. WidgetContainer — title bar, description, export options, border styling
  2. DynamicSizeContainer — responsive width/height based on the widget's allocated space
  3. ErrorBoundary — catches rendering errors and shows fallback UI

Design your component to fill its container responsively. Handle expected errors gracefully:

const Visualization: CustomVisualization<VisualizationProps> = ({ dataOptions }) => {
  if (!dataOptions.value?.length) {
    return <div style={{ padding: 16, color: '#666' }}>Add a measure to get started.</div>;
  }

  return <div>...</div>;
};

# Widget Configuration

Control widget-level behavior via customWidget.config:

customWidget: {
  name: 'my-custom-chart',
  displayName: 'My Custom Chart',
  config: {
    header: {
      visible: false, // Hide the widget header (title bar)
    },
  },
  visualization: { Component: Visualization },
},

Set header.visible: false for full-bleed visualizations that don't need a title bar.

# Wrapping Built-In Charts

You can wrap an existing Compose SDK chart inside a plugin to reuse SDK rendering while customizing behavior:

import type { CustomVisualization, CustomVisualizationProps } from '@sisense/sdk-ui';
import { LineChart } from '@sisense/sdk-ui';

import type { DataOptions, StyleOptions } from '../types';

type MyCustomLineChartProps = CustomVisualizationProps<DataOptions, StyleOptions>;

export const MyCustomLineChart: CustomVisualization<MyCustomLineChartProps> = (props) => {
  const styleOptions = { ...props.styleOptions };
  return (
    <LineChart
      dataSet={props.dataSource}
      dataOptions={props.dataOptions}
      filters={props.filters}
      styleOptions={styleOptions}
    />
  );
};

When wrapping built-in charts:

  • StyledColumn[] and StyledMeasureColumn[] can be passed directly — no manual .map() to Attribute needed; built-in charts accept styled columns
  • Spread styleOptions into a new object so downstream style merging works correctly
  • Use Pick<LineStyleOptions, ...> for your StyleOptions to expose only the properties your design panel controls

Next lesson: Fetching Data