sisense.com
✅ 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):

PropTypeDescription
dataSourceDataSourceData model to query. Pass to query hooks.
dataOptionsDataOptionsStructured data config matching your data panel inputs.
styleOptionsStyleOptionsStyle config from the design panel.
filtersFilter[] | FilterRelationsActive filters from the dashboard context.
highlightsFilter[]Cross-widget highlight filters. Matching data is visually emphasized.
onDataPointClickCustomVisualizationDataPointEventHandlerSingle data point click. See Event Handling.
onDataPointContextMenuCustomVisualizationDataPointContextMenuHandlerRight-click handler. See Event Handling.
onDataPointsSelectedCustomVisualizationDataPointsEventHandlerMulti-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>;
ParameterDefaultDescription
DataOptionsGenericDataOptionsShape of data options matching data panel inputs
StyleOptionsCustomVisualizationStyleOptionsShape of style options from design panel
DataPointAbstractDataPointWithEntriesShape 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

Last Updated: