Hi

I think I may of discovered a possible error in Visualization XYGraph package.  
Namely certain combination of points and axes results in an 
ArrayIndexOutOfBounds exception when the graph is drawn.

The simplest example I could find to replicate it was:


public class ErrorExample {

        public static void main(String[] args) {
                final Shell shell = new Shell();
                shell.setSize(300, 250);
            shell.open();
//use LightweightSystem to create the bridge between SWT and draw2D
                final LightweightSystem lws = new LightweightSystem(shell);
                
                //create a new XY Graph.
                XYGraph xyGraph = new XYGraph();
                xyGraph.setTitle("Error Example");
                xyGraph.primaryYAxis.setTitle("Y - axis");
                xyGraph.primaryXAxis.setTitle("X - axis");
                xyGraph.primaryYAxis.setAutoScale(false);
                xyGraph.primaryXAxis.setAutoScale(false);
                xyGraph.primaryXAxis.setShowMajorGrid(true);
                xyGraph.primaryYAxis.setShowMajorGrid(true);
                xyGraph.primaryXAxis.setRange(new Range(0.0,5.0));
                xyGraph.primaryYAxis.setRange(new Range(0.0,10.0));
                //set it as the content of LightwightSystem
                lws.setContents(xyGraph);
                
                //create a trace data provider, which will provide the data to 
the trace.
                CircularBufferDataProvider traceDataProvider = new 
CircularBufferDataProvider(false);
                traceDataProvider.setBufferSize(100);   
                traceDataProvider.addSample(new Sample(-1, 11));
                traceDataProvider.addSample(new Sample(6,4));
                
                //create the trace
Trace trace = new Trace("Trace1-XY Plot", xyGraph.primaryXAxis, xyGraph.primaryYAxis, traceDataProvider);
                
                //set trace property
                trace.setPointStyle(PointStyle.XCROSS);

                //add the trace to xyGraph
                xyGraph.addTrace(trace);
                                        
Display display = Display.getDefault();
            while (!shell.isDisposed()) {
              if (!display.readAndDispatch())
                display.sleep();
            }
}

}


When run this crashes with the following stack trace.


Exception in thread "main" org.eclipse.swt.SWTException: Failed to execute 
runnable (java.lang.ArrayIndexOutOfBoundsException: 2)
        at org.eclipse.swt.SWT.error(Unknown Source)
        at org.eclipse.swt.SWT.error(Unknown Source)
        at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Unknown Source)
        at org.eclipse.swt.widgets.Display.runAsyncMessages(Unknown Source)
        at org.eclipse.swt.widgets.Display.readAndDispatch(Unknown Source)
        at com.example.ErrorExample.main(ErrorExample.java:56)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 2
        at 
org.eclipse.nebula.visualization.xygraph.figures.Trace.getStraightLineIntersection(Trace.java:1091)
        at 
org.eclipse.nebula.visualization.xygraph.figures.Trace.getIntersection(Trace.java:1033)
        at 
org.eclipse.nebula.visualization.xygraph.figures.Trace.paintFigure(Trace.java:700)
        at org.eclipse.draw2d.Figure.paint(Figure.java:1115)
        at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1167)
        at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1202)
        at 
org.eclipse.nebula.visualization.xygraph.figures.PlotArea.paintClientArea(PlotArea.java:232)
        at org.eclipse.draw2d.Figure.paint(Figure.java:1117)
        at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1167)
        at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1202)
        at org.eclipse.draw2d.Figure.paint(Figure.java:1117)
        at org.eclipse.draw2d.Figure.paintChildren(Figure.java:1167)
        at org.eclipse.draw2d.Figure.paintClientArea(Figure.java:1202)
        at org.eclipse.draw2d.Figure.paint(Figure.java:1117)
        at 
org.eclipse.draw2d.DeferredUpdateManager.paint(DeferredUpdateManager.java:165)
        at 
org.eclipse.draw2d.LightweightSystem.paint(LightweightSystem.java:203)
        at 
