Menu

mouse clicks on plots

Help
2014-03-12
2014-03-12
  • Tamás Máhr

    Tamás Máhr - 2014-03-12

    Hi,

    What is the best way of detecting mouse-click events on plots? I would like to pop up a name that corresponds to a plot in a graph.

    I can attach a mouse listener to a GJGraph, and I iterate through the plots in the graph calling plot.intersect(e.getX(), e.getY()) on each plot, but it seems to return true even if I click to a totally different part of the graph.

    Thanks!

    Tamas

     
    • Malcolm Lidierth

      Tamas
      This behaviour calls the intersects method in the java.awt.Shape implementations so what you describe is probably expected.

      e.getX(), e.getY() specifies a 10 pixel-wide rectangle for the comparison.

      Java doc for Shape:
      "Tests if the interior of the Shape intersects the interior of a specified rectangular area. The rectangular area is considered to intersect the Shape if any point is contained in both the interior of the Shape and the specified rectangular area."

      The area of a line e.g. is defined as the area under the curve using a specified "winding rule".

      Your listener could refine that, e.g. by calculating the distance between any x,y point in the line and the e.getX(), e.getY() values.

      M

       
  • Tamás Máhr

    Tamás Máhr - 2014-03-12

    Hi,

    Thanks for the info. I did as you said, and the following code seems to work for me:

            chart.addMouseListener(new MouseAdapter() {
                private Popup popup;
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (popup != null){
                        popup.hide();
                        popup = null;
                    }
                    for (String columnName : plots.keySet()) {
                        GJPlotInterface plot = plots.get(columnName);
                        if (plot.intersects(e.getX(), e.getY())){ // this is based on Shape.intersects(), which is returns true if the click is "inside" the shape of the plot
                            ArrayList<Shape> screenDataArray = plot.getScreenDataArray();
                            for (Shape shape : screenDataArray) {
                                double[] coords = new double[6];
                                PathIterator pathIterator = shape.getPathIterator(null);
                                Point2D startPoint = null;
                                Point2D endPoint = null;
                                while (!pathIterator.isDone()){
                                    if (pathIterator.currentSegment(coords) == PathIterator.SEG_LINETO){
                                        endPoint = new Point2D.Double(coords[0], coords[1]);
    
                                        Double line = new Line2D.Double(startPoint, endPoint);
    
                                        double distance = line.ptSegDist(e.getX(), e.getY());
    
                                        if (distance < PLOT_SELECTION_PRECISION){
                                            popup  = PopupFactory.getSharedInstance().getPopup(chart, new JLabel(columnName), e.getXOnScreen(), e.getYOnScreen() - 30);
    
                                            popup.show();
                                            return;
                                        }
                                    }
    
                                    startPoint = new Point2D.Double(coords[0], coords[1]);
    
                                    pathIterator.next();
                                }
                            }
    
    
                        }
                    }
                }
            });
    

    It actually seems to work better than the logic that selects the plot in the graph. ;)

    Tamas

     

Anonymous
Anonymous

Add attachments
Cancel