Skip to main content

Plugin development

Vitessce supports plugin view types, coordination types, and file types.

Plugin view types and coordination types can enable development of interactive visualizations to support custom use cases (i.e., use cases beyond those supported by existing view types). Plugin file types can enable loading data that is stored in custom file formats.

caution

Note that because Vitessce is still under development we do not guarantee that minor version bumps of Vitessce will not break existing plugins. For instance, we do not make guarantees that exported helper functions such as React data-loading hooks (e.g., useRasterData, useExpressionMatrixData, etc.) will not be removed or will have a consistent function signature across Vitessce minor versions. However, we will keep them consistent across patch versions within the same minor version. Therefore, plugin developers should be sure to document which version(s) of Vitessce that plugins have been developed under. We recommend using a README badge to do so.

tip

If you believe a plugin would be applicable to the wider Vitessce user base, we encourage opening a discussion about contributing it back to the Vitessce core.

note

Currently, plugins can be defined and registered in JavaScript. There is not yet a straightforward way to expose plugins to the Python or R widgets (nor is there currently a way to develop plugins in Python/R directly). Hopefully we can make this possible in the future.

Plugins via props

Plugin view types, coordination types, and file types can be passed via props to the <Vitessce> React component.

<Vitessce
// ...
pluginViewTypes={/* array of PluginViewType */}
pluginFileTypes={/* array of PluginFileType */}
pluginJointFileTypes={/* array of PluginJointFileType */}
pluginCoordinationTypes={/* array of PluginCoordinationType */}
/>

Plugin view types

Plugin views must be implemented as React components. They must be wrapped in a PluginViewType instance so that the React component can be associated with a name that can be used as a value for the field layout[].component in the view config.

PluginViewType(viewType, reactComponent, coordinationTypes)

Parameters:

  • viewType (string) - A name for the plugin view type.
  • reactComponent (function) - A React function component.
  • coordinationType (string[]) - A list of coordination types supported by this component.
import { PluginViewType, CoordinationType } from 'vitessce';

// ...
// Omitted: definition of a React component
// in some function called MyCustomZoomControllerSubscriber.
// ...

const pluginViewTypes = [
new PluginViewType(
'myCustomZoomController',
MyCustomZoomControllerSubscriber,
[
CoordinationType.DATASET,
CoordinationType.SPATIAL_ZOOM,
],
),
];

For a full example, see the Plugin View Type Development tutorial.

Plugin coordination types

Plugin coordination types must be registered to provide a default value, and so that views can subscribe to coordination value updates.

PluginCoordinationType(coordinationType, defaultValue, valueSchema)

Parameters:

  • coordinationType (string) - A name for the plugin coordination type.
  • defaultValue (z.infer<T1>) - A default value for the coordination type. Used for initialization if the initial value is undefined.
  • valueSchema (z.ZodTypeAny<T1>) - A Zod schema for the value.
import {
PluginCoordinationType,
z, // vitessce re-exports { z } from zod
} from 'vitessce';

const pluginCoordinationTypes = [
new PluginCoordinationType(
'myCustomCoordinationType',
0.75,
z.number(),
),
];

For a full example, see the Plugin Coordination Type Development tutorial.

Plugin file types

A plugin (atomic) file type must be implemented as a pair of JavaScript classes (a data source class and a data loader class). The classes must be registered so that they can be associated with a name that can be used as a value for the field datasets[].files[].fileType in the view config.

PluginFileType(fileType, dataType, dataLoaderClass, dataSourceClass, optionsSchema)

Parameters:

  • fileType (string) - A name for the plugin file type.
  • dataType (string) - A name for the data type associated with the plugin file type. Can be an existing data type.
  • dataLoaderClass (class) - A data loader class definition. Its constructor takes two parameters: dataSource, fileDefinition where dataSource is a data source instance and fileDefinition is the file definition JSON object from the view config.
  • dataSourceClass (class) - A data source class definition. Can be an existing data source class. Its constructor takes one parameter: an object with the file URL { url }.
  • optionsSchema (z.ZodTypeAny<T1>) - A Zod schema for the options property of file definitions for this fileType.
import {
PluginFileType,
z, // vitessce re-exports { z } from zod
} from 'vitessce';

// ...
// Omitted: definition of the classes
// MyCustomExpressionMatrixDataLoader and MyCustomExpressionMatrixDataSource.
// ...

const pluginFileTypes = [
new PluginFileType(
'myCustomExpressionMatrixFormat.xyz',
'expression-matrix',
MyCustomExpressionMatrixDataLoader,
MyCustomExpressionMatrixDataSource,
z.null(),
),
];

For a full example, see the Plugin File Type Development tutorial.

Plugin joint file types

A plugin joint file type must be implemented as a JavaScript function that takes one joint file definition as input and returns an array of file definitions with atomic file types. The function must be registered so that the file type can be associated with a name that can be used as a value for the field datasets[].files[].fileType in the view config.

PluginJointFileType(fileType, expandFunction, optionsSchema)

Parameters:

  • fileType (string) - A name for the plugin joint file type.
  • expandFunction (function) - A JavaScript function.
  • optionsSchema (z.ZodTypeAny<T1>) - A Zod schema for the options property of file definitions for this fileType.
import {
PluginJointFileType,
z, // vitessce re-exports { z } from zod
} from 'vitessce';

function mySegmentationsAndLocationsExpansionFunction(fileDef) {
const { url, coordinationValues } = fileDef;
return [
{
// Assuming 'obsSegmentations.segmentations-and-locations.csv'
// was already registered as an "atomic" plugin file type.
fileType: 'obsSegmentations.segmentations-and-locations.csv',
url,
coordinationValues,
},
{
// Assuming 'obsLocations.segmentations-and-locations.csv'
// was already registered as an "atomic" plugin file type.
fileType: 'obsLocations.segmentations-and-locations.csv',
url,
coordinationValues,
}
];
}

const pluginJointFileTypes = [
new PluginJointFileType(
'segmentations-and-locations.csv',
mySegmentationsAndLocationsExpansionFunction,
z.null(),
),
];