Trouble exporting Scene to .vtkjs

Dear All,

Using the xml plugin from Point labels available with PV 5.7? - #7 by jourdain, we were able to add text labels to a point cloud in ParaView (Nightly on Mac).

Now, we would like to export the scene to a .vtkjs file to finally allow our colleagues a quick inspection in the vtk Scene Explorer.

Unfortunately, as soon as the Label Representation is selected for our data, the following error message appears upon .vtkjs-export:

Generic Warning: In vtkPVWebExporter.cxx, line 71
Failed to rename datasets using ParaView proxy name

Traceback (most recent call last):
  File "/Applications/", line 77, in applyParaViewNaming
    renameMap = getRenameMap()
  File "/Applications/", line 36, in getRenameMap
    names = getAllNames()
  File "/Applications/", line 26, in getAllNames
    actorRep = vtkRepInstance.GetActiveRepresentation().GetActor()
AttributeError: 'paraview.modules.vtkRemotingViews.vtkDataLabelRepr' object has no attribute 'GetActor'

Do you have any idea what we can do about this? Thank you :slight_smile:

Unfortunately I don’t think we have yet an implementation of those 3D labels in vtk.js.
But once we do, we will need to extend some code in VTK/ParaView to properly handle those object in the scene so they can be exported and displayed in vtk.js.

Maybe @martink or @Forrest_Li may know better the status of vtk.js on those text labels.


We do not have a point label class yet on the JS side.

But …you can sort of do what you want with a bit of code like this example

but it isn’t a direct in/out from paraview. But I think it is possible with some JS side coding.

Actually @martink suggestion is really good. You could export from ParaView just the pointset with the string array attached to it and have a custom vtk.js scene viewer that will do the same labels technique as that example.

The only caveat I see is that the PV exporter may currently skip non numerical array but that should be easy to fix/extend. And the JS code required to do such viewer will be pretty minimal and quick.

Hi @martink , @jourdain ,
thank you for your suggestions and sorry for not coming back to the topic earlier - I needed a while to learn at least some basics of javascript, npm, webpack, etc. to get things running :slight_smile:

Slightly inspired by SceneExplorerWidget.js, I put together the following LabelWidget.js:

import vtkPixelSpaceCallbackMapper from '@kitware/vtk.js/Rendering/Core/PixelSpaceCallbackMapper';
import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';

export default function addWidget(renderer, container, sceneItems, render) {

    let dims = null;

    const textCanvas = document.createElement('canvas');
    textCanvas.classList.add('labelCanvas'); = 'absolute'; = '0px'; = '0px'; = '100%'; = '100%'; = 'hidden';

    const textCtx = textCanvas.getContext('2d');

    window.addEventListener('resize', () => {
        dims = container.getBoundingClientRect();
        textCanvas.setAttribute('width', dims.width);
        textCanvas.setAttribute('height', dims.height);

    window.dispatchEvent(new Event("resize"));

    function getArrayNames(sceneItem) {
        return `<option value="0">---</option>`
            + sceneItem.source.getArrays()
                // introduced "+1" in array index, so that "0" means "no labels"
                .map((array, idx) => `<option value="${idx+1}">${}</option>`)

    const listStr = sceneItems
        (item, idx) =>
            `<li><select name="${idx}">${getArrayNames(item)}</select>&nbsp;&nbsp;${}</li>`

    const listContainer = document.createElement('ul');
    listContainer.innerHTML = listStr; = 'absolute'; = '25px'; = '100px'; = 'white'; = '5px'; = 'none'; = '5px 10px'; = '0'; = 'block'; = 'solid 1px black';


    document.querySelector('body').addEventListener('keypress', (e) => {
      if (String.fromCharCode(e.charCode) === 'l') {
        if ( === 'none') {
 = 'block';
        } else {
 = 'none';

    const selectList = listContainer.querySelectorAll('select');
    for (let i = 0; i < selectList.length; i++) {
      const selectElem = selectList[i];
      selectElem.addEventListener('change', handleChange);

    function handleChange(e) {
        const itemIdx = Number(;
        const value = Number(;
        // ugly hack: we just append an attribute to the sceneItem
        sceneItems[itemIdx].labelArray = value;
        if (render) {

    for (const sceneItem of sceneItems) {
       console.log(`Adding labels to ${}`)

        const psMapper = vtkPixelSpaceCallbackMapper.newInstance();
        psMapper.setCallback((coordsList) => {
        if (textCtx && dims) {
            textCtx.clearRect(0, 0, dims.width, dims.height);

            const labelArray = sceneItem.labelArray;

            if (labelArray) {
                coordsList.forEach((xy, idx) => {
                    textCtx.font = '12px serif';
                    textCtx.textAlign = 'center';
                    textCtx.textBaseline = 'middle';
                        // "-1" to compensate for offset introduced in getArrays()
                        // pixel ratio scaling from
                        xy[0] / window.devicePixelRatio,
                        dims.height - xy[1] / window.devicePixelRatio);
                    });            }

        const textActor = vtkActor.newInstance();

which can be instantiated in the onReady() function of the SceneExplorer via

import labelWidget from './LabelWidget';

        // Add UI to enable labels for different scene items

Now, I can conveniently select, for which sceneItems I want to see labels at the respective vtkPoints and which data array entries are to be printed (very messy here, this is not the original data):

Missing point is now, to also export the non-numeric point data arrays from Paraview into the *.vtkjs file.

Do you possibly have suggestions where I could start with this?

You will have to fix that class and the Array one to support the vtkAbstractArray/vtkStringArray.

Ouch, seeing C++ here does that mean I‘d have to build Paraview myself? - Did that years ago on Linux, but today I‘m on a corporate Windows machine with virtually no permissions…

Would there be an option with Python scripting in Paraview?