package com.neuronrobotics.graphing; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.util.ArrayList; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.JTextField; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import net.miginfocom.swing.MigLayout; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.data.Range; import org.jfree.data.xy.XYSeriesCollection; public class GraphingWindow extends JPanel { private XYSeriesCollection xyDataset; private ChartPanel chartPanel; private ValueAxis axis; private JTextField length = new JTextField(5); private JSlider window = new JSlider(1, 100); private JSlider scale = new JSlider(1, 100); private ArrayList<DataChannel> dataChannels = new ArrayList<>(); /** * long */ private static final long serialVersionUID = 2171583604829088880L; public GraphingWindow() { setName("DyIO Graph"); xyDataset = new XYSeriesCollection(); JFreeChart chart = ChartFactory.createXYLineChart( "Live Data", "Time", "Value", xyDataset, PlotOrientation.VERTICAL, true, false, false); chartPanel = new ChartPanel(chart); XYPlot plot = (XYPlot) chart.getPlot(); axis = plot.getDomainAxis(); scale.setValue(100); setDefaultWindow(); scale.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { if(window.getValue() ==100) { setDefaultWindow(); }else { setMovedWindow(window.getValue()); } } }); window.setValue(100); window.addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { if(window.getValue() ==100) { setDefaultWindow(); }else { setMovedWindow(window.getValue()); } } }); length.addKeyListener(new KeyListener() { public void keyTyped(KeyEvent e) { if(e.getKeyChar() != '\n' && (e.getKeyChar() < '0' || e.getKeyChar() > '9')) { e.consume(); } } public void keyReleased(KeyEvent e) { } public void keyPressed(KeyEvent e) { } }); length.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { int value; try { value = Integer.parseInt(length.getText()); } catch(Exception e) { value = scale.getMaximum(); } axis.setFixedAutoRange(value); length.setText(String.valueOf(value)); scale.setValue(value); invalidate(); repaint(); } }); JButton clearBtn = new JButton("Clear Data"); clearBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { for(DataChannel dc : dataChannels) { dc.clear(); } } }); JPanel options = new JPanel(new MigLayout()); options.add(new JLabel("Range Size:")); options.add(scale); options.add(length); options.add(new JLabel("seconds")); options.add(clearBtn, "east"); setLayout(new BorderLayout()); setSize(new Dimension(500, 400)); add(chartPanel, BorderLayout.CENTER); add(options, BorderLayout.SOUTH); JPanel opt= new JPanel(new MigLayout()); opt.add(new JLabel("View Window")); opt.add(window); JPanel slidingWindow= new JPanel(new MigLayout()); slidingWindow.add(options, "wrap"); slidingWindow.add(opt, "wrap"); add(slidingWindow, BorderLayout.SOUTH); } private void setDefaultWindow() { axis.setAutoRange(true); axis.setFixedAutoRange(scale.getValue()); length.setText(String.valueOf(scale.getValue())); //invalidate(); repaint(); } private void setMovedWindow(double percent) { axis.setAutoRange(false); Range total = xyDataset.getDomainBounds(true); double lower =total.getLowerBound(); double upper =total.getUpperBound(); double loc = (upper -lower)*percent/100; double sLower =loc-(scale.getValue()/2); double sUpper =loc+(scale.getValue()/2); axis.setRange(sLower, sUpper); length.setText(String.valueOf(scale.getValue())); //invalidate(); //repaint(); } public void addDataset(DataChannel data) { if(!dataChannels.contains(data)) { dataChannels.add(data); } if(!(xyDataset.indexOf(data.getSeries()) > -1)) { showDataChannel(data); } } public void removeDataset(DataChannel data) { if(!dataChannels.contains(data)) { dataChannels.add(data); } if(xyDataset.indexOf(data.getSeries()) > -1) { hideDataChannel(data); } } public void hideDataChannel(DataChannel data) { xyDataset.removeSeries(data.getSeries()); } public void showDataChannel(DataChannel data) { xyDataset.addSeries(data.getSeries()); } }