📄 stripchart.java
字号:
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* StripChart.java
* Copyright (C) 2002 Mark Hall
*
*/
package weka.gui.beans;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.Random;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;
import weka.core.Instance;
import weka.core.Instances;
/**
* Bean that can display a horizontally scrolling strip chart. Can
* display multiple plots simultaneously
*
* @author <a href="mailto:mhall@cs.waikato.ac.nz">Mark Hall</a>
* @version $Revision$
*/
public class StripChart
extends JPanel
implements ChartListener, InstanceListener, Visible,
BeanCommon, UserRequestAcceptor,
Serializable {
/** default colours for colouring lines */
protected Color [] m_colorList = {Color.green,
Color.red,
Color.blue,
Color.cyan,
Color.pink,
new Color(255, 0, 255),
Color.orange,
new Color(255, 0, 0),
new Color(0, 255, 0),
Color.white};
// Class providing a panel for the plot
private class StripPlotter extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (m_osi != null) {
g.drawImage(m_osi,0,0,this);
}
}
}
private transient JFrame m_outputFrame = null;
private transient StripPlotter m_plotPanel = null;
/**
* The off screen image for rendering to
*/
private transient Image m_osi = null;
/**
* Width and height of the off screen image
*/
private int m_iheight;
private int m_iwidth;
/**
* Max value for the y axis
*/
private double m_max = 1;
/**
* Min value for the y axis
*/
private double m_min = 0;
/**
* Scale update requested
*/
private boolean m_yScaleUpdate = false;
private double m_oldMax;
private double m_oldMin;
private Font m_labelFont = new Font("Monospaced", Font.PLAIN, 10);
private FontMetrics m_labelMetrics;
// private int m_plotCount = 0;
private Vector m_legendText = new Vector();
/**
* Class providing a panel for displaying the y axis
*/
private JPanel m_scalePanel = new JPanel() {
public void paintComponent(Graphics gx) {
super.paintComponent(gx);
if (m_labelMetrics == null) {
m_labelMetrics = gx.getFontMetrics(m_labelFont);
}
gx.setFont(m_labelFont);
int hf = m_labelMetrics.getAscent();
String temp = ""+m_max;
gx.setColor(m_colorList[m_colorList.length-1]);
gx.drawString(temp, 1, hf-2);
temp = ""+(m_min + ((m_max - m_min)/2.0));
gx.drawString(temp, 1, (this.getHeight() / 2)+(hf / 2));
temp = ""+m_min;
gx.drawString(temp, 1, this.getHeight()-1);
}
};
/**
* Class providing a panel for the legend
*/
private JPanel m_legendPanel = new JPanel() {
public void paintComponent(Graphics gx) {
super.paintComponent(gx);
if (m_labelMetrics == null) {
m_labelMetrics = gx.getFontMetrics(m_labelFont);
}
int hf = m_labelMetrics.getAscent();
int x = 10; int y = hf+15;
gx.setFont(m_labelFont);
for (int i = 0; i < m_legendText.size(); i++) {
String temp = (String)m_legendText.elementAt(i);
gx.setColor(m_colorList[(i % m_colorList.length)]);
gx.drawString(temp,x,y);
y+=hf;
}
StripChart.this.revalidate();
}
};
/**
* Holds the data to be plotted. Entries in the list are arrays of
* y points.
*/
private LinkedList m_dataList = new LinkedList();
// private double [] m_dataPoint = new double[1];
private double [] m_previousY = new double[1];
private transient Thread m_updateHandler;
protected BeanVisual m_visual =
new BeanVisual("StripChart",
BeanVisual.ICON_PATH+"StripChart.gif",
BeanVisual.ICON_PATH+"StripChart_animated.gif");
private Object m_listenee = null;
private transient weka.gui.Logger m_log = null;
/**
* Print x axis labels every m_xValFreq points
*/
private int m_xValFreq = 500;
private int m_xCount = 0;
/**
* Shift the plot by this many pixels every time a point is plotted
*/
private int m_refreshWidth = 1;
/**
* Plot every m_refreshFrequency'th point
*/
private int m_refreshFrequency = 5;
public StripChart() {
// m_plotPanel.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
setLayout(new BorderLayout());
add(m_visual, BorderLayout.CENTER);
// start a thread to handle plot updates
initPlot();
}
/**
* Global info for this bean
*
* @return a <code>String</code> value
*/
public String globalInfo() {
return "Visualize incremental classifier performance as a scrolling plot.";
}
/**
* GUI Tip text
*
* @return a <code>String</code> value
*/
public String xLabelFreqTipText() {
return "Show x axis labels this often";
}
/**
* Set the frequency for printing x label values
*
* @param freq an <code>int</code> value
*/
public void setXLabelFreq(int freq) {
m_xValFreq = freq;
setRefreshWidth();
}
/**
* Get the frequency by which x axis values are printed
*
* @return an <code>int</code> value
*/
public int getXLabelFreq() {
return m_xValFreq;
}
/**
* GUI Tip text
*
* @return a <code>String</code> value
*/
public String refreshFreqTipText() {
return "Plot every x'th data point";
}
/**
* Set how often (in x axis points) to refresh the display
*
* @param freq an <code>int</code> value
*/
public void setRefreshFreq(int freq) {
m_refreshFrequency = freq;
setRefreshWidth();
}
/**
* Get the refresh frequency
*
* @return an <code>int</code> value
*/
public int getRefreshFreq() {
return m_refreshFrequency;
}
private void setRefreshWidth() {
m_refreshWidth = 1;
if (m_labelMetrics == null) {
getGraphics().setFont(m_labelFont);
m_labelMetrics = getGraphics().getFontMetrics(m_labelFont);
}
int refWidth = m_labelMetrics.stringWidth("99000");
// compute how often x label will be rendered
int z = (getXLabelFreq() / getRefreshFreq());
if (z < 1) {
z = 1;
}
if (z * m_refreshWidth < refWidth+5) {
m_refreshWidth *= (((refWidth+5) / z) + 1) ;
}
}
/**
* Provide some necessary initialization after object has
* been deserialized.
*
* @param ois an <code>ObjectInputStream</code> value
* @exception IOException if an error occurs
* @exception ClassNotFoundException if an error occurs
*/
private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
try {
ois.defaultReadObject();
initPlot();
// startHandler();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void initPlot() {
m_plotPanel = new StripPlotter();
m_plotPanel.setBackground(Color.black);
m_scalePanel.setBackground(Color.black);
m_legendPanel.setBackground(Color.black);
m_xCount = 0;
}
private void startHandler() {
if (m_updateHandler == null) {
m_updateHandler = new Thread() {
private double [] dataPoint;
public void run() {
while (true) {
if (m_outputFrame != null) {
synchronized(m_dataList) {
while(m_dataList.isEmpty()) {
// while (m_dataList.empty()) {
try {
m_dataList.wait();
} catch (InterruptedException ex) {
return;
}
}
dataPoint = (double [])m_dataList.remove(0);
//dataPoint = (double [])m_dataList.pop();
}
if (m_outputFrame != null) {
StripChart.this.updateChart(dataPoint);
}
}
}
}
};
// m_updateHandler.setPriority(Thread.MIN_PRIORITY);
m_updateHandler.start();
}
}
/**
* Popup the chart panel
*/
public void showChart() {
if (m_outputFrame == null) {
m_outputFrame = new JFrame("Strip Chart");
m_outputFrame.getContentPane().setLayout(new BorderLayout());
m_outputFrame.getContentPane().add(m_legendPanel, BorderLayout.WEST);
m_outputFrame.getContentPane().add(m_plotPanel, BorderLayout.CENTER);
m_outputFrame.getContentPane().add(m_scalePanel, BorderLayout.EAST);
m_legendPanel.setMinimumSize(new Dimension(100,getHeight()));
m_legendPanel.setPreferredSize(new Dimension(100,getHeight()));
m_scalePanel.setMinimumSize(new Dimension(30, getHeight()));
m_scalePanel.setPreferredSize(new Dimension(30, getHeight()));
Font lf = new Font("Monospaced", Font.PLAIN, 12);
m_legendPanel.setBorder(BorderFactory.
createTitledBorder(BorderFactory.
createEtchedBorder(Color.gray,
Color.darkGray),
"Legend" ,
TitledBorder.CENTER,
TitledBorder.DEFAULT_POSITION, lf,
Color.blue));
m_outputFrame.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
if (m_updateHandler != null) {
System.err.println("Interrupting");
m_updateHandler.interrupt();
m_updateHandler = null;
}
synchronized (m_dataList) {
m_dataList = new LinkedList();
}
m_outputFrame.dispose();
m_outputFrame = null;
}
});
m_outputFrame.pack();
m_outputFrame.setSize(600,150);
m_outputFrame.setResizable(false);
m_outputFrame.setVisible(true);
int iwidth = m_plotPanel.getWidth();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -