# Volume Controller genericRenderWindow

**URL:** https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779
**Category:** Web
**Created:** [May 14, 2021, 11:01am UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779 "2021-05-14T11:01:27Z")
**Posts on this page:** 15
**Page:** 1

<div class="post-metadata">

### Author: ![Julia](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@Julia](https://discourse.vtk.org/u/Julia)
#### Post date: [May 14, 2021, 11:01am UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/1 "2021-05-14T11:01:27Z")

</div>

Hi,

I managed to get the volume viewer functionality of adding the controller widget to work in full screen render mode. However, I experience difficulty making it work with a generic render window (so not full screen). In the html a div is created with id ‘container’, this container is used in the javascript to render the window in that div.

```
 <div id="container" class="rounded shadow-lg" ></div>
   <script type="text/javascript">
          const {renderer, renderWindow } = window.createVTKWindow("#container", file);
                window.renderer = renderer;
                window.renderWindow = renderWindow;
     </script>
  </div>

```

In the javascript I tried the following:

```
function createVTKWindow(name, url) {
  const container = document.querySelector(`container id from div`);
  const background = userParams.background
  ? options.background.split(',').map((s) => Number(s))
   : [1, 1, 1];
  const containerStyle = userParams.containerStyle;
  const genericRenderWindow = vtkGenericRenderWindow.newInstance({
    background,
    containerStyle,
  });
  genericRenderWindow.setContainer(container);

  const renderer = genericRenderWindow.getRenderer();
  const renderWindow = genericRenderWindow.getRenderWindow();

  const camera = renderer.getActiveCamera()
  renderer.setActiveCamera(window.camera);

  fetch(url)
      .then(resp => resp.blob())
      .then(blob => {
          onDownloaded(container, renderer, renderWindow, blob, function() {
             $("#loader").remove();
         });
     })
      .catch(() => {
         console.log('Error retrieving data..')
         $("#loader").remove();
     });

  return {
    renderer: renderer,
    renderWindow: renderWindow
 };
window.createVTKWindow = createVTKWindow;

function onDownloaded(container, renderer, renderWindow, bin, completion = null) {
const reader = new FileReader();
reader.onload = function onLoad(e) {
    const vtiReader = vtkXMLImageDataReader.newInstance();
    vtiReader.parseAsArrayBuffer(reader.result);

    // --- Set up the cone actor ---
    const source = vtiReader.getOutputData(0);
    const mapper = vtkVolumeMapper.newInstance();
    const actor = vtkVolume.newInstance();

    const dataArray = source.getPointData().getScalars() || source.getPointData().getArrays()[0];
    const dataRange = dataArray.getRange();

    const lookupTable = vtkColorTransferFunction.newInstance();
    const piecewiseFunction = vtkPiecewiseFunction.newInstance();

    // /* Pipeline handling */
    actor.setMapper(mapper);
    mapper.setInputData(source);
    renderer.addActor(actor);

    const sampleDistance =
        0.7 *
        Math.sqrt(
            source
            .getSpacing()
            .map((v) => v * v)
            .reduce((a, b) => a + b, 0)
        );

    mapper.setSampleDistance(sampleDistance);

    // set the actor properties
    actor.getProperty().setRGBTransferFunction(0, lookupTable);
    actor.getProperty().setScalarOpacity(0, piecewiseFunction);
    actor.getProperty().setInterpolationTypeToLinear();

    actor
        .getProperty()
        .setScalarOpacityUnitDistance(
            0,
            vtkBoundingBox.getDiagonalLength(source.getBounds()) /
            Math.max(...source.getDimensions())
        );

    actor.getProperty().setGradientOpacityMinimumValue(0, 0);
    actor
        .getProperty()
        .setGradientOpacityMaximumValue(0, (dataRange[1] - dataRange[0]) * 0.05);
    actor.getProperty().setShade(true);
    actor.getProperty().setUseGradientOpacity(0, true);
    actor.getProperty().setGradientOpacityMinimumOpacity(0, 0.0);
    actor.getProperty().setGradientOpacityMaximumOpacity(0, 1.0);
    actor.getProperty().setAmbient(0.2);
    actor.getProperty().setDiffuse(0.7);
    actor.getProperty().setSpecular(0.3);
    actor.getProperty().setSpecularPower(8.0);

     const controllerWidget = vtkVolumeController.newInstance({
        size: [200, 100],
        rescaleColorMap: true,
        expanded: true,
      });

    const isBackgroundDark = background[0] + background[1] + background[2] < 1.5;
    controllerWidget.setContainer(container);
    controllerWidget.setupContent(renderWindow, actor, isBackgroundDark);
    controllerWidget.setSize(200, 100);
    controllerWidget.render();
    fpsMonitor.update();

    // --- Add actor to scene ---
    renderer.resetCamera();
    renderWindow.render();

    if (completion) completion();

};
  reader.readAsArrayBuffer(new File([bin], "data"));
}
window.onDownloaded = onDownloaded;

```

