diff --git a/package.json b/package.json
index 787f687..eca0932 100644
--- a/package.json
+++ b/package.json
@@ -27,7 +27,7 @@
"semantic-release": "semantic-release"
},
"peerDependencies": {
- "@kitware/vtk.js": "^20.1.3",
+ "@kitware/vtk.js": "^21.3.0",
"react": "^16.0.0"
},
"devDependencies": {
@@ -35,7 +35,7 @@
"@babel/plugin-transform-runtime": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@babel/preset-react": "^7.12.10",
- "@kitware/vtk.js": "^20.1.3",
+ "@kitware/vtk.js": "^21.3.0",
"@rollup/plugin-babel": "^5.2.2",
"@rollup/plugin-commonjs": "17.0.0",
"@rollup/plugin-eslint": "^8.0.1",
diff --git a/src/core/Geometry2DRepresentation.js b/src/core/Geometry2DRepresentation.js
new file mode 100644
index 0000000..da06eeb
--- /dev/null
+++ b/src/core/Geometry2DRepresentation.js
@@ -0,0 +1,230 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+
+import { ViewContext, RepresentationContext, DownstreamContext } from './View';
+import { vec2Equals } from '../utils';
+
+import vtkActor2D from '@kitware/vtk.js/Rendering/Core/Actor2D.js';
+import vtkMapper2D from '@kitware/vtk.js/Rendering/Core/Mapper2D.js';
+import vtkColorMaps from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps.js';
+import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction.js';
+import vtkCoordinate from '@kitware/vtk.js/Rendering/Core/Coordinate.js';
+import { Coordinate } from '@kitware/vtk.js/Rendering/Core/Coordinate/Constants.js';
+
+/**
+ * Geometry2DRepresentation is useful for rendering polydata in 2D screen space.
+ * It takes the following set of properties:
+ * - representation: ['POINTS', 'WIREFRAME', 'SURFACE'],
+ * - pointSize: 1,
+ * - color: [1,1,1],
+ * - opacity: 1,
+ */
+export default class Geometry2DRepresentation extends Component {
+ constructor(props) {
+ super(props);
+
+ // Guard to prevent rendering if no data
+ this.validData = false;
+ this.currentVisibility = true;
+
+ // Create vtk.js actor/mapper
+ this.actor = vtkActor2D.newInstance({
+ visibility: false,
+ representationId: props.id,
+ });
+ this.lookupTable = vtkColorTransferFunction.newInstance();
+ this.transformCoordinate = vtkCoordinate.newInstance({
+ coordinateSystem: Coordinate.DISPLAY,
+ });
+ this.mapper = vtkMapper2D.newInstance({
+ lookupTable: this.lookupTable,
+ useLookupTableScalarRange: false,
+ scalarVisibility: false,
+ transformCoordinate: this.transformCoordinate,
+ });
+ this.actor.setMapper(this.mapper);
+
+ this.subscriptions = [];
+ }
+
+ render() {
+ return (
+
+ {(view) => {
+ if (!this.view) {
+ view.renderer.addActor2D(this.actor);
+ this.view = view;
+ }
+ return (
+
+
+
+ {this.props.children}
+
+
+
+ );
+ }}
+
+ );
+ }
+
+ componentDidMount() {
+ this.update(this.props);
+ }
+
+ componentDidUpdate(prevProps, prevState, snapshot) {
+ this.update(this.props, prevProps);
+ }
+
+ componentWillUnmount() {
+ while (this.subscriptions.length) {
+ this.subscriptions.pop().unsubscribe();
+ }
+
+ if (this.view && this.view.renderer) {
+ this.view.renderer.removeActor(this.actor);
+ }
+
+ this.actor.delete();
+ this.actor = null;
+
+ this.mapper.delete();
+ this.mapper = null;
+
+ this.lookupTable.delete();
+ this.lookupTable = null;
+
+ this.transformCoordinate.delete();
+ this.transformCoordinate = null;
+ }
+
+ update(props, previous) {
+ const {
+ actor,
+ mapper,
+ property,
+ colorMapPreset,
+ colorDataRange,
+ transformCoordinate,
+ } = props;
+ let changed = false;
+
+ if (actor && (!previous || actor !== previous.actor)) {
+ changed = this.actor.set(actor) || changed;
+ }
+ if (mapper && (!previous || mapper !== previous.mapper)) {
+ changed = this.mapper.set(mapper) || changed;
+ }
+ if (property && (!previous || property !== previous.property)) {
+ changed = this.actor.getProperty().set(property) || changed;
+ }
+
+ if (
+ colorMapPreset &&
+ this.lookupTable &&
+ (!previous || colorMapPreset !== previous.colorMapPreset)
+ ) {
+ changed = true;
+ const preset = vtkColorMaps.getPresetByName(colorMapPreset);
+ this.lookupTable.applyColorMap(preset);
+ this.lookupTable.setMappingRange(...colorDataRange);
+ this.lookupTable.updateRange();
+ }
+
+ if (
+ colorDataRange &&
+ this.lookupTable &&
+ (!previous || !vec2Equals(colorDataRange, previous.colorDataRange))
+ ) {
+ changed = true;
+ this.lookupTable.setMappingRange(...colorDataRange);
+ this.lookupTable.updateRange();
+ }
+
+ if (
+ transformCoordinate &&
+ this.transformCoordinate &&
+ (!previous || transformCoordinate !== previous.transformCoordinate)
+ ) {
+ changed = true;
+ this.transformCoordinate.set(transformCoordinate);
+ }
+
+ // actor visibility
+ if (actor && actor.visibility !== undefined) {
+ this.currentVisibility = actor.visibility;
+ changed =
+ this.actor.setVisibility(this.currentVisibility && this.validData) ||
+ changed;
+ }
+
+ if (changed) {
+ // trigger render
+ this.dataChanged();
+ }
+ }
+
+ dataAvailable() {
+ if (!this.validData) {
+ this.validData = true;
+ this.actor.setVisibility(this.currentVisibility);
+
+ // trigger render
+ this.dataChanged();
+ }
+ }
+
+ dataChanged() {
+ if (this.view) {
+ this.view.renderView();
+ }
+ }
+}
+
+Geometry2DRepresentation.defaultProps = {
+ colorMapPreset: 'erdc_rainbow_bright',
+ colorDataRange: [0, 1],
+};
+
+Geometry2DRepresentation.propTypes = {
+ /**
+ * The ID used to identify this component.
+ */
+ id: PropTypes.string,
+
+ /**
+ * Properties to set to the actor
+ */
+ actor: PropTypes.object,
+
+ /**
+ * Properties to set to the actor
+ */
+ mapper: PropTypes.object,
+
+ /**
+ * Properties to set to the actor.property
+ */
+ property: PropTypes.object,
+
+ /**
+ * Preset name for the lookup table color map
+ */
+ colorMapPreset: PropTypes.string,
+
+ /**
+ * Data range use for the colorMap
+ */
+ colorDataRange: PropTypes.arrayOf(PropTypes.number),
+
+ /**
+ * Coordinate system that the input dataset is in.
+ */
+ transformCoordinate: PropTypes.object,
+
+ children: PropTypes.oneOfType([
+ PropTypes.arrayOf(PropTypes.node),
+ PropTypes.node,
+ ]),
+};
diff --git a/src/core/index.js b/src/core/index.js
index 5a3e542..e646c07 100644
--- a/src/core/index.js
+++ b/src/core/index.js
@@ -7,6 +7,7 @@ import vtkReader from './Reader';
import vtkShareDataSet from './ShareDataSet';
import vtkView from './View';
import vtkGeometryRepresentation from './GeometryRepresentation';
+import vtkGeometry2DRepresentation from './Geometry2DRepresentation';
import vtkGlyphRepresentation from './GlyphRepresentation';
import vtkImageData from './ImageData';
import vtkDataArray from './DataArray';
@@ -24,6 +25,7 @@ export const Reader = vtkReader;
export const ShareDataSet = vtkShareDataSet;
export const View = vtkView;
export const GeometryRepresentation = vtkGeometryRepresentation;
+export const Geometry2DRepresentation = vtkGeometry2DRepresentation;
export const GlyphRepresentation = vtkGlyphRepresentation;
export const ImageData = vtkImageData;
export const DataArray = vtkDataArray;
@@ -42,6 +44,7 @@ export default {
ShareDataSet: vtkShareDataSet,
View: vtkView,
GeometryRepresentation: vtkGeometryRepresentation,
+ Geometry2DRepresentation: vtkGeometry2DRepresentation,
GlyphRepresentation: vtkGlyphRepresentation,
ImageData: vtkImageData,
DataArray: vtkDataArray,
diff --git a/src/index.js b/src/index.js
index 768523a..c077c6c 100644
--- a/src/index.js
+++ b/src/index.js
@@ -23,6 +23,7 @@ export const Reader = Core.Reader;
export const ShareDataSet = Core.ShareDataSet;
export const View = Core.View;
export const GeometryRepresentation = Core.GeometryRepresentation;
+export const Geometry2DRepresentation = Core.Geometry2DRepresentation;
export const GlyphRepresentation = Core.GlyphRepresentation;
export const ImageData = Core.ImageData;
export const DataArray = Core.DataArray;
diff --git a/usage/Geometry/PolyDataViewer.js b/usage/Geometry/PolyDataViewer.js
index 5f1d9d2..b42d5a1 100644
--- a/usage/Geometry/PolyDataViewer.js
+++ b/usage/Geometry/PolyDataViewer.js
@@ -1,46 +1,92 @@
import React from 'react';
import ReactDOM from 'react-dom';
-import { View, GeometryRepresentation, PolyData } from 'react-vtk-js';
+import {
+ View,
+ GeometryRepresentation,
+ Geometry2DRepresentation,
+ PolyData,
+} from 'react-vtk-js';
+
+import { Representation } from '@kitware/vtk.js/Rendering/Core/Property/Constants';
+import { DisplayLocation } from '@kitware/vtk.js/Rendering/Core/Property2D/Constants';
+import { Coordinate } from '@kitware/vtk.js/Rendering/Core/Coordinate/Constants';
// React complains about unique key prop but I don't see why
function Example(props) {
return (
-