Tooltips on the points of a MultiColorScatterList

250 views
Skip to first unread message

Tommy D

unread,
Feb 22, 2013, 10:21:13 AM2/22/13
to jz...@googlegroups.com
Hi,

I'm using a MCSL to display in 3D the data coming from a measurement machine. What I would like to do is to display a tooltip displaying information of a point of data when the mouse is hovering on that point. What would be the simplest way to do this?

Right now I have a List of Coord3d which I use to construct a new MultiColorScatterList.
scatter exemple.png

Tommy D

unread,
Feb 26, 2013, 11:33:30 AM2/26/13
to jz...@googlegroups.com
Hello again,

I finally got my way round by rewriting the MSCL class by manipulating each data point as a AbstractDrawable and Pickable. I also extended the MousePickingController class and overridden the appropriate methods so that an event is only fired when the mouse is released.

But it seems adding a MousePickingController messes with the behavior of the other AbstractCameraController (namely CameraKeyController and CameraMouseController). I want to zoom the Z axis with the mouse wheel but now it either displace it along the Z axis or make a weird zoom like behavior. Using the Shitf + L/R arrows just displace the graphic along the Z axis. I've tried to look into that class and I just can't find where those new faulty behaviors are defined.

So I've tried this :


private void removeAddControllers() {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                synchronized (this) {
                    List<AbstractCameraController> controllerList = getControllers();

                    for (AbstractCameraController tempController : controllerList) {
                        removeController(tempController);
                    }

                    addController(new CameraKeyController());
                    addController(new CameraMouseController());
                }
            }
        });
    }
 
I've put it in a synchronized thread because I get Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException in
'for (AbstractCameraController tempController : controllerList) {'
 

Can you help me Martin?

P.S. I've bought the documentation, it should be under the name of E. Dalpé.

Tommy D

unread,
Feb 26, 2013, 11:40:16 AM2/26/13
to jz...@googlegroups.com
Found the problem, I can't iterate through a list if the list is modified. I've used this instead :

for (int i = 0; i < controllerList.size(); i++) {
            AbstractCameraController tempController = controllerList.get(i);
            removeController(tempController);
        }

Tommy D

unread,
Feb 26, 2013, 12:12:12 PM2/26/13
to jz...@googlegroups.com
Note that I still that weird zoom behavior like the scatter is moving toward the origin. This is so weird.

Martin Pernollet

unread,
Feb 26, 2013, 12:31:37 PM2/26/13
to Jzy3d
Hi,
Sorry for late reply.
If you try removing some controllers, I think you might be using ChartLauncher.openChart(). See page 7 of the guide to see how to open the chart without controller and thus to add your own without burden.
Cheers,
Martin


2013/2/26 Tommy D <fido...@gmail.com>
--
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes Jzy3d.
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse jzy3d+un...@googlegroups.com.
Pour plus d'options, visitez le site https://groups.google.com/groups/opt_out .
 
 

Tommy D

unread,
Feb 26, 2013, 1:41:08 PM2/26/13
to jz...@googlegroups.com
Thank you for the answer.

However, I am not using openChart(). What I do instead is I extend Chart into a class which manages the AbstractDrawables to display. Each times a new drawable is displayed I do this :

case SCATER :
//Code to display the current scatter drawable I created
 
ScatterPickingController<String, String> mouseController = new ScatterPickingController<String, String>(this, 5);
            mouseController.getPickingSupport().addObjectPickedListener(new IObjectPickedListener() {
                @Override
                public void objectPicked(List<? extends Object> vertices, PickingSupport picking) {
                    if (vertices.size() > 0) {
                        System.out.println("Vertex : " + vertices.get(0));
                    }
                }
            });
           
            for (DrawablePickableCoord3d tempDPC : dpcList) {
                mouseController.getPickingSupport().registerDrawableObject(tempDPC, tempDPC);
            }
//Other cases, end of switch statement
 
 List<AbstractCameraController> controllerList = getControllers();
        AbstractCameraController[] controllerArray = new AbstractCameraController[controllerList.size()];
        controllerArray = controllerList.toArray(controllerArray);
        
        for (int i = 0; i < controllerArray.length; i++) {
            AbstractCameraController tempController = controllerArray[i];

            removeController(tempController);
        }
        
        addController(new CameraKeyController());
        addController(new CameraMouseController());

Still it looks like the new controllers I add are either in conflict with the MousePickingController or are ignored.

Thx for your time.

Tommy D

unread,
Feb 26, 2013, 2:10:23 PM2/26/13
to jz...@googlegroups.com
It also appears that the removeController() method doesn't work for whatever MousePickingController is adding to the Chart.

Martin Pernollet

unread,
Feb 26, 2013, 2:26:10 PM2/26/13
to Jzy3d
Oo I misunderstood your problem.

Looking at the current implementation, the MousePickingController is zooming on X and Y only, and not on Z like does CameraMouseController. Is that your problem?

If so, override method mouseWheelMoved to let it behave like CameraMouseController

public void mouseWheelMoved(MouseWheelEvent e) {
stopThreadController();
float factor = 1 + (e.getWheelRotation()/10.0f);
zoomZ(factor);
}
 
Concerning non working controller removal, the reason is that you did not call chart.addController(picking) but simply linked the controller to the chart by giving the chart reference to the controller constructor.

I have added todos here if you want to monitor API updates: https://github.com/jzy3d/jzy3d-api/issues/9

Tommy D

unread,
Feb 26, 2013, 3:06:11 PM2/26/13
to jz...@googlegroups.com
In  ScatterPickingController<V, E> extends MousePickingController<V, E> I did what you recommended, except I've changed stopTheadController because it didn't exist :

@Override
    public void mouseWheelMoved(MouseWheelEvent e) {
        if(threadController!=null)
            threadController.stop();

       
        float factor = 1 + (e.getWheelRotation()/10.0f);
        zoomZ(factor);
    }

I've also added super.addController(mouseController); in my extended Chart when there's a scatter loaded and kept this code :

List<AbstractCameraController> controllerList = getControllers();
        AbstractCameraController[] controllerArray = new AbstractCameraController[controllerList.size()];
        controllerArray = controllerList.toArray(controllerArray);
       
        for (int i = 0; i < controllerArray.length; i++) {
            AbstractCameraController tempController = controllerArray[i];
            removeController(tempController);
        }
       
        addController(new CameraKeyController());
        addController(new CameraMouseController());/**/
 
It works when I display a new Drawable, but if I move the camera then the mousewheel event makes the chart zoom like the picture attached or shifts on the Z axis depending on some unknown factor.
wrong zoom.png

Tommy D

unread,
Feb 26, 2013, 3:12:31 PM2/26/13
to jz...@googlegroups.com
Also it looks like each time there's a new drawable, the scaling factor increases, like one mouse wheel tick makes the drawable grow (or shift) 2 times faster

Tommy D

unread,
Feb 26, 2013, 3:43:27 PM2/26/13
to jz...@googlegroups.com
I just noticed that when I click on a data point, which fire a pick event, the graphic comes to normal as it should be. Very strange.

Martin Pernollet

unread,
Feb 26, 2013, 4:23:10 PM2/26/13
to Jzy3d



2013/2/26 Tommy D <fido...@gmail.com>

In  ScatterPickingController<V, E> extends MousePickingController<V, E> I did what you recommended, except I've changed stopTheadController because it didn't exist :

Possibly added recently. Your change is OK.

 

@Override
    public void mouseWheelMoved(MouseWheelEvent e) {
        if(threadController!=null)
            threadController.stop();

       
        float factor = 1 + (e.getWheelRotation()/10.0f);
        zoomZ(factor);
    }

I've also added super.addController(mouseController); in my extended Chart when there's a scatter loaded and kept this code :


Assuming mouseController is your ScatterPickingController, that should be OK. But then you should not call the constructor referencing Chart, otherwise, the controller will register itself two times (at mousecontroller initialization, and once you call addController).

 

List<AbstractCameraController> controllerList = getControllers();
        AbstractCameraController[] controllerArray = new AbstractCameraController[controllerList.size()];
        controllerArray = controllerList.toArray(controllerArray);
       
        for (int i = 0; i < controllerArray.length; i++) {
            AbstractCameraController tempController = controllerArray[i];
            removeController(tempController);
        }


I do not understand why you try removing controllers as their should be none, see chart constructor here:
https://github.com/jzy3d/jzy3d-api/blob/master/src/api/org/jzy3d/chart/Chart.java

But clearing an empty list shouldn't cause any problem.

 
       
        addController(new CameraKeyController());
        addController(new CameraMouseController());/**/
 
It works when I display a new Drawable, but if I move the camera then the mousewheel event makes the chart zoom like the picture attached or shifts on the Z axis depending on some unknown factor.

You then have two mouse listeners listening to mouse wheel change: ScatterMousePicking (hopefully registered only one time), and CameraMouseController.
That should simply double the Z zoom, but it is still worth trying if the problem still occurs if not adding CameraMouseController and CameraKeyController.

If that does not change anything, can you show your pickable scatter implementation?

Tommy D

unread,
Feb 27, 2013, 10:31:52 AM2/27/13
to jz...@googlegroups.com
Assuming mouseController is your ScatterPickingController, that should be OK. But then you should not call the constructor referencing Chart, otherwise, the controller will register itself two times (at mousecontroller initialization, and once you call addController).
 
 Fixed, that would explain the scaling factor increasing each time a new drawable is loaded. Now the ScatterPickingController's constructor calls only chart.addController(chart);

 

List<AbstractCameraController> controllerList = getControllers();
        AbstractCameraController[] controllerArray = new AbstractCameraController[controllerList.size()];
        controllerArray = controllerList.toArray(controllerArray);
       
        for (int i = 0; i < controllerArray.length; i++) {
            AbstractCameraController tempController = controllerArray[i];
            removeController(tempController);
        }


I do not understand why you try removing controllers as their should be none, see chart constructor here:
https://github.com/jzy3d/jzy3d-api/blob/master/src/api/org/jzy3d/chart/Chart.java

But clearing an empty list shouldn't cause any problem.

I've removed that code, now there's only  addController(new CameraKeyController()); and addController(new CameraMouseController()); in my extended Chart's constructor. What I do instead is I have an ScatterPickingController attribute in my class. Each time a drawable is loaded I invoke :

if (_currentMouseController != null) {
            removeController(_currentMouseController);
            _currentMouseController.dispose();
            _currentMouseController = null;
        }

and then if my new drawable is a scatter (could also be one of three type of tessellation) then a new ScatterPickingController is instentiated.
But here's what is bothering, even after I've called removeController() and dipose() and after I've changed my type of drawable for a tessellation (thus ScatterPickingController is not reinstanciated), it still tries to pick Pickables, but I got that exception :

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:615)
    at java.util.ArrayList.get(ArrayList.java:393)
    at org.jzy3d.chart.controllers.mouse.picking.MousePickingController.pick(MousePickingController.java:105)
    at com.ibm.brmt.icos.ui.ScatterPickingController.mouseReleased(ScatterPickingController.java:51)

Also note that when in Scatter mode I have the same problems with the mousewheel functions, but when I change to tessellation then the mousewheelevent behavior works fine. This looks like a bookkeeping problem.

 
       
        addController(new CameraKeyController());
        addController(new CameraMouseController());/**/
 
It works when I display a new Drawable, but if I move the camera then the mousewheel event makes the chart zoom like the picture attached or shifts on the Z axis depending on some unknown factor.

You then have two mouse listeners listening to mouse wheel change: ScatterMousePicking (hopefully registered only one time), and CameraMouseController.
That should simply double the Z zoom, but it is still worth trying if the problem still occurs if not adding CameraMouseController and CameraKeyController.

I've tried not to add the CameraMousecontroller and the CameraKeyController and just kept the ScatterPickingController. If my mouseWheelMoved override is an empty method, then nothing happens, if I change it to


@Override
    public void mouseWheelMoved(MouseWheelEvent e) {
        if(threadController!=null)
            threadController.stop();
       
        float factor = 1 + (e.getWheelRotation()/10.0f);
        zoomZ(factor);/**/
    }

then it shifts along the z axis, instead of stretching it like the CameraMouseController would, which is weird since it is the same code.

Also, note that adding a ScatterPickingController with the two others also changes the behavior of the CameraKeyController in the same way.
 

If that does not change anything, can you show your pickable scatter implementation?
 
Sure, I've attached the relevant files. And yeah, I know that copying the entire Coord3d class is ugly, but I can't think of another solution.
 
DrawablePickableCoord3d.java
PickableRainbowScatter.java
ScatterPickingController.java

Martin Pernollet

unread,
Feb 28, 2013, 5:28:12 AM2/28/13
to Jzy3d
Hi,

Your both custom drawable do not append coordinates to the bouding box, which might explain weird sizing behaviour.

Appart of that, Coord3d is only a geometry data structure holding x, y, and z. To make a "drawable coord", look at Point class which store a coord and other drawable fields (e.g. bounding box, color, etc) + methods to be drawn, transformed, etc

The clean way to do what you want would be to use a collection of PickablePoint, and an AbstractComposite to assemble them in a single drawable. It is then up to you to override the draw method of AbstractComposite to let your points share a Colormapper. 

Once all that works, you might wish to optimize your pickable scatter to have a single boundingbox instead of one boundingbox for each point being dynamically merged by AbstractComposite on call to getBounds().

Martin

 


2013/2/27 Tommy D <fido...@gmail.com>
 

--

Tommy D

unread,
Feb 28, 2013, 11:10:21 AM2/28/13
to jz...@googlegroups.com
Thank you for the response.

I tried your first suggestion, now each time a point is made a pickable drawable I add its coordinates to its bbox, and when a Pickable scatter is created I add those bbox to the bbox of the scatter, that alone didn't really change the behavior. I've also added this code before loading a new drawable :

if (_currentMouseController != null) {
            _currentMouseController.dispose();
            removeController(_currentMouseController);
            _currentMouseController = null;
        }

It seems that .dispose() being before removeController() is important. Before that I got out of range exceptions, now it fixed a lot of problems.

Now there's still one problem remaining :  When I load a new drawable in scatter mode, the mouseWheel event works fine and the drawable stretches along the Z axis, but it seems that as soon the Chart got the focus, i.e. after click the chart without dragging the mouse, I got the wrong mousewheel event behavior again. But when i click on a point the drawable stretches itself back correctly the way it is supposed after x mousewheel ticks.

Martin Pernollet

unread,
Feb 28, 2013, 11:27:53 AM2/28/13
to Jzy3d



2013/2/28 Tommy D <fido...@gmail.com>

Thank you for the response.

I tried your first suggestion, now each time a point is made a pickable drawable I add its coordinates to its bbox, and when a Pickable scatter is created I add those bbox to the bbox of the scatter, that alone didn't really change the behavior. I've also added this code before loading a new drawable :

if (_currentMouseController != null) {
            _currentMouseController.dispose();
            removeController(_currentMouseController);
            _currentMouseController = null;
        }



What is the goal of that piece of code?


 
It seems that .dispose() being before removeController() is important. Before that I got out of range exceptions, now it fixed a lot of problems.

Now there's still one problem remaining :  When I load a new drawable in scatter mode, the mouseWheel event works fine and the drawable stretches along the Z axis, but it seems that as soon the Chart got the focus, i.e. after click the chart without dragging the mouse, I got the wrong mousewheel event behavior again. But when i click on a point the drawable stretches itself back correctly the way it is supposed after x mousewheel ticks.


What is "wrong mouseWheel behaviour"? Is that possible you provide a video or a serie of screenshots?

Tommy D

unread,
Feb 28, 2013, 1:22:49 PM2/28/13
to jz...@googlegroups.com
On Thursday, 28 February 2013 11:27:53 UTC-5, Martin wrote:



2013/2/28 Tommy D <fido...@gmail.com>
Thank you for the response.

I tried your first suggestion, now each time a point is made a pickable drawable I add its coordinates to its bbox, and when a Pickable scatter is created I add those bbox to the bbox of the scatter, that alone didn't really change the behavior. I've also added this code before loading a new drawable :

if (_currentMouseController != null) {
            _currentMouseController.dispose();
            removeController(_currentMouseController);
            _currentMouseController = null;
        }



What is the goal of that piece of code?

Before a new drawable is displayed on the Chart, this code is executed to remove any old ScatterPickingController. Without it, the ScatterPickingController are never removed and so are their picking event.
 
 

 
It seems that .dispose() being before removeController() is important. Before that I got out of range exceptions, now it fixed a lot of problems.

Now there's still one problem remaining :  When I load a new drawable in scatter mode, the mouseWheel event works fine and the drawable stretches along the Z axis, but it seems that as soon the Chart got the focus, i.e. after click the chart without dragging the mouse, I got the wrong mousewheel event behavior again. But when i click on a point the drawable stretches itself back correctly the way it is supposed after x mousewheel ticks.


What is "wrong mouseWheel behaviour"? Is that possible you provide a video or a serie of screenshots?

Sure, I attached a series of SS.
picking.zip
Reply all
Reply to author
Forward
0 new messages