double xscale, yscale;
void updateConversion() {
- height = getHeight() - BORDER_TOP - BORDER_BOTTOM;
- width = getWidth() - BORDER_LEFT - BORDER_RIGHT;
- if (height < 1)
- height = 1;
- if (width < 1)
- width = 1;
- xscale = (double)width / (gx1 - gx0 + 1);
- yscale = (double)height / (gy1 - gy0 + 1);
+ height = getHeight() - BORDER_TOP - BORDER_BOTTOM;
+ width = getWidth() - BORDER_LEFT - BORDER_RIGHT;
+ if (height < 1)
+ height = 1;
+ if (width < 1)
+ width = 1;
+ xscale = (double)width / (gx1 - gx0 + 1);
+ yscale = (double)height / (gy1 - gy0 + 1);
}
Graphics makeClip(Graphics g) {
- return g.create(BORDER_LEFT, BORDER_TOP, width, height);
+ return g.create(BORDER_LEFT, BORDER_TOP, width, height);
}
// Note that these do not include the border offset!
int screenX(int gx) {
- return (int)(xscale * (gx - gx0) + 0.5);
+ return (int)(xscale * (gx - gx0) + 0.5);
}
int screenY(int gy) {
- return (int)(height - yscale * (gy - gy0));
+ return (int)(height - yscale * (gy - gy0));
}
int graphX(int sx) {
- return (int)(sx / xscale + gx0 + 0.5);
+ return (int)(sx / xscale + gx0 + 0.5);
}
Graph(Window parent) {
- this.parent = parent;
- gy0 = 0; gy1 = 0xffff;
- gx0 = 0; gx1 = MIN_WIDTH << scale;
+ this.parent = parent;
+ gy0 = 0; gy1 = 0xffff;
+ gx0 = 0; gx1 = MIN_WIDTH << scale;
}
void rightDrawString(Graphics2D g, String s, int x, int y) {
- TextLayout layout =
- new TextLayout(s, parent.smallFont, g.getFontRenderContext());
- Rectangle2D bounds = layout.getBounds();
- layout.draw(g, x - (float)bounds.getWidth(), y + (float)bounds.getHeight() / 2);
+ TextLayout layout =
+ new TextLayout(s, parent.smallFont, g.getFontRenderContext());
+ Rectangle2D bounds = layout.getBounds();
+ layout.draw(g, x - (float)bounds.getWidth(), y + (float)bounds.getHeight() / 2);
}
protected void paintComponent(Graphics g) {
- Graphics2D g2d = (Graphics2D)g;
+ Graphics2D g2d = (Graphics2D)g;
- /* Repaint. Synchronize on Oscilloscope to avoid data changing.
- Simply clear panel, draw Y axis and all the mote graphs. */
- synchronized (parent.parent) {
- updateConversion();
- g2d.setColor(Color.BLACK);
- g2d.fillRect(0, 0, getWidth(), getHeight());
- drawYAxis(g2d);
+ /* Repaint. Synchronize on Oscilloscope to avoid data changing.
+ Simply clear panel, draw Y axis and all the mote graphs. */
+ synchronized (parent.parent) {
+ updateConversion();
+ g2d.setColor(Color.BLACK);
+ g2d.fillRect(0, 0, getWidth(), getHeight());
+ drawYAxis(g2d);
- Graphics clipped = makeClip(g2d);
- int count = parent.moteListModel.size();
- for (int i = 0; i < count; i++) {
- clipped.setColor(parent.moteListModel.getColor(i));
- drawGraph(clipped, parent.moteListModel.get(i));
- }
- }
+ Graphics clipped = makeClip(g2d);
+ int count = parent.moteListModel.size();
+ for (int i = 0; i < count; i++) {
+ clipped.setColor(parent.moteListModel.getColor(i));
+ drawGraph(clipped, parent.moteListModel.get(i));
+ }
+ }
}
/* Draw the Y-axis */
protected void drawYAxis(Graphics2D g) {
- int axis_x = BORDER_LEFT - 1;
- int height = getHeight() - BORDER_BOTTOM - BORDER_TOP;
-
- g.setColor(Color.WHITE);
- g.drawLine(axis_x, BORDER_TOP, axis_x, BORDER_TOP + height - 1);
-
- /* Draw a reasonable set of tick marks */
- int nTicks = height / TICK_SPACING;
- if (nTicks > MAX_TICKS)
- nTicks = MAX_TICKS;
-
- int tickInterval = (gy1 - gy0 + 1) / nTicks;
- if (tickInterval == 0)
- tickInterval = 1;
-
- /* Tick interval should be of the family A * 10^B,
- where A = 1, 2 * or 5. We tend more to rounding A up, to reduce
- rather than increase the number of ticks. */
- int B = (int)(Math.log(tickInterval) / Math.log(10));
- int A = (int)(tickInterval / Math.pow(10, B) + 0.5);
- if (A > 2) A = 5;
- else if (A > 5) A = 10;
-
- tickInterval = A * (int)Math.pow(10, B);
-
- /* Ticks are printed at multiples of tickInterval */
- int tick = ((gy0 + tickInterval - 1) / tickInterval) * tickInterval;
- while (tick <= gy1) {
- int stick = screenY(tick) + BORDER_TOP;
- rightDrawString(g, "" + tick, axis_x - TICK_WIDTH / 2 - 2, stick);
- g.drawLine(axis_x - TICK_WIDTH / 2, stick,
- axis_x - TICK_WIDTH / 2 + TICK_WIDTH, stick);
- tick += tickInterval;
- }
-
+ int axis_x = BORDER_LEFT - 1;
+ int height = getHeight() - BORDER_BOTTOM - BORDER_TOP;
+
+ g.setColor(Color.WHITE);
+ g.drawLine(axis_x, BORDER_TOP, axis_x, BORDER_TOP + height - 1);
+
+ /* Draw a reasonable set of tick marks */
+ int nTicks = height / TICK_SPACING;
+ if (nTicks > MAX_TICKS)
+ nTicks = MAX_TICKS;
+
+ int tickInterval = (gy1 - gy0 + 1) / nTicks;
+ if (tickInterval == 0)
+ tickInterval = 1;
+
+ /* Tick interval should be of the family A * 10^B,
+ where A = 1, 2 * or 5. We tend more to rounding A up, to reduce
+ rather than increase the number of ticks. */
+ int B = (int)(Math.log(tickInterval) / Math.log(10));
+ int A = (int)(tickInterval / Math.pow(10, B) + 0.5);
+ if (A > 2) A = 5;
+ else if (A > 5) A = 10;
+
+ tickInterval = A * (int)Math.pow(10, B);
+
+ /* Ticks are printed at multiples of tickInterval */
+ int tick = ((gy0 + tickInterval - 1) / tickInterval) * tickInterval;
+ while (tick <= gy1) {
+ int stick = screenY(tick) + BORDER_TOP;
+ rightDrawString(g, "" + tick, axis_x - TICK_WIDTH / 2 - 2, stick);
+ g.drawLine(axis_x - TICK_WIDTH / 2, stick,
+ axis_x - TICK_WIDTH / 2 + TICK_WIDTH, stick);
+ tick += tickInterval;
+ }
+
}
/* Draw graph for mote nodeId */
protected void drawGraph(Graphics g, int nodeId) {
- SingleGraph sg = new SingleGraph(g, nodeId);
+ SingleGraph sg = new SingleGraph(g, nodeId);
- if (gx1 - gx0 >= width) // More points than pixels-iterate by pixel
- for (int sx = 0; sx < width; sx++)
- sg.nextPoint(g, graphX(sx), sx);
- else // Less points than pixel-iterate by points
- for (int gx = gx0; gx <= gx1; gx++)
- sg.nextPoint(g, gx, screenX(gx));
+ if (gx1 - gx0 >= width) // More points than pixels-iterate by pixel
+ for (int sx = 0; sx < width; sx++)
+ sg.nextPoint(g, graphX(sx), sx);
+ else // Less points than pixel-iterate by points
+ for (int gx = gx0; gx <= gx1; gx++)
+ sg.nextPoint(g, gx, screenX(gx));
}
/* Inner class to simplify drawing a graph. Simplify initialise it, then
feed it the X screen and graph coordinates, from left to right. */
private class SingleGraph {
- int lastsx, lastsy, nodeId;
+ int lastsx, lastsy, nodeId;
- /* Start drawing the graph mote id */
- SingleGraph(Graphics g, int id) {
- nodeId = id;
- lastsx = -1;
- lastsy = -1;
- }
+ /* Start drawing the graph mote id */
+ SingleGraph(Graphics g, int id) {
+ nodeId = id;
+ lastsx = -1;
+ lastsy = -1;
+ }
- /* Next point in mote's graph is at x value gx, screen coordinate sx */
- void nextPoint(Graphics g, int gx, int sx) {
- int gy = parent.parent.data.getData(nodeId, gx);
- int sy = -1;
+ /* Next point in mote's graph is at x value gx, screen coordinate sx */
+ void nextPoint(Graphics g, int gx, int sx) {
+ int gy = parent.parent.data.getData(nodeId, gx);
+ int sy = -1;
- if (gy >= 0) { // Ignore missing values
- double rsy = height - yscale * (gy - gy0);
+ if (gy >= 0) { // Ignore missing values
+ double rsy = height - yscale * (gy - gy0);
- // Ignore problem values
- if (rsy >= -1e6 && rsy <= 1e6)
- sy = (int)(rsy + 0.5);
+ // Ignore problem values
+ if (rsy >= -1e6 && rsy <= 1e6)
+ sy = (int)(rsy + 0.5);
- if (lastsy >= 0 && sy >= 0)
- g.drawLine(lastsx, lastsy, sx, sy);
- }
- lastsx = sx;
- lastsy = sy;
- }
+ if (lastsy >= 0 && sy >= 0)
+ g.drawLine(lastsx, lastsy, sx, sy);
+ }
+ lastsx = sx;
+ lastsy = sy;
+ }
}
/* Update X-axis range in GUI */
void updateXLabel() {
- parent.xLabel.setText("X: " + gx0 + " - " + gx1);
+ parent.xLabel.setText("X: " + gx0 + " - " + gx1);
}
/* Ensure that graph is nicely positioned on screen. max is the largest
sample number received from any mote. */
private void recenter(int max) {
- // New data will show up at the 3/4 point
- // The 2nd term ensures that gx1 will be >= max
- int scrollby = ((gx1 - gx0) >> 2) + (max - gx1);
- gx0 += scrollby;
- gx1 += scrollby;
- if (gx0 < 0) { // don't bother showing negative sample numbers
- gx1 -= gx0;
- gx0 = 0;
- }
- updateXLabel();
+ // New data will show up at the 3/4 point
+ // The 2nd term ensures that gx1 will be >= max
+ int scrollby = ((gx1 - gx0) >> 2) + (max - gx1);
+ gx0 += scrollby;
+ gx1 += scrollby;
+ if (gx0 < 0) { // don't bother showing negative sample numbers
+ gx1 -= gx0;
+ gx0 = 0;
+ }
+ updateXLabel();
}
/* New data received. Redraw graph, scrolling if necessary */
void newData() {
- int max = parent.parent.data.maxX();
+ int max = parent.parent.data.maxX();
- if (max > gx1 || max < gx0) // time to scroll
- recenter(max);
- repaint();
+ if (max > gx1 || max < gx0) // time to scroll
+ recenter(max);
+ repaint();
}
/* User set the X-axis scale to newScale */
void setScale(int newScale) {
- gx1 = gx0 + (MIN_WIDTH << newScale);
- scale = newScale;
- recenter(parent.parent.data.maxX());
- repaint();
+ gx1 = gx0 + (MIN_WIDTH << newScale);
+ scale = newScale;
+ recenter(parent.parent.data.maxX());
+ repaint();
}
/* User attempted to set Y-axis range to newy0..newy1. Refuse bogus
values (return false), or accept, redraw and return true. */
boolean setYAxis(int newy0, int newy1) {
- if (newy0 >= newy1 || newy0 < 0 || newy0 > 65535 ||
- newy1 < 0 || newy1 > 65535)
- return false;
- gy0 = newy0;
- gy1 = newy1;
- repaint();
- return true;
+ if (newy0 >= newy1 || newy0 < 0 || newy0 > 65535 ||
+ newy1 < 0 || newy1 > 65535)
+ return false;
+ gy0 = newy0;
+ gy1 = newy1;
+ repaint();
+ return true;
}
}