What results from this is a rendered window within the specified div. However, the window remains black and keeps on loading. How do I make the Volume Controller work with a generic render window? Can someone help? Thanks in advance!

---

<div class="post-metadata">

### Author: ![Sebastien\_Jourdain](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sebastien_jourdain/32/100_2.png) [@Sebastien\_Jourdain](https://discourse.vtk.org/u/Sebastien_Jourdain)
#### Post date: [May 14, 2021, 2:20pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/2 "2021-05-14T14:20:20Z")

</div>

You should not share the same container between the RenderWindow and the VolumeController. Each of them should have their own div…

---

<div class="post-metadata">

### Author: ![Julia](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@Julia](https://discourse.vtk.org/u/Julia)
#### Post date: [May 14, 2021, 2:28pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/3 "2021-05-14T14:28:39Z")

</div>

So I could put in the div above, another div for the controller? Then select that container and set it as the container for the controller widget?

---

<div class="post-metadata">

### Author: ![Sebastien\_Jourdain](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sebastien_jourdain/32/100_2.png) [@Sebastien\_Jourdain](https://discourse.vtk.org/u/Sebastien_Jourdain)
#### Post date: [May 14, 2021, 2:31pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/4 "2021-05-14T14:31:22Z")

</div>

Yes that was the idea… While also making sure the controller is above (z-index) the render window container…

---

<div class="post-metadata">

### Author: ![Julia](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@Julia](https://discourse.vtk.org/u/Julia)
#### Post date: [May 15, 2021, 6:21pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/5 "2021-05-15T18:21:45Z")

</div>

@Sebastien_Jourdain I tried creating a new div as you mentioned. I added the following in the javascript:

```auto
const controllerContainer = document.createElement('div');
controllerContainer.innerHTML = `<div id="controller" style="
            display: flex;
            align-items: stretch;
            flex-direction: column;
            justify-content: space-between;
            position: absolute;
            top: 5px;
            left: 5px;
            background: rgba(128, 128, 128, 0.5);
            background-color: rgba(128, 128, 128, 0.5);
            background-position-x: 0%;
            background-position-y: 0%;
            background-repeat: repeat;
            background-attachment: scroll;
            background-image: none;
            background-size: auto;
            background-origin: padding-box;
            background-clip: border-box;
            border-radius: 5px;
            border: 0.5px solid black;
            box-sizing: border-box;
            padding: 2px;
            z-index:5;"><div/>`;
container.appendChild(controllerContainer);

```

The container is the window where the volume rendering happens. So I append the constructed controllerContainer to the other container. However, I can find the div in the browser but the widget does not render in it and the page keeps on loading the entire time. What am I doing wrong?

```auto
       const controllerWidget = vtkVolumeController.newInstance({
            size: [450, 150],
            rescaleColorMap: true,
            expanded: true,
          });

        const isBackgroundDark = background[0] + background[1] + background[2] < 1.5;
        controllerWidget.setContainer(controllerContainer);
        controllerWidget.setupContent(renderWindow, actor, isBackgroundDark);
        controllerWidget.setSize(450, 150);
        controllerWidget.render();
        fpsMonitor.update();

