net.liuxuan.device.w3330.JIF_DrawChart_w3330.java Source code

Java tutorial

Introduction

Here is the source code for net.liuxuan.device.w3330.JIF_DrawChart_w3330.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package net.liuxuan.device.w3330;

import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import com.google.common.io.Files;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileSystemView;
import net.liuxuan.UI.component.ExtensionFileFilter;
import net.liuxuan.device.Fluke45.utils.Fluke45Chart;
import org.apache.commons.math3.filter.DefaultMeasurementModel;
import org.apache.commons.math3.filter.DefaultProcessModel;
import org.apache.commons.math3.filter.KalmanFilter;
import org.apache.commons.math3.filter.MeasurementModel;
import org.apache.commons.math3.filter.ProcessModel;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.ArrayRealVector;
import org.apache.commons.math3.linear.RealMatrix;
import org.apache.commons.math3.linear.RealVector;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.Marker;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.TimeSeriesDataItem;
import org.jfree.ui.Layer;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.TextAnchor;

/**
 *
 * @author Moses
 */
public class JIF_DrawChart_w3330 extends net.liuxuan.UI.JIFUI {

    private static JIF_DrawChart_w3330 myInstance; //thisJFrame singleton

    public static JIF_DrawChart_w3330 getInstance(net.liuxuan.UI.DataHolder.DataHolder _datas) {
        if (myInstance == null) {
            myInstance = new JIF_DrawChart_w3330();
        }
        myInstance.datas = _datas;
        return myInstance;
    }

    TimeSeriesCollection trcollection;
    TimeSeriesCollection trcollection2;
    TimeSeries ts_wppm;
    TimeSeries ts_wppm_zero;
    TimeSeries ts_flux;
    TimeSeries ts_wvtr;
    TimeSeries ts_tempcell;
    TimeSeries ts_tempambi;
    TimeSeries ts_status;
    TimeSeries ts_fitting;
    TimeSeries ts_fitting2;
    //    ArrayList<Double> fittingdata = new ArrayList<Double>();
    //    ArrayList<Long> times = new ArrayList<Long>();

    ArrayList<W3330MetaData> metadatas = new ArrayList<W3330MetaData>();

    int dropinterval = 30;//??? 

    double[] filterds = new double[10];
    int filterpoint = 0;
    //    XYSeries xyseries = new XYSeries("Random Data");
    //    XYSeriesCollection xyseriesCollection1 = new XYSeriesCollection(xyseries);
    ChartPanel chartPanel;

    /**
     * Creates new form JIF_DrawChart
     */
    private JIF_DrawChart_w3330() {
        initComponents();
        //        init();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel_Show = new javax.swing.JPanel();
        jPanel_Control = new javax.swing.JPanel();
        jButtonOpen = new javax.swing.JButton();
        jCheckBox_wppm = new javax.swing.JCheckBox();
        jCheckBox_wppmZero = new javax.swing.JCheckBox();
        jCheckBox_wvtr = new javax.swing.JCheckBox();
        jCheckBox_flux = new javax.swing.JCheckBox();
        jCheckBox_celltemp = new javax.swing.JCheckBox();
        jCheckBox_ambitemp = new javax.swing.JCheckBox();
        jCheckBox_status = new javax.swing.JCheckBox();
        jFormattedTextField_temp = new javax.swing.JFormattedTextField();
        jCheckBox_fitting = new javax.swing.JCheckBox();
        jCheckBox_fitting2 = new javax.swing.JCheckBox();

        setClosable(true);
        setIconifiable(true);
        setMaximizable(true);
        setResizable(true);

        org.jdesktop.layout.GroupLayout jPanel_ShowLayout = new org.jdesktop.layout.GroupLayout(jPanel_Show);
        jPanel_Show.setLayout(jPanel_ShowLayout);
        jPanel_ShowLayout.setHorizontalGroup(jPanel_ShowLayout
                .createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING).add(0, 884, Short.MAX_VALUE));
        jPanel_ShowLayout.setVerticalGroup(jPanel_ShowLayout
                .createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING).add(0, 520, Short.MAX_VALUE));

        jPanel_Control.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        jButtonOpen.setText("");
        jButtonOpen.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonOpenActionPerformed(evt);
            }
        });

        jCheckBox_wppm.setSelected(true);
        jCheckBox_wppm.setText("Wppm");
        jCheckBox_wppm.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox_wppmActionPerformed(evt);
            }
        });

        jCheckBox_wppmZero.setSelected(true);
        jCheckBox_wppmZero.setText("Wppm-Zero");
        jCheckBox_wppmZero.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox_wppmZeroActionPerformed(evt);
            }
        });

        jCheckBox_wvtr.setSelected(true);
        jCheckBox_wvtr.setText("wvtr");
        jCheckBox_wvtr.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox_wvtrActionPerformed(evt);
            }
        });

        jCheckBox_flux.setSelected(true);
        jCheckBox_flux.setText("flux");
        jCheckBox_flux.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox_fluxActionPerformed(evt);
            }
        });

        jCheckBox_celltemp.setSelected(true);
        jCheckBox_celltemp.setText("cell temp.");
        jCheckBox_celltemp.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox_celltempActionPerformed(evt);
            }
        });

        jCheckBox_ambitemp.setSelected(true);
        jCheckBox_ambitemp.setText("ambi.temp.");
        jCheckBox_ambitemp.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox_ambitempActionPerformed(evt);
            }
        });

        jCheckBox_status.setSelected(true);
        jCheckBox_status.setText("status");
        jCheckBox_status.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox_statusActionPerformed(evt);
            }
        });

        jFormattedTextField_temp.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(
                new javax.swing.text.NumberFormatter(java.text.NumberFormat.getIntegerInstance())));
        jFormattedTextField_temp.setText("30");

        jCheckBox_fitting.setSelected(true);
        jCheckBox_fitting.setText("fitting");
        jCheckBox_fitting.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox_fittingActionPerformed(evt);
            }
        });

        jCheckBox_fitting2.setSelected(true);
        jCheckBox_fitting2.setText("fitting2");
        jCheckBox_fitting2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jCheckBox_fitting2ActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout jPanel_ControlLayout = new org.jdesktop.layout.GroupLayout(jPanel_Control);
        jPanel_Control.setLayout(jPanel_ControlLayout);
        jPanel_ControlLayout.setHorizontalGroup(jPanel_ControlLayout
                .createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                .add(jPanel_ControlLayout.createSequentialGroup().addContainerGap().add(jButtonOpen).add(18, 18, 18)
                        .add(jCheckBox_wppm).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jCheckBox_wppmZero).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jCheckBox_wvtr).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jCheckBox_flux).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jCheckBox_celltemp).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jCheckBox_ambitemp).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jCheckBox_status).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jCheckBox_fitting).addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(jCheckBox_fitting2).add(29, 29, 29)
                        .add(jFormattedTextField_temp, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 42,
                                org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                        .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)));
        jPanel_ControlLayout
                .setVerticalGroup(jPanel_ControlLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                        .add(jPanel_ControlLayout.createSequentialGroup().addContainerGap().add(jPanel_ControlLayout
                                .createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE).add(jButtonOpen)
                                .add(jCheckBox_wppm).add(jCheckBox_wppmZero).add(jCheckBox_wvtr).add(jCheckBox_flux)
                                .add(jCheckBox_celltemp).add(jCheckBox_ambitemp).add(jCheckBox_status)
                                .add(jFormattedTextField_temp, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
                                        org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
                                        org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                                .add(jCheckBox_fitting).add(jCheckBox_fitting2))
                                .addContainerGap(14, Short.MAX_VALUE)));

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel_Control,
                        org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
                        Short.MAX_VALUE)
                .add(jPanel_Show, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
                        org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE));
        layout.setVerticalGroup(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                .add(layout.createSequentialGroup()
                        .add(jPanel_Show, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
                                org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED).add(jPanel_Control,
                                org.jdesktop.layout.GroupLayout.PREFERRED_SIZE,
                                org.jdesktop.layout.GroupLayout.DEFAULT_SIZE,
                                org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)));

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonOpenActionPerformed
        openFiletoCurve();
    }//GEN-LAST:event_jButtonOpenActionPerformed

    private void jCheckBox_wppmActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox_wppmActionPerformed
        if (jCheckBox_wppm.isSelected()) {
            trcollection.addSeries(ts_wppm);
        } else {
            trcollection.removeSeries(ts_wppm);
        }
    }//GEN-LAST:event_jCheckBox_wppmActionPerformed

    private void jCheckBox_wppmZeroActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox_wppmZeroActionPerformed
        if (jCheckBox_wppmZero.isSelected()) {
            trcollection.addSeries(ts_wppm_zero);
        } else {
            trcollection.removeSeries(ts_wppm_zero);
        }
    }//GEN-LAST:event_jCheckBox_wppmZeroActionPerformed

    private void jCheckBox_wvtrActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox_wvtrActionPerformed
        if (jCheckBox_wvtr.isSelected()) {
            trcollection.addSeries(ts_wvtr);
        } else {
            trcollection.removeSeries(ts_wvtr);
        }
    }//GEN-LAST:event_jCheckBox_wvtrActionPerformed

    private void jCheckBox_fluxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox_fluxActionPerformed
        if (jCheckBox_flux.isSelected()) {
            trcollection2.addSeries(ts_flux);
        } else {
            trcollection2.removeSeries(ts_flux);
        }
    }//GEN-LAST:event_jCheckBox_fluxActionPerformed

    private void jCheckBox_celltempActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox_celltempActionPerformed
        if (jCheckBox_celltemp.isSelected()) {
            trcollection2.addSeries(ts_tempcell);
        } else {
            trcollection2.removeSeries(ts_tempcell);
        }
    }//GEN-LAST:event_jCheckBox_celltempActionPerformed

    private void jCheckBox_ambitempActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox_ambitempActionPerformed
        if (jCheckBox_ambitemp.isSelected()) {
            trcollection2.addSeries(ts_tempambi);
        } else {
            trcollection2.removeSeries(ts_tempambi);
        }
    }//GEN-LAST:event_jCheckBox_ambitempActionPerformed

    private void jCheckBox_statusActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox_statusActionPerformed
        if (jCheckBox_status.isSelected()) {
            trcollection2.addSeries(ts_status);
        } else {
            trcollection2.removeSeries(ts_status);
        }
    }//GEN-LAST:event_jCheckBox_statusActionPerformed

    private void jCheckBox_fittingActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox_fittingActionPerformed
        if (jCheckBox_fitting.isSelected()) {
            trcollection2.addSeries(ts_fitting);
        } else {
            trcollection2.removeSeries(ts_fitting);
        }
    }//GEN-LAST:event_jCheckBox_fittingActionPerformed

    private void jCheckBox_fitting2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jCheckBox_fitting2ActionPerformed
        if (jCheckBox_fitting2.isSelected()) {
            trcollection.addSeries(ts_fitting2);
        } else {
            trcollection.removeSeries(ts_fitting2);
        }
    }//GEN-LAST:event_jCheckBox_fitting2ActionPerformed

    public void openFiletoCurve() throws NumberFormatException {
        String tempstr = jFormattedTextField_temp.getText();
        int tempint = Integer.parseInt(tempstr);
        dropinterval = tempint;

        //??
        //??0?1
        double oldzero = -1000;
        long oldzerotime = -1;
        double oldstatus = -1;

        filterds = new double[dropinterval];
        SimpleDateFormat sdfx = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]");
        //        String content;
        List<String> fileContentStringList = null;

        JFileChooser jfc = initFileChooser();

        //?lastpath
        String latestPath = (String) datas.get("lastpath");

        File currentDir = null;
        FileSystemView fsv = FileSystemView.getFileSystemView();
        if (latestPath == null) {
            //?
            currentDir = fsv.getHomeDirectory();
        } else {
            currentDir = new File(latestPath);
            if (currentDir.exists() && currentDir.isDirectory()) {
            } else {
                currentDir = fsv.getHomeDirectory();
            }
        }
        jfc.setCurrentDirectory(currentDir);

        int result = jfc.showOpenDialog(this); // ""?
        if (result == JFileChooser.APPROVE_OPTION) {
            //            String filepath = jfc.getSelectedFile().getAbsolutePath();
            //lastpath
            datas.put("lastpath", jfc.getSelectedFile().isDirectory() ? jfc.getSelectedFile().getAbsolutePath()
                    : jfc.getSelectedFile().getParent());

            if (jfc.getSelectedFile() == null) {
                //
                System.out.println("!!");
                return;
            }
            try {
                fileContentStringList = Files.readLines(jfc.getSelectedFile(), Charsets.ISO_8859_1);

            } catch (IOException ex) {
                Logger.getLogger(JIF_DrawChart_w3330.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            System.out.println("!!");
            return;
        }

        //??,dropinterval
        parseFileToDataStructure(fileContentStringList, dropinterval);
        if (metadatas.size() == 0) {
            System.out.println("?");
            return;
        } else {
            chartPanel.getChart().setTitle("" + jfc.getSelectedFile().getName());
            System.out.println("" + jfc.getSelectedFile().getName());
            System.out.println(String.format("?%d", fileContentStringList.size()));
            System.out.println(String.format("?%d", metadatas.size()));
        }

        //?
        KalmanFilterHolder kfh_AmbiTemp = new KalmanFilterHolder(25d);//?
        KalmanFilterHolder kfh_ppm = new KalmanFilterHolder(13d);//?

        //===============kalman?
        clearChart();//?

        tsNotifyFalse();//?

        //??
        for (int i = 0; i < metadatas.size(); i++) {
            W3330MetaData data = metadatas.get(i);

            if (oldzero < -1) {
                oldzero = data.zero;
                oldzerotime = data.time.getTime();
            } else if (oldzero != data.zero) {
                oldzero = data.zero;
                oldzerotime = data.time.getTime();
                //
                Color purple = new Color(139, 0, 255);
                String Labelstr = String.format("%.4f", data.zero);
                chartDrawHerizonLine(data, purple, Labelstr);
            }

            //status 1?? 2 ? 3 4 5?? 6 7?? 8 9? 0 
            if (oldstatus != data.status) {
                oldstatus = data.status;
                //
                Color purple = new Color(139, 0, 255);
                String Labelstr;

                switch ((int) data.status) {
                case 1:
                    Labelstr = "??";
                    break;
                case 2:
                    Labelstr = "?";
                    break;
                case 3:
                    Labelstr = "";
                    break;
                case 4:
                    Labelstr = "";
                    break;
                case 5:
                    Labelstr = "??";
                    break;
                case 6:
                    Labelstr = "";
                    break;
                case 7:
                    Labelstr = "??";
                    break;
                case 8:
                    Labelstr = "";
                    break;
                case 9:
                    Labelstr = "?";
                    break;
                case 0:
                    Labelstr = "";
                    break;
                default:
                    Labelstr = "???status=" + data.status;
                    //                        throw new AssertionError();
                }
                //                Labelstr = String.format("%.4f", data.zero);
                chartDrawVerticalLine(data, purple, Labelstr);

                //?ppm
                kfh_ppm = new KalmanFilterHolder(data.wppm);//?
            }

            //
            data.filter1 = kfh_AmbiTemp.getEstimation(data.temp3);
            data.filter2 = kfh_ppm.getEstimation(data.wppm);

            //fitting2 = kalmanfilter2.getStateEstimation()[0]-(fitting-25)*0.78;
            //                        fitting2 = wppm-(fitting-25)*0.7;//ppm
            //                        fitting = kalmanfilter.getStateEstimation()[0];
            // state estimate shouldn't be larger than the measurement noise
            //                        double diff = Math.abs(x.getEntry(0) - kalmanfilter.getStateEstimation()[0]);
            /*
                         //?
                         if (filterpoint < filterds.length) {
                         //?
                         filterds[filterpoint] = temp3;
                         filterpoint++;
                         fitting = wppm;
                         } else {
                
                         //???
                         filterds[filterpoint % filterds.length] = temp3;
                         double[] copy = Arrays.copyOf(filterds, filterds.length);
                         Arrays.sort(copy);
                
                         double total = 0;
                         for (int idx = copy.length / 4; idx < copy.length - copy.length / 4; idx++) {
                         total += copy[idx];
                         }
                         temp3 = total / (copy.length - copy.length / 4 - copy.length / 4);
                         filterpoint++;
                         //0.78?
                         //????
                         //                            fitting = wppm-(filterds[filterpoint%filterds.length]-25)*0.78;
                         fitting = wppm - (temp3 - 25) * 0.78;
                         }
                         */
            ts_wppm.addOrUpdate(new Millisecond(data.time), data.wppm);
            ts_wppm_zero.addOrUpdate(new Millisecond(data.time), data.ppmzero);
            ts_wvtr.addOrUpdate(new Millisecond(data.time), data.wvtr);
            //??100??100
            ts_flux.addOrUpdate(new Millisecond(data.time), data.flux);
            //25????25
            ts_tempambi.addOrUpdate(new Millisecond(data.time), data.temp3);
            //38????38
            ts_tempcell.addOrUpdate(new Millisecond(data.time), data.temp1);
            //?
            //status 1?? 2 ? 3 4 5?? 6 7?? 8 9? 0 
            ts_status.addOrUpdate(new Millisecond(data.time), data.status);
            ts_fitting.addOrUpdate(new Millisecond(data.time), data.filter1);
            data.fitting2 = data.wppm - (data.temp3 - 25) * 1.25;//??
            //data.fitting2 = data.wppm *(273.15+25)/(273.15+data.temp3);//??
            //            data.fitting2= data.wppm+(data.flux-40)*12.4;
            //            ts_fitting2.addOrUpdate(new Millisecond(data.time), data.fitting2);
            ts_fitting2.addOrUpdate(new Millisecond(data.time), data.filter2);
            //fitting2 ?
            /*
             int step = 20;
             step = tempint;
             if (data.zero > 0 && i % step == 0 && i > 2 * step) {
             //??
             double value_wvtr = (data.wppm - data.zero) * 0.02161956;
             double total = 0;
             double value_avg = 0;
             double old1 = (metadatas.get(i - step).wppm - data.zero);
             double old2 = (metadatas.get(i - step * 2).wppm - data.zero);
             total = (old1 + old2 + (data.wppm - data.zero)) * 0.02161956;
             value_avg = total / 3;
             double diff = (value_wvtr - value_avg) / value_avg;
             System.out.println(String.format(":%s?%.4f?%.4f???%.4f%%", sdfx.format(data.time), value_wvtr, value_avg, diff * 100));
             ts_fitting2.addOrUpdate(new Millisecond(data.time), data.wppm - old1 - data.zero);
             }
             */
        }

        tsNotifyTrue();//
    }

    private void chartDrawHerizonLine(W3330MetaData data, Color color, String Labelstr) {
        XYPlot plot = (XYPlot) chartPanel.getChart().getPlot();
        final Marker start = new ValueMarker(data.zero);
        start.setPaint(color);
        start.setLabel(Labelstr);
        start.setLabelAnchor(RectangleAnchor.BOTTOM_LEFT);
        start.setLabelTextAnchor(TextAnchor.TOP_LEFT);
        start.setLabelPaint(color);
        plot.addRangeMarker(start);
    }

    private void chartDrawVerticalLine(W3330MetaData data, Color color, String Labelstr) {
        XYPlot plot = (XYPlot) chartPanel.getChart().getPlot();
        final Marker start = new ValueMarker(data.time.getTime());
        start.setPaint(color);
        start.setLabel(Labelstr);
        start.setLabelAnchor(RectangleAnchor.TOP_LEFT);
        start.setLabelTextAnchor(TextAnchor.TOP_LEFT);
        start.setLabelPaint(color);
        plot.addDomainMarker(start);
    }

    private void tsNotifyTrue() {
        ts_wppm.setNotify(true);
        ts_wppm_zero.setNotify(true);
        ts_flux.setNotify(true);
        ts_wvtr.setNotify(true);
        ts_tempambi.setNotify(true);
        ts_tempcell.setNotify(true);
        ts_status.setNotify(true);
        ts_fitting.setNotify(true);
        ts_fitting2.setNotify(true);
    }

    private void tsNotifyFalse() {
        ts_wppm.setNotify(false);
        ts_wppm_zero.setNotify(false);
        ts_flux.setNotify(false);
        ts_wvtr.setNotify(false);
        ts_tempambi.setNotify(false);
        ts_tempcell.setNotify(false);
        ts_status.setNotify(false);
        ts_fitting.setNotify(false);
        ts_fitting2.setNotify(false);
    }

    private void clearChart() {
        //        String[] sa = (String[]) fileContentStringList.toArray(new String[fileContentStringList.size()]);
        ((XYPlot) chartPanel.getChart().getPlot()).clearDomainMarkers();
        ((XYPlot) chartPanel.getChart().getPlot()).clearRangeMarkers();
        ts_wppm.clear();
        ts_wppm_zero.clear();
        ts_flux.clear();
        ts_wvtr.clear();
        ts_tempambi.clear();
        ts_tempcell.clear();
        ts_status.clear();
        ts_fitting.clear();
        ts_fitting2.clear();
    }

    protected JFileChooser initFileChooser() {
        ExtensionFileFilter filter = new ExtensionFileFilter("log,txt", true, true);
        filter.setDescription("?");
        JFileChooser jfc = new JFileChooser();
        FileSystemView fsv = FileSystemView.getFileSystemView();
        //?
        jfc.setCurrentDirectory(fsv.getHomeDirectory());
        jfc.setDialogTitle("?");
        jfc.setMultiSelectionEnabled(false);
        jfc.setDialogType(JFileChooser.OPEN_DIALOG);
        jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);//JFileChooser.FILES_AND_DIRECTORIES
        jfc.setFileFilter(filter);
        return jfc;
    }

    @Override
    public void init() {
        initChart();
    }

    /**
     * ?jfreechart
     */
    public void initChart() {
        ts_wppm = new TimeSeries("PPM", Millisecond.class);
        ts_wppm_zero = new TimeSeries("PPM-Zero", Millisecond.class);
        ts_flux = new TimeSeries("Flux", Millisecond.class);
        ts_wvtr = new TimeSeries("WVTR", Millisecond.class);
        ts_tempcell = new TimeSeries(" Cell Temperature", Millisecond.class);
        ts_tempambi = new TimeSeries("Ambient Temperature", Millisecond.class);
        ts_status = new TimeSeries("Status", Millisecond.class);
        ts_fitting = new TimeSeries("fitting curve1", Millisecond.class);
        ts_fitting2 = new TimeSeries("fitting curve2", Millisecond.class);
        trcollection = new TimeSeriesCollection(ts_wppm);

        trcollection.addSeries(ts_wppm_zero);

        trcollection.addSeries(ts_wvtr);

        trcollection.addSeries(ts_fitting2);//ppm
        trcollection2 = new TimeSeriesCollection(ts_flux);

        trcollection2.addSeries(ts_fitting);//temp3

        trcollection2.addSeries(ts_tempcell);

        trcollection2.addSeries(ts_tempambi);

        trcollection2.addSeries(ts_status);
        //        timeseriescopylist.add(getTimeSeries(3).createCopy(0, getTimeSeries(3).getItemCount() - 1));
        JFreeChart jfreechart = ChartFactory.createTimeSeriesChart("", "Time(s)", "PPM", trcollection,
                true, true, false);
        XYPlot xyplot = jfreechart.getXYPlot();

        xyplot.setDomainCrosshairVisible(true);
        xyplot.setRangeCrosshairVisible(true);

        Font fs = new Font("", Font.BOLD, 14);
        Font fs2 = new Font("", Font.BOLD, 12);

        XYLineAndShapeRenderer line0render = (XYLineAndShapeRenderer) xyplot.getRenderer(0);

        Color purple = new Color(139, 0, 255);

        line0render.setSeriesPaint(0, Color.blue);
        line0render.setSeriesPaint(1, Color.green);
        line0render.setSeriesPaint(2, Color.red);
        line0render.setSeriesPaint(3, purple);

        //        line0render.setSeriesPaint(3, Color.ORANGE);
        XYLineAndShapeRenderer line1render = new XYLineAndShapeRenderer();
        Color Rosered = new Color(230, 28, 100);
        line1render.setSeriesPaint(0, Color.orange);
        line1render.setSeriesPaint(1, Color.yellow);
        line1render.setSeriesPaint(2, Color.cyan);
        line1render.setSeriesPaint(3, Rosered);
        line1render.setBaseShapesVisible(false);
        xyplot.setRenderer(1, line1render);

        //??
        ValueAxis valueaxis = xyplot.getDomainAxis();

        //
        valueaxis.setLabelFont(fs);

        //
        valueaxis.setTickLabelFont(fs2);

        ValueAxis valueaxis2 = new NumberAxis("");
        valueaxis2.setLabelFont(fs);
        valueaxis2.setTickLabelFont(fs2);

        xyplot.setRangeAxis(1, valueaxis2);
        xyplot.setDataset(1, trcollection2);
        xyplot.mapDatasetToRangeAxis(1, 1);

        //??
        valueaxis.setAutoRange(true);
        //?? 7days
        //                valueaxis.setFixedAutoRange(604800000D);
        valueaxis = xyplot.getRangeAxis();

        valueaxis.setLabelFont(new Font("", Font.BOLD, 14));
        valueaxis.setLabelPaint(line0render.getSeriesPaint(0));
        valueaxis2.setLabelPaint(line1render.getSeriesPaint(0));

        jfreechart.getTitle().setFont(new Font("", Font.BOLD, 20));//
        jfreechart.getLegend().setItemFont(new Font("", Font.ITALIC, 15));
        xyplot.getRenderer(0).setSeriesToolTipGenerator(0, new StandardXYToolTipGenerator("{1}, {2}",
                new SimpleDateFormat("MM-dd HH:mm:ss"), new DecimalFormat("0.0000")));
        xyplot.getRenderer(1).setSeriesToolTipGenerator(0, new StandardXYToolTipGenerator("{1}, {2}",
                new SimpleDateFormat("MM-dd HH:mm:ss"), new DecimalFormat("0.0000")));
        chartPanel = new ChartPanel(jfreechart);

        initChartMenu();
        //        chartPanel.getPopupMenu().add(jmenuitem2);
        //        chartPanel.getPopupMenu().getPopupMenuListeners();

        chartPanel.setSize(950, 620);
        chartPanel.setPreferredSize(new Dimension(950, 620));
        jPanel_Show.add(chartPanel, BorderLayout.CENTER);
    }

    /**
     * ????
     */
    public void initChartMenu() {
        GetPointAction action = new GetPointAction();
        JMenu fx = new JMenu("?");
        JMenuItem jmenuitem_select1 = new JMenuItem("");
        jmenuitem_select1.addActionListener(action);
        fx.add(jmenuitem_select1);
        JMenuItem jmenuitem_select2 = new JMenuItem("");
        jmenuitem_select2.addActionListener(action);
        fx.add(jmenuitem_select2);
        JMenuItem jmenuitem_avg = new JMenuItem("?");
        jmenuitem_avg.addActionListener(action);
        fx.add(jmenuitem_avg);
        JMenuItem jmenuitem_parse = new JMenuItem("?");
        jmenuitem_parse.addActionListener(action);
        fx.add(jmenuitem_parse);
        JMenuItem jmenuitem_bzc = new JMenuItem("?");
        jmenuitem_bzc.addActionListener(action);
        fx.add(jmenuitem_bzc);

        JMenuItem jmenuitem_zz1 = new JMenuItem("1");
        jmenuitem_zz1.addActionListener(action);
        fx.add(jmenuitem_zz1);
        JMenuItem jmenuitem_zz2 = new JMenuItem("2");
        jmenuitem_zz2.addActionListener(action);
        fx.add(jmenuitem_zz2);
        chartPanel.getPopupMenu().add(fx);

        JMenu bx = new JMenu("");

        JMenuItem jmenuitem7 = new JMenuItem("");
        jmenuitem7.addActionListener(action);
        bx.add(jmenuitem7);
        JMenuItem jmenuitem9 = new JMenuItem("");
        jmenuitem9.addActionListener(action);
        bx.add(jmenuitem9);
        JMenuItem jmenuitem10 = new JMenuItem("");
        jmenuitem10.addActionListener(action);
        bx.add(jmenuitem10);

        chartPanel.getPopupMenu().add(bx);
    }

    /**
     * ??
     *
     * @param inlist List
     * @param second  
     */
    private void parseFileToDataStructure(List<String> inlist, long second) {
        metadatas = new ArrayList<W3330MetaData>();
        long last = 0;
        for (int i = 0; i < inlist.size(); i++) {
            String str = inlist.get(i);
            W3330MetaData data = W3330MetaData.parseString(str);
            if (data != null) {
                if (last == 0 || data.time.getTime() - last > second * 1000) {
                    last = data.time.getTime();
                    metadatas.add(data);
                    // ? X??
                    i = (int) (i + second / 1.9);

                }
            }
        }

    }

    private String[] docompress(List<String> inlist, int everyX) {
        List<String> rtnsl = new ArrayList<String>();
        List<String> tempsl = new ArrayList<String>();
        int count = 0;
        for (String s : inlist) {
            if (s == null || s.isEmpty()) {
                continue;
            }
            if (count == 0 || count == inlist.size() - 1) {
                rtnsl.add(s);
            } else if (count % everyX == 0) {
                rtnsl.add(s);
                //rtnsl.add(s);
            } else {
            }
            count++;
        }
        return (String[]) rtnsl.toArray(new String[rtnsl.size()]);

    }

    private Date chartstarttime;
    private Date chartendtime;

    /**
     * ???
     */
    class GetPointAction implements ActionListener { //???

        @Override
        public void actionPerformed(ActionEvent event) {

            String command = event.getActionCommand();
            //            System.out.println(command);

            //            int x = (int) chartPanel.getMousePosition().getX();
            //            int y = (int) chartPanel.getMousePosition().getY();
            XYPlot plot = (XYPlot) chartPanel.getChart().getPlot();
            double XValue = plot.getDomainCrosshairValue();
            double YValue = plot.getRangeCrosshairValue();

            Date date = new Date((long) XValue);

            if (command.equals("")) {
                chartstarttime = date;
                System.out.println(String.format(
                        "[%1$tY/%1$tm/%1$te %1$tH:%1$tM:%1$tS %1$tL],%2$f", date,
                        YValue));
            } else if (command.equals("")) {
                chartendtime = date;
                System.out.println(String.format(
                        "[%1$tY/%1$tm/%1$te %1$tH:%1$tM:%1$tS %1$tL],%2$f", date,
                        YValue));
            } else if (command.equals("?")) {
                double total = 0;
                double total2 = 0;
                int totalcount = 0;
                long start = chartstarttime.getTime();
                long end = chartendtime.getTime();
                for (int i = 0; i < metadatas.size(); i++) {
                    W3330MetaData da = metadatas.get(i);
                    long time = da.time.getTime();
                    if (time >= start && time <= end) {
                        total += da.wppm;
                        total2 += da.temp3;
                        totalcount++;
                    }
                    if (time > end) {
                        System.out.println("wppm?" + total / totalcount + ",?"
                                + total2 / totalcount);
                        break;
                    }
                }
            } else if (command.equals("?")) {
                long start = chartstarttime.getTime();
                long end = chartendtime.getTime();
                if (end < start) {
                    System.out.println("?");
                }

                double total = 0;
                double total2 = 0;
                int totalcount = 0;
                long start2 = start;
                long end2 = end;
                long distance = end - start;

                SimpleDateFormat sdfx = new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]");
                for (int i = 0; i < metadatas.size(); i++) {
                    W3330MetaData da = metadatas.get(i);
                    long time = da.time.getTime();
                    if (time >= start2 && time <= end2) {
                        //?
                        total += da.wppm;
                        total2 += da.temp3;
                        totalcount++;
                    } else if (time > end2) {
                        //??
                        //
                        System.out
                                .println(String.format(" %s  %s,wppm?%.4f,?%.4f",
                                        sdfx.format(new Date(start2)), sdfx.format(new Date(end2)),
                                        total / totalcount, total2 / totalcount));
                        //                        System.out.println("wppm?" + total / totalcount + ",?" + total2 / totalcount);
                        //?
                        total = da.wppm;
                        total2 = da.temp3;
                        totalcount = 1;
                        start2 = time;
                        end2 = start2 + distance;
                        //                        break;
                    } else if (i == metadatas.size() - 1) {
                        System.out
                                .println(String.format(" %s  %s,wppm?%.4f,?%.4f",
                                        sdfx.format(new Date(start2)), sdfx.format(da.time), total / totalcount,
                                        total2 / totalcount));
                    }
                }
            } else if (command.equals("?")) {
                long start = chartstarttime.getTime();
                long end = chartendtime.getTime();
                if (end < start) {
                    System.out.println("?");
                }
                int starti = -1;
                int endi = -1;
                double total = 0;
                double total2 = 0;
                double total3 = 0;
                double max1 = Double.MIN_VALUE;
                double max2 = Double.MIN_VALUE;
                double max3 = Double.MIN_VALUE;
                double min1 = Double.MAX_VALUE;
                double min2 = Double.MAX_VALUE;
                double min3 = Double.MAX_VALUE;
                int totalcount = 0;

                for (int i = 0; i < metadatas.size(); i++) {
                    W3330MetaData da = metadatas.get(i);
                    long time = da.time.getTime();
                    if (time >= start && time <= end) {
                        //?
                        if (starti == -1) {
                            starti = i;
                        }
                        total += da.wppm;
                        max1 = max1 > da.wppm ? max1 : da.wppm;
                        min1 = min1 < da.wppm ? min1 : da.wppm;
                        total2 += da.temp3;
                        max2 = max2 > da.temp3 ? max2 : da.temp3;
                        min2 = min2 < da.temp3 ? min2 : da.temp3;
                        total3 += da.fitting2;
                        max3 = max3 > da.fitting2 ? max3 : da.fitting2;
                        min3 = min3 < da.fitting2 ? min3 : da.fitting2;
                        totalcount++;

                    } else if (time > end) {
                        if (endi == -1) {
                            endi = i - 1;
                        }
                        break;
                    }
                }
                total = total / totalcount;//?
                total2 = total2 / totalcount;//?
                total3 = total3 / totalcount;//?

                double omega = 0;
                double omega2 = 0;
                double omega3 = 0;
                for (int i = starti; i < endi + 1; i++) {
                    W3330MetaData da = metadatas.get(i);
                    omega += (da.wppm - total) * (da.wppm - total);
                    omega2 += (da.temp3 - total) * (da.temp3 - total);
                    omega3 += (da.fitting2 - total) * (da.fitting2 - total);
                }
                System.out.println(
                        String.format("ppm:%.4f,:%.4f,?PPM:%.4f",
                                Math.sqrt(omega / totalcount), Math.sqrt(omega2 / totalcount),
                                Math.sqrt(omega3 / totalcount)));
                System.out.println(String.format(
                        "ppm?%.4f,%.4f,?%.4f,%.4f,?PPM?%.4f,%.4f",
                        min1, max1, min2, max2, min3, max3));

            } else if (command.equals("")) {
                //                plot.getRangeMarkers(Layer.FOREGROUND);
                String s = JOptionPane.showInputDialog("?");
                final Marker start = new ValueMarker(YValue);
                start.setPaint(Color.GREEN);
                start.setLabel(String.format("%s,%.4f", s, YValue));
                start.setLabelAnchor(RectangleAnchor.BOTTOM_LEFT);
                start.setLabelTextAnchor(TextAnchor.TOP_LEFT);
                start.setLabelPaint(Color.red);
                plot.addRangeMarker(start);
            } else if (command.equals("")) {
                //                plot.getRangeMarkers(Layer.FOREGROUND);
                String s = JOptionPane.showInputDialog("?");
                final Marker start = new ValueMarker(XValue);
                start.setPaint(Color.GREEN);
                start.setLabel(String.format("%s", s, XValue));

                start.setLabelAnchor(RectangleAnchor.CENTER);
                start.setLabelTextAnchor(TextAnchor.BOTTOM_RIGHT);
                start.setLabelPaint(Color.red);
                plot.addDomainMarker(start);
            } else if (command.equals("")) {
                int k = JOptionPane.showConfirmDialog(null, "?");
                if (k == JOptionPane.YES_OPTION) {
                    plot.clearDomainMarkers();
                    plot.clearRangeMarkers();
                }
            } else if (command.equals("1")) {
                ValueAxis valueaxis = plot.getRangeAxis(0);
                System.out.println(valueaxis.getLabel());
                ;
                String s = JOptionPane.showInputDialog("??");
                if (Strings.isNullOrEmpty(s)) {
                    //donothing
                    valueaxis.setLabel("PPM");
                } else {
                    valueaxis.setLabel(s);
                    //                    valueaxis.setLabelPaint(Color.BLUE);
                }
                s = JOptionPane.showInputDialog("?");
                if (Strings.isNullOrEmpty(s)) {
                    return;
                }
                double lower = Double.parseDouble(s);
                s = JOptionPane.showInputDialog("?");
                if (Strings.isNullOrEmpty(s)) {
                    return;
                }
                double upper = Double.parseDouble(s);
                valueaxis.setRange(lower, upper);
            } else if (command.equals("2")) {
                ValueAxis valueaxis2 = plot.getRangeAxis(1);

                String s = JOptionPane.showInputDialog("??");
                if (Strings.isNullOrEmpty(s)) {
                    //donothing
                    valueaxis2.setLabel("");
                } else {
                    valueaxis2.setLabel(s);
                }

                s = JOptionPane.showInputDialog("?");
                if (Strings.isNullOrEmpty(s)) {
                    return;
                }
                double lower = Double.parseDouble(s);
                s = JOptionPane.showInputDialog("?");
                if (Strings.isNullOrEmpty(s)) {
                    return;
                }
                double upper = Double.parseDouble(s);
                valueaxis2.setRange(lower, upper);

            } else {

            }

            //            System.out.println(chartPanel.getMousePosition().getX());
            //            System.out.println(chartPanel.getMousePosition().getY());
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonOpen;
    private javax.swing.JCheckBox jCheckBox_ambitemp;
    private javax.swing.JCheckBox jCheckBox_celltemp;
    private javax.swing.JCheckBox jCheckBox_fitting;
    private javax.swing.JCheckBox jCheckBox_fitting2;
    private javax.swing.JCheckBox jCheckBox_flux;
    private javax.swing.JCheckBox jCheckBox_status;
    private javax.swing.JCheckBox jCheckBox_wppm;
    private javax.swing.JCheckBox jCheckBox_wppmZero;
    private javax.swing.JCheckBox jCheckBox_wvtr;
    private javax.swing.JFormattedTextField jFormattedTextField_temp;
    private javax.swing.JPanel jPanel_Control;
    private javax.swing.JPanel jPanel_Show;
    // End of variables declaration//GEN-END:variables

}