📄 graphpanel.java
字号:
/* * "Copyright (c) 2001 and The Regents of the University * of California. All rights reserved. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without written agreement is * hereby granted, provided that the above copyright notice and the following * two paragraphs appear in all copies of this software. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." * * $\Id$ *//** * File: GraphPanel.java * * Description: * Displays data coming from the apps/oscilloscope application. * * Requires that the SerialForwarder is already started. * * @author Jason Hill and Eric Heien */package net.tinyos.oscilloscope;import net.tinyos.util.*;import java.io.*;
import java.util.*;
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.sql.Time;
class V2 extends Vector{
void chop(int number){
removeRange(0, number);
}
}
class Point2D { double x, y; Point2D( double newX, double newY ) { x = newX; y = newY; } double getX() { return x; } double getY() { return y; } public String toString() { return x+", "+y; }}
public class GraphPanel extends Panel
implements Runnable, MouseListener, MouseMotionListener, PacketListenerIF {
//set the number of channels to display and the number of readings
// per packet. 2 channels and 4 reading means 2 readings per packet
// per channel.
int num_channels = 10;
int num_readings = 10;
boolean debug = false;
boolean sliding = false;
boolean legend = true;
boolean connectPoints = true;
boolean valueTest = false;
int testChannel = -1,valueX,valueY;
oscilloscope graph;
//output stream for logging the data to.
PrintWriter os;
double bottom, top;
int start, end;
V2 cutoff;
V2 data[];
String dataLegend[];
boolean legendActive[];
Color plotColors[];
int moteNum[]; // Maps channel # to mote # int streamNum[]; // Maps channel # to mote stream # int lastPacketNum[]; // Last packet # for channel double xScaling=200, yScaling=75;
Point highlight_start, highlight_end;
GraphPanel(oscilloscope graph) {
setBackground(Color.white);
addMouseListener(this);
addMouseMotionListener(this);
cutoff = new V2();
//create an array to hold the data sets.
data = new V2[num_channels];
for(int i = 0; i < num_channels; i ++) data[i] = new V2();
dataLegend = new String[num_channels];
legendActive = new boolean[num_channels];
lastPacketNum = new int[num_channels];
for( int i=0;i<num_channels;i++ ) lastPacketNum[i] = -1; streamNum = new int[num_channels];
for( int i=0;i<num_channels;i++ ) streamNum[i] = -1; moteNum = new int[num_channels];
for( int i=0;i<num_channels;i++ ) moteNum[i] = -1; plotColors = new Color[num_channels];
for( int i=0;i<num_channels;i++ ) dataLegend[i] = ""; dataLegend[0] = "Light";
for( int i=0;i<num_channels;i++ ) legendActive[i] = false;
for( int i=0;i<1;i++ ) legendActive[i] = true;
plotColors[0] = Color.green;
plotColors[1] = Color.red;
plotColors[2] = Color.blue;
plotColors[3] = Color.magenta;
plotColors[4] = Color.orange;
plotColors[5] = Color.yellow;
plotColors[6] = Color.cyan;
plotColors[7] = Color.pink;
plotColors[8] = Color.green;
plotColors[9] = Color.white;
try{
//create a file for logging data to.
FileOutputStream f = new FileOutputStream("log");
os = new PrintWriter(f);
}catch(Exception e){
e.printStackTrace();
}
this.graph = graph;
bottom = 00;
top = 1024.00;
start = -400; end = 5000;
Thread t = new Thread(this);
t.start();
}
int big_filter;
int sm_filter;
int db_filter;
void add_point(Point2D val, int place){
if(place >= data.length) return;
data[place].add(val);
if(val != null && sliding && ((val.getX() > (end - 20)) || (val.getX() < start)) && place == 0) {
int diff = end - start; end = (int)val.getX() + 20; start = end - diff;
}
int max_length = 0x3fff; for(int i = 0; i < num_channels; i ++){
//if(data[i].size() > max_length & start > 2000) {
if(data[i].size() > max_length) {
synchronized(data[i]){data[i].chop(max_length/10);
}
}
}
if( val != null ) os.println(""+val.toString() + ", " + place);
repaint(100);
}
void read_data(){
int counter = 0; try{
FileInputStream fin = new FileInputStream("data");
byte[] readings = new byte[7];
int cnt = 0;
while(fin.read(readings) == 7){
String s = new String(readings);
add_point(new Point2D(counter,new Double(s).doubleValue()), 0);
counter++; }
}catch(Exception e){
}
/* try{ for(counter = 1; counter > 0;counter ++){ for(int j = 0; j < 3000000; j ++){
add_point(new Point2D(j & 0xffff , 750*Math.sin((float)j/190)), 0); Thread.sleep( 1); }
}}catch(Exception e){}*/ }
public void packetReceived(byte[] readings){
int moteID, msgType, packetNum, channelID, val, channel=-1, i; int defaultMsgType = 10; boolean foundPlot = false; if(check_crc(readings) == false) return; for( i=0;i<readings.length;i++ ) System.out.print( readings[i]+" " ); System.out.println( "" ); //process the packet // Read mote id, channel number here, turn on corresponding graph if necessary moteID = readings[5] << 8; moteID |= readings[4] & 0x0ff; msgType = readings[2]; if( msgType != defaultMsgType ) { System.out.println( "Ignoring packet of msgType "+msgType ); return; } packetNum = (readings[7] << 8) & 0xff00; packetNum |= readings[6] & 0x0ff; channelID = readings[9] << 8; channelID |= readings[8] & 0x0ff; for( i=0;i<num_channels;i++ ) { if( moteNum[i] == moteID && streamNum[i] == channelID ) { foundPlot = true; legendActive[i] = true; channel = i; i = num_channels+1; } } if( !foundPlot ) { for( i=0;i<num_channels&&moteNum[i]!=-1;i++ ); channel = i; moteNum[i] = moteID; streamNum[i] = channelID; lastPacketNum[i] = packetNum; legendActive[i] = true; dataLegend[i] = "Mote "+moteID+" Chan "+channelID; } if( channel < 0 ) { System.out.println( "All data streams full. Please clear data set." ); return; } if( lastPacketNum[channel] == -1 ) lastPacketNum[channel] = packetNum; for( ;lastPacketNum[channel] > packetNum;packetNum++ ) for( i=0;i<num_readings;i++ ) // Add 10 blank points for each lost packet add_point(null, channel); for( i = 10; i < 10+num_readings * 2;i +=2){ Point2D newPoint; val = readings[i + 1] << 8; val |= readings[i] & 0x0ff; // Convert endian //System.out.println( "Read "+val ); //System.out.println( "xVal "+packetNum ); newPoint = new Point2D( ((double)(packetNum+(i/2)-10)), val ); //System.out.println( newPoint ); add_point( newPoint, channel); } } public void run() { read_data();
SerialForwarderStub r = new SerialForwarderStub("127.0.0.1", 9000);
try{
r.Open();
r.registerPacketListener(this);
r.Read();
}catch(Exception e){
e.printStackTrace();
}
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseDragged(MouseEvent e) {
Dimension d = getSize();
if( valueTest ) {
valueX = (int)(start+((float)end-(float)start)*(((float)e.getX())/((float)d.width)));
if( valueX < 0 ) valueX = 0;
if( valueX >= data[testChannel].size() ) valueX = data[testChannel].size()-1; valueY = (int)((Point2D)data[testChannel].get( valueX )).getY();
} else if( highlight_start != null ) {
highlight_end.x = e.getX();
highlight_end.y = e.getY();
}
repaint(100);
e.consume();
}
public void mouseMoved(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
removeMouseMotionListener(this);
if( highlight_start != null )
set_zoom();
valueTest = false;
testChannel = -1;
highlight_start = null;
highlight_end = null;
e.consume();
repaint(100);
}
public void mousePressed(MouseEvent e) {
addMouseMotionListener(this);
// Check to see if mouse clicked near plot
Dimension d = getSize();
double xVal,yVal;
xVal = start+((float)end-(float)start)*(((float)e.getX())/((float)d.width));
yVal = top+(bottom-top)*(((float)e.getY())/((float)d.height));
// System.out.println( xVal+" "+yVal );
for( int i=0;i<num_channels;i++ ) {
if( !(xVal < 0 || (int)xVal > data[i].size()) ) {
if( Math.abs( ((Point2D)data[i].get( (int)xVal )).getY() - yVal ) < (top-bottom)/40 ) {
valueTest = true;
testChannel = i;
valueX = (int)xVal;
valueY = (int)((Point2D)data[i].get( valueX )).getY();
}
}
}
if( !valueTest ) {
highlight_start = new Point();
highlight_end = new Point();
highlight_start.x = e.getX();
highlight_start.y = e.getY();
highlight_end.x = e.getX();
highlight_end.y = e.getY();
}
repaint(100);
e.consume();
}
public void start() {
}
public void stop() {
}
//double buffer the graphics.
Image offscreen;
Dimension offscreensize;
Graphics offgraphics;
public synchronized void update(Graphics g) {
//get the size of the window.
Dimension d = getSize();
//get the end value o fthe window.
int end = this.end;
graph.time_location.setMaximum(Math.max(end, data[0].size()));
graph.time_location.setValue(end);
//create the offscreen image if necessary (only done once)
if ((offscreen == null) || (d.width != offscreensize.width) || (d.height != offscreensize.height)) {
offscreen = createImage(d.width, d.height);
offscreensize = d;
if (offgraphics != null) {
offgraphics.dispose();
}
offgraphics = offscreen.getGraphics();
offgraphics.setFont(getFont());
}
//blank the screen.
offgraphics.setColor(Color.black);
offgraphics.fillRect(0, 0, d.width, d.height);
// Draw axes
int xPos,yPos,i,numLines=100,xOff=0,yOff=0; double xTicSpacing=d.width/25.03,yTicSpacing=d.height/13.7; // change #s? Color xColor,yColor;
xColor = Color.white;
yColor = Color.white;
xPos = d.width*start/(start-end);
yPos = (int)(((float)(d.height*top))/((float)(top-bottom)));
if( xPos < 30 ) {
//xPos = 30;
while( xPos < 30 ) { xPos += xTicSpacing;
xOff++; }
yColor = yColor.darker();
}
if( yPos < 30 ) {
//yPos = 30;
while( yPos < 30 ) { yPos += yTicSpacing;
yOff++; }
xColor = xColor.darker();
}
if( xPos > d.width-30 ) {
//xPos = d.width-30;
while( xPos > d.width-30 ) { xPos -= xTicSpacing;
xOff--; }
yColor = yColor.darker();
}
if( yPos > d.height-30 ) {
//yPos = d.height-30;
while( yPos > d.height-30 ) { yPos -= yTicSpacing;
yOff--; }
xColor = xColor.darker();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -