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