```

The following screen is what I receive:

 ![image](https://discourse.vtk.org/uploads/default/original/2X/1/1346d9d990e93ed204fb1491fae582eb20df3f28.png)

---

<div class="post-metadata">

### Author: ![Julia](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@Julia](https://discourse.vtk.org/u/Julia)
#### Post date: [May 16, 2021, 6:29pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/6 "2021-05-16T18:29:24Z")

</div>

I finally found what’s wrong and it’s working now! I have only one question left. The sliders of the widget (for shadow and the colormap, see picture below) are not working.  
 ![image](https://discourse.vtk.org/uploads/default/original/2X/a/afc51981910a3c5a7254813d01ae4b61a9ced5c7.png)  
The rest is working very well. Is there perhaps a bug in the sliders? As the only thing that I am supposed to do is load in the controller and give it a container.

---

<div class="post-metadata">

### Author: ![Sebastien\_Jourdain](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sebastien_jourdain/32/100_2.png) [@Sebastien\_Jourdain](https://discourse.vtk.org/u/Sebastien_Jourdain)
#### Post date: [May 17, 2021, 6:26pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/7 "2021-05-17T18:26:59Z")

</div>

I don’t think there is any issue with the sliders. Can you explain what you mean by not working?

1. You can not grab them to make them move?
2. You can move them, but nothing change in the rendering?
3. Something else?

---

<div class="post-metadata">

### Author: ![Julia](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@Julia](https://discourse.vtk.org/u/Julia)
#### Post date: [May 17, 2021, 6:34pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/8 "2021-05-17T18:34:29Z")

</div>

It’s the first scenario you mention.

---

<div class="post-metadata">

### Author: ![Sebastien\_Jourdain](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sebastien_jourdain/32/100_2.png) [@Sebastien\_Jourdain](https://discourse.vtk.org/u/Sebastien_Jourdain)
#### Post date: [May 17, 2021, 7:50pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/9 "2021-05-17T19:50:04Z")

</div>

Adjust the z-index of the container that host the controller so it can go above the one that is grabbing the mouse events.

---

<div class="post-metadata">

### Author: ![Julia](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@Julia](https://discourse.vtk.org/u/Julia)
#### Post date: [May 18, 2021, 6:29am UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/10 "2021-05-18T06:29:07Z")

</div>

I did what you suggested, but unfortunately without success. This is what I did:

```auto
const controllerContainer = document.createElement('div');
controllerContainer.style.zIndex = "10";
container.appendChild(controllerContainer);

const controllerWidget = vtkVolumeController.newInstance({
     size: [300, 150],
     rescaleColorMap: true,
      expanded: true,
   });

const isBackgroundDark = background[0] + background[1] + background[2] < 1.5;
controllerWidget.setContainer(controllerContainer);
controllerWidget.setupContent(renderWindow, actor, isBackgroundDark);
controllerWidget.setSize(300, 150);
controllerWidget.render();
fpsMonitor.update();

```

I intentionally gave a large z-index in order to make sure it is higher than the window container. However this sadly does not solve the problem. Am I still doing something wrong or could there be another reason for not being able to drag those sliders? (I also have this problem with the fullscreenRenderWindow version)

---

<div class="post-metadata">

### Author: ![Sebastien\_Jourdain](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sebastien_jourdain/32/100_2.png) [@Sebastien\_Jourdain](https://discourse.vtk.org/u/Sebastien_Jourdain)
#### Post date: [May 18, 2021, 1:56pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/11 "2021-05-18T13:56:15Z")

</div>

If you had this issue with the fullscreenRenderWindow controller panel, that probably means you have something else still above your sliders. Is your page only the RW and controller? Or something else is there too?

You might need to fix the container for your RW with a smaller zindex.

---

<div class="post-metadata">

### Author: ![Julia](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@Julia](https://discourse.vtk.org/u/Julia)
#### Post date: [May 18, 2021, 2:23pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/12 "2021-05-18T14:23:29Z")

</div>

Yes the page is only the renderwindow and the controller

---

<div class="post-metadata">

### Author: ![Sebastien\_Jourdain](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sebastien_jourdain/32/100_2.png) [@Sebastien\_Jourdain](https://discourse.vtk.org/u/Sebastien_Jourdain)
#### Post date: [May 18, 2021, 2:31pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/13 "2021-05-18T14:31:52Z")

</div>

It should work (assuming you also changed the z-index of the RenderWindow container too).  
Is [the example](https://kitware.github.io/vtk-js/examples/VolumeViewer/VolumeViewer.html?fileURL=https://data.kitware.com/api/v1/item/59e12e988d777f31ac6455c5/download) working as expected on the vtk.js web site?

---

<div class="post-metadata">

### Author: ![Julia](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/j/2bfe46/32.png) [@Julia](https://discourse.vtk.org/u/Julia)
#### Post date: [May 18, 2021, 2:37pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/14 "2021-05-18T14:37:10Z")

</div>

Yes in the example the sliders work, so I guess it works as expected. It does work when I use the JavaScript obtained from the html page in the example, but not when I use the ES6 code.

---

<div class="post-metadata">

### Author: ![Sebastien\_Jourdain](https://discourse.vtk.org/user_avatar/discourse.vtk.org/sebastien_jourdain/32/100_2.png) [@Sebastien\_Jourdain](https://discourse.vtk.org/u/Sebastien_Jourdain)
#### Post date: [May 18, 2021, 3:01pm UTC](https://discourse.vtk.org/t/volume-controller-genericrenderwindow/5779/15 "2021-05-18T15:01:03Z")

</div>

The example that works for you is generated from that es6 code. You must be doing something special but it is hard to tell. It seems to be related to just JavaScript/HTML issue and not really on vtk.js.