org.eclipse.draw2d.LightweightSystem$2.handleEvent(LightweightSystem.java:110)
        at org.eclipse.swt.widgets.EventTable.sendEvent(Unknown Source)
        at org.eclipse.swt.widgets.Display.sendEvent(Unknown Source)
        at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
        at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
        at org.eclipse.swt.widgets.Widget.sendEvent(Unknown Source)
        at org.eclipse.swt.widgets.Control.drawWidget(Unknown Source)
        at org.eclipse.swt.widgets.Canvas.drawWidget(Unknown Source)
        at org.eclipse.swt.widgets.Widget.drawRect(Unknown Source)
        at org.eclipse.swt.widgets.Canvas.drawRect(Unknown Source)
        at org.eclipse.swt.widgets.Display.windowProc(Unknown Source)
        at org.eclipse.swt.internal.cocoa.OS.objc_msgSend(Native Method)
        at org.eclipse.swt.internal.cocoa.NSView.displayIfNeeded(Unknown Source)
        at org.eclipse.swt.widgets.Control.update(Unknown Source)
        at org.eclipse.swt.widgets.Control.update(Unknown Source)
        at 
org.eclipse.draw2d.NativeGraphicsSource.getGraphics(NativeGraphicsSource.java:48)
        at 
org.eclipse.draw2d.DeferredUpdateManager.getGraphics(DeferredUpdateManager.java:147)
        at 
org.eclipse.draw2d.DeferredUpdateManager.repairDamage(DeferredUpdateManager.java:310)
        at 
org.eclipse.draw2d.DeferredUpdateManager.performUpdate(DeferredUpdateManager.java:192)
        at 
org.eclipse.draw2d.DeferredUpdateManager$UpdateRequest.run(DeferredUpdateManager.java:44)
        at org.eclipse.swt.widgets.RunnableLock.run(Unknown Source)
        ... 4 more


From the stack trace I think the problem may be caused by the following method 
in the Trace class:


private ISample[] getStraightLineIntersection(final ISample dp1,
                        final ISample dp2) {
                final double x1 = dp1.getXValue();
                final double y1 = dp1.getYValue();
                final double x2 = dp2.getXValue();
                final double y2 = dp2.getYValue();
                final double dx = x2 - x1;
                final double dy = y2 - y1;
                final ISample[] dpTuple = new Sample[2];
                int count = 0; // number of valid dbTuple entries
                double x, y;

                if (dy != 0.0) { // Intersection with lower xAxis
                        final double ymin = yAxis.getRange().getLower();
                        x = (ymin - y1) * dx / dy + x1;
                        y = ymin;
                        if (evalDP(x, y, dp1, dp2))
                                dpTuple[count++] = new Sample(x, y);
                        // Intersection with upper xAxis
                        final double ymax = yAxis.getRange().getUpper();
                        x = (ymax - y1) * dx / dy + x1;
                        y = ymax;
                        if (evalDP(x, y, dp1, dp2))
                                dpTuple[count++] = new Sample(x, y);
                }
                // A line that runs diagonally through the plot,
                // hitting for example the lower left as well as upper right 
corners
                // would cut both X as well as both Y axes.
                // Return only the X axes hits, since Y axes hits are actually 
the
                // same points.
                if (count == 2)
                        return dpTuple;
                if (dx != 0.0) { // Intersection with left yAxis
                        final double xmin = xAxis.getRange().getLower();
                        x = xmin;
                        y = (xmin - x1) * dy / dx + y1;
                        if (evalDP(x, y, dp1, dp2))
                                dpTuple[count++] = new Sample(x, y);
                        // Intersection with right yAxis
                        final double xmax = xAxis.getRange().getUpper();
                        x = xmax;
                        y = (xmax - x1) * dy / dx + y1;
                        if (dx != 0 && evalDP(x, y, dp1, dp2))
                                dpTuple[count++] = new Sample(x, y);
                }
                return dpTuple;
        }


It seems if you get one match in the 'X Axis' block and then another two
matches in the 'Y Axis' block then the out of bounds error will be triggered.

Is there a bug out for this, I had a brief look on the bugzilla page but could 
not find any?  Do I need to raise one?

To participate in the discussion, go here: 
https://www.eclipse.org/forums/index.php?t=rview&frm_id=64
_______________________________________________
nebula-dev mailing list
[email protected]
To change your delivery options, retrieve your password, or unsubscribe from 
this list, visit
https://dev.eclipse.org/mailman/listinfo/nebula-dev

Reply via email to