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?