<commit_before>package dr.app.tracer.analysis;

import org.virion.jam.framework.AuxilaryFrame;
import org.virion.jam.framework.DocumentFrame;
import dr.util.Variate;
import dr.app.tracer.application.TracerFileMenuHandler;

import javax.swing.*;
import java.awt.*;

public class TemporalAnalysisFrame extends AuxilaryFrame {
	private int binCount;
	private double minTime;
	private double maxTime;

	private boolean rangeSet;

	TemporalAnalysisPlotPanel temporalAnalysisPlotPanel = null;

	public TemporalAnalysisFrame(DocumentFrame frame, String title, int binCount) {
		this(frame, title, binCount, 0.0, 0.0);
		rangeSet = false;
	}

	public TemporalAnalysisFrame(DocumentFrame frame, String title, int binCount, double minTime, double maxTime) {

		super(frame);

		setTitle(title);

		this.binCount = binCount;
		this.minTime = minTime;
		this.maxTime = maxTime;

		rangeSet = true;

		temporalAnalysisPlotPanel = new TemporalAnalysisPlotPanel(this);

		setContentsPanel(temporalAnalysisPlotPanel);

		getSaveAction().setEnabled(false);
		getSaveAsAction().setEnabled(false);

		getCutAction().setEnabled(false);
		getCopyAction().setEnabled(true);
		getPasteAction().setEnabled(false);
		getDeleteAction().setEnabled(false);
		getSelectAllAction().setEnabled(false);
		getFindAction().setEnabled(false);

		getZoomWindowAction().setEnabled(false);
	}

	public void initializeComponents() {

		setSize(new java.awt.Dimension(640, 480));
	}

    public void addDemographic(String title, Variate xData,
                                 Variate yDataMean, Variate yDataMedian,
                                 Variate yDataUpper, Variate yDataLower,
                                 double timeMean, double timeMedian,
                                 double timeUpper, double timeLower) {

	    if (!rangeSet) {
		    throw new RuntimeException("Range not set");
	    }

	    if (getTitle().length() == 0) {
		    setTitle(title);
	    }

		temporalAnalysisPlotPanel.addDemographicPlot(title, xData, yDataMean, yDataMedian, yDataUpper, yDataLower,
                timeMean, timeMedian, timeUpper, timeLower);
		setVisible(true);
	}

	public void addDensity(String title, Variate xData,  Variate yData) {

		if (!rangeSet) {
			throw new RuntimeException("Range not set");
		}

		temporalAnalysisPlotPanel.addDensityPlot(title, xData, yData);
		setVisible(true);
	}

	public boolean useExportAction() { return true; }

    public JComponent getExportableComponent() {
		return temporalAnalysisPlotPanel.getExportableComponent();
	}

	public void doCopy() {
		java.awt.datatransfer.Clipboard clipboard =
			Toolkit.getDefaultToolkit().getSystemClipboard();

		java.awt.datatransfer.StringSelection selection =
			new java.awt.datatransfer.StringSelection(this.toString());

		clipboard.setContents(selection, selection);
	}

	public int getBinCount() {
		return binCount;
	}

	public double getMinTime() {
		if (!rangeSet) {
			throw new RuntimeException("Range not set");
		}

		return minTime;
	}

	public double getMaxTime() {
		if (!rangeSet) {
			throw new RuntimeException("Range not set");
		}

		return maxTime;
	}

	public void setRange(double minTime, double maxTime) {
		if (rangeSet) {
			throw new RuntimeException("Range already set");
		}

		this.minTime = minTime;
		this.maxTime = maxTime;
		rangeSet = true;
	}

	public boolean isRangeSet() {
		return rangeSet;
	}

	public String toString() {
		StringBuffer buffer = new StringBuffer();

        java.util.List<TemporalAnalysisPlotPanel.AnalysisData> analyses = temporalAnalysisPlotPanel.getAnalysisData();
        buffer.append("Time");
        for (TemporalAnalysisPlotPanel.AnalysisData analysis : analyses) {
            if (analysis.isDemographic) {
                buffer.append("\t").append(analysis.title).append("\tMedian\tUpper\tLower");
            } else {
                buffer.append("\t").append(analysis.title);
            }
        }
        buffer.append("\n");

        Variate timeScale = temporalAnalysisPlotPanel.getTimeScale();
        for (int i = 0; i < timeScale.getCount(); i++) {
            buffer.append(String.valueOf(timeScale.get(i)));

            for (TemporalAnalysisPlotPanel.AnalysisData analysis : analyses) {
                if (analysis.isDemographic) {
                    buffer.append("\t");
                    buffer.append(String.valueOf(analysis.yDataMean.get(i)));
                    buffer.append("\t");
                    buffer.append(String.valueOf(analysis.yDataMedian.get(i)));
                    buffer.append("\t");
                    buffer.append(String.valueOf(analysis.yDataUpper.get(i)));
                    buffer.append("\t");
                    buffer.append(String.valueOf(analysis.yDataLower.get(i)));
                } else {
                    buffer.append("\t");
                    buffer.append(String.valueOf(analysis.yDataMean.get(i)));
                }
            }
			buffer.append("\n");
		}

		return buffer.toString();
	}
}<commit_msg>Made TemporalAnalysisFrame implement TracerFileMenuHandler so it will now export data and PDFs.<commit_after>package dr.app.tracer.analysis;

import org.virion.jam.framework.AuxilaryFrame;
import org.virion.jam.framework.DocumentFrame;
import dr.util.Variate;
import dr.app.tracer.application.TracerFileMenuHandler;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.awt.event.ActionEvent;
import java.io.*;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.*;

public class TemporalAnalysisFrame extends AuxilaryFrame implements TracerFileMenuHandler {
	private int binCount;
	private double minTime;
	private double maxTime;

	private boolean rangeSet;

	TemporalAnalysisPlotPanel temporalAnalysisPlotPanel = null;

	public TemporalAnalysisFrame(DocumentFrame frame, String title, int binCount) {
		this(frame, title, binCount, 0.0, 0.0);
		rangeSet = false;
	}

	public TemporalAnalysisFrame(DocumentFrame frame, String title, int binCount, double minTime, double maxTime) {

		super(frame);

		setTitle(title);

		this.binCount = binCount;
		this.minTime = minTime;
		this.maxTime = maxTime;

		rangeSet = true;

		temporalAnalysisPlotPanel = new TemporalAnalysisPlotPanel(this);

		setContentsPanel(temporalAnalysisPlotPanel);

		getSaveAction().setEnabled(false);
		getSaveAsAction().setEnabled(false);

		getCutAction().setEnabled(false);
		getCopyAction().setEnabled(true);
		getPasteAction().setEnabled(false);
		getDeleteAction().setEnabled(false);
		getSelectAllAction().setEnabled(false);
		getFindAction().setEnabled(false);

		getZoomWindowAction().setEnabled(false);
	}

	public void initializeComponents() {

		setSize(new java.awt.Dimension(640, 480));
	}

    public void addDemographic(String title, Variate xData,
                                 Variate yDataMean, Variate yDataMedian,
                                 Variate yDataUpper, Variate yDataLower,
                                 double timeMean, double timeMedian,
                                 double timeUpper, double timeLower) {

	    if (!rangeSet) {
		    throw new RuntimeException("Range not set");
	    }

	    if (getTitle().length() == 0) {
		    setTitle(title);
	    }

		temporalAnalysisPlotPanel.addDemographicPlot(title, xData, yDataMean, yDataMedian, yDataUpper, yDataLower,
                timeMean, timeMedian, timeUpper, timeLower);
		setVisible(true);
	}

	public void addDensity(String title, Variate xData,  Variate yData) {

		if (!rangeSet) {
			throw new RuntimeException("Range not set");
		}

		temporalAnalysisPlotPanel.addDensityPlot(title, xData, yData);
		setVisible(true);
	}

	public boolean useExportAction() { return true; }

    public JComponent getExportableComponent() {
		return temporalAnalysisPlotPanel.getExportableComponent();
	}

	public void doCopy() {
		java.awt.datatransfer.Clipboard clipboard =
			Toolkit.getDefaultToolkit().getSystemClipboard();

		java.awt.datatransfer.StringSelection selection =
			new java.awt.datatransfer.StringSelection(this.toString());

		clipboard.setContents(selection, selection);
	}

	public int getBinCount() {
		return binCount;
	}

	public double getMinTime() {
		if (!rangeSet) {
			throw new RuntimeException("Range not set");
		}

		return minTime;
	}

	public double getMaxTime() {
		if (!rangeSet) {
			throw new RuntimeException("Range not set");
		}

		return maxTime;
	}

	public void setRange(double minTime, double maxTime) {
		if (rangeSet) {
			throw new RuntimeException("Range already set");
		}

		this.minTime = minTime;
		this.maxTime = maxTime;
		rangeSet = true;
	}

	public boolean isRangeSet() {
		return rangeSet;
	}

	public final void doExportData() {

	    FileDialog dialog = new FileDialog(this,
	            "Export Data...",
	            FileDialog.SAVE);

	    dialog.setVisible(true);
	    if (dialog.getFile() != null) {
	        File file = new File(dialog.getDirectory(), dialog.getFile());

	        try {
	            FileWriter writer = new FileWriter(file);
	            writer.write(toString());
	            writer.close();


	        } catch (IOException ioe) {
	            JOptionPane.showMessageDialog(this, "Unable to write file: " + ioe,
	                    "Unable to write file",
	                    JOptionPane.ERROR_MESSAGE);
	        }
	    }

	}

	public final void doExportPDF() {
	    FileDialog dialog = new FileDialog(this,
	            "Export PDF Image...",
	            FileDialog.SAVE);

	    dialog.setVisible(true);
	    if (dialog.getFile() != null) {
	        File file = new File(dialog.getDirectory(), dialog.getFile());

	        Rectangle2D bounds = temporalAnalysisPlotPanel.getExportableComponent().getBounds();
	        Document document = new Document(new com.lowagie.text.Rectangle((float)bounds.getWidth(), (float)bounds.getHeight()));
	        try {
	            // step 2
	            PdfWriter writer;
	            writer = PdfWriter.getInstance(document, new FileOutputStream(file));
	            // step 3
	            document.open();
	            // step 4
	            PdfContentByte cb = writer.getDirectContent();
	            PdfTemplate tp = cb.createTemplate((float)bounds.getWidth(), (float)bounds.getHeight());
	            Graphics2D g2d = tp.createGraphics((float)bounds.getWidth(), (float)bounds.getHeight(), new DefaultFontMapper());
	            temporalAnalysisPlotPanel.getExportableComponent().print(g2d);
	            g2d.dispose();
	            cb.addTemplate(tp, 0, 0);
	        }
	        catch(DocumentException de) {
	            JOptionPane.showMessageDialog(this, "Error writing PDF file: " + de,
	                    "Export PDF Error",
	                    JOptionPane.ERROR_MESSAGE);
	        }
	        catch (FileNotFoundException e) {
	            JOptionPane.showMessageDialog(this, "Error writing PDF file: " + e,
	                    "Export PDF Error",
	                    JOptionPane.ERROR_MESSAGE);
	        }
	        document.close();
	    }
	}

	public String toString() {
		StringBuffer buffer = new StringBuffer();

        java.util.List<TemporalAnalysisPlotPanel.AnalysisData> analyses = temporalAnalysisPlotPanel.getAnalysisData();
        buffer.append("Time");
        for (TemporalAnalysisPlotPanel.AnalysisData analysis : analyses) {
            if (analysis.isDemographic) {
                buffer.append("\t").append(analysis.title).append("\tMedian\tUpper\tLower");
            } else {
                buffer.append("\t").append(analysis.title);
            }
        }
        buffer.append("\n");

        Variate timeScale = temporalAnalysisPlotPanel.getTimeScale();
        for (int i = 0; i < timeScale.getCount(); i++) {
            buffer.append(String.valueOf(timeScale.get(i)));

            for (TemporalAnalysisPlotPanel.AnalysisData analysis : analyses) {
                if (analysis.isDemographic) {
                    buffer.append("\t");
                    buffer.append(String.valueOf(analysis.yDataMean.get(i)));
                    buffer.append("\t");
                    buffer.append(String.valueOf(analysis.yDataMedian.get(i)));
                    buffer.append("\t");
                    buffer.append(String.valueOf(analysis.yDataUpper.get(i)));
                    buffer.append("\t");
                    buffer.append(String.valueOf(analysis.yDataLower.get(i)));
                } else {
                    buffer.append("\t");
                    buffer.append(String.valueOf(analysis.yDataMean.get(i)));
                }
            }
			buffer.append("\n");
		}

		return buffer.toString();
	}

	public Action getExportDataAction() {
		return exportDataAction;
	}

	public Action getExportPDFAction() {
		return exportPDFAction;
	}

	private AbstractAction exportDataAction = new AbstractAction("Export Data...") {
	    public void actionPerformed(ActionEvent ae) {
	        doExportData();
	    }
	};

	private AbstractAction exportPDFAction = new AbstractAction("Export PDF...") {
	    public void actionPerformed(ActionEvent ae) {
	        doExportPDF();
	    }
	};

}
{'fraction_non_alphanumeric': 0.11058536213080974, 'fraction_numerical': 0.002671144012821491, 'mean_word_length': 2.7752808988764044, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2976421', 'n_tokens_mistral': 4029, 'n_tokens_neox': 3598, 'n_words': 742}