de.fischer.thotti.reportgen.diagram.ChartGenerator.java Source code

Java tutorial

Introduction

Here is the source code for de.fischer.thotti.reportgen.diagram.ChartGenerator.java

Source

/*
 * Copyright 2012 Oliver B. Fischer
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.fischer.thotti.reportgen.diagram;

import de.fischer.thotti.persistence.NDResultEntity;
import de.fischer.thotti.persistence.PersistenceHelper;
import de.fischer.thotti.persistence.TestVariant;
import de.fischer.thotti.reportgen.combiner.AverageDayCombinerIterator;
import de.fischer.thotti.reportgen.combiner.MedianIterator;
import de.fischer.thotti.reportgen.model.TestVariantModel;
import org.apache.batik.dom.GenericDOMImplementation;
import org.apache.batik.svggen.SVGGraphics2D;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;

import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

public class ChartGenerator {
    public static final int DEFAULT_CHAR_WIDTH = 800;
    public static final int DEFAULT_CHAR_HEIGHT = 400;
    public PersistenceHelper persistenceHelper;
    private File baseDir;

    @Deprecated
    public ChartGenerator(File dir) {
        this.baseDir = dir;
    }

    public ChartGenerator() {
    }

    public void setPersistenceHelper(final PersistenceHelper helper) {
        persistenceHelper = helper;
    }

    public ChartGenerator withPersistenceHelper(final PersistenceHelper helper) {
        setPersistenceHelper(helper);

        return this;
    }

    public void setBaseDir(File dir) {
        baseDir = dir;
    }

    public ChartGenerator withBaseDir(File dir) {
        setBaseDir(dir);

        return this;
    }

    private JFreeChart createChart(final String chartTitle, final XYDataset xyDataset) {
        JFreeChart chart = ChartFactory.createTimeSeriesChart(chartTitle, // title
                "Date", // x-axis label
                "Seconds", // y-axis label
                xyDataset, // data
                true, // create legend?
                false, // generate tooltips?
                false // generate URLs?
        );

        // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
        chart.setBackgroundPaint(Color.white);

        //        final StandardLegend legend = (StandardLegend) chart.getLegend();
        //      legend.setDisplaySeriesShapes(true);

        // get a reference to the plot for further customisation...
        final XYPlot plot = chart.getXYPlot();
        plot.setBackgroundPaint(Color.WHITE);
        //    plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
        plot.setDomainGridlinePaint(Color.gray);
        plot.setRangeGridlinePaint(Color.lightGray);

        final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
        //renderer.setSeriesLinesVisible(1, false);
        //renderer.setSeriesLinesVisible(0, false);
        plot.setRenderer(renderer);

        // change the auto tick unit selection to integer units only...
        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        // OPTIONAL CUSTOMISATION COMPLETED.

        DateAxis axis = (DateAxis) plot.getDomainAxis();
        axis.setDateFormatOverride(new SimpleDateFormat("dd-MM-yyyy"));

        return chart;
    }

    public ChartMetaData generateSingleVariantsChart(final String testId, String jvmArgsId, String paramGrpId) {

        String variantId = String.format("%s-%s-%s", testId, jvmArgsId, paramGrpId);

        File chartFile;
        try {
            final TimeSeriesCollection collection = new TimeSeriesCollection();

            String chartTitle = String.format("%s-%s-%s", testId, jvmArgsId, paramGrpId);
            String svgFilename = String.format("%s-%s-%s.svg", testId, jvmArgsId, paramGrpId);

            chartFile = new File(baseDir, svgFilename);

            TimeSeries series = new TimeSeries(String.format("Average of %s", variantId), Day.class);
            TimeSeries mediaSeries = new TimeSeries(String.format("Median of %s", variantId), Day.class);

            List<NDResultEntity> results = persistenceHelper.findAllResultsForVariant(testId, jvmArgsId,
                    paramGrpId);

            SortedSet<NDResultEntity> sortedSet = new TreeSet<NDResultEntity>(
                    new TestVariantModel.DateComparator());

            sortedSet.addAll(results);

            Iterator<Measurement> itr = new AverageDayCombinerIterator(sortedSet.iterator());

            while (itr.hasNext()) {
                Measurement singleResult = itr.next();

                Date startDate = singleResult.getPointInTime();
                double time = singleResult.getDuration();

                double t2 = convertMilliSecsToSeconds(time);

                series.add(new Day(startDate), t2);
            }

            collection.addSeries(series);

            Iterator<DatePoint> medianItr = new MedianIterator(sortedSet.iterator());

            while (medianItr.hasNext()) {
                DatePoint singleResult = medianItr.next();

                Date startDate = singleResult.getPointInTime();
                double value = convertMilliSecsToSeconds(singleResult.getValue());

                mediaSeries.add(new Day(startDate), value);
            }

            collection.addSeries(mediaSeries);

            final JFreeChart chart = createChart(chartTitle, collection);

            saveChartAsSVG(chart, svgFilename);

            System.out.println(String.format("Written %s", chartFile.toString()));

            return new ChartMetaData().withFilename(chartFile.getName()).withWidth(DEFAULT_CHAR_WIDTH)
                    .withHeight(DEFAULT_CHAR_HEIGHT).withFormat("SVG");

        } catch (IOException ioe) {
            // @todo Throw an better exception!
            ioe.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
        }

        return null;
    }

    public ChartMetaData generateAllVariantsChart(final String testId) {
        File chartFile;
        try {
            final List<TestVariant> variants = persistenceHelper.findAllVariants(testId);
            final TimeSeriesCollection collection = new TimeSeriesCollection();

            String svgFilename = String.format("%s.svg", testId);

            chartFile = new File(baseDir, svgFilename);

            for (TestVariant variant : variants) {
                TimeSeries series = new TimeSeries(String.format("Average of %s", variant.getCombinedId()),
                        Day.class);
                TimeSeries mediaSeries = new TimeSeries("Median of " + variant, Day.class);

                List<NDResultEntity> results = persistenceHelper.findAllResultsForVariant(variant);

                SortedSet<NDResultEntity> sortedSet = new TreeSet<NDResultEntity>(
                        new TestVariantModel.DateComparator());

                sortedSet.addAll(results);

                Calendar now = Calendar.getInstance();

                now.add(Calendar.DATE, 1);

                Iterator<Measurement> itr = new AverageDayCombinerIterator(sortedSet.iterator());
                Iterator<DatePoint> medianItr = new MedianIterator(sortedSet.iterator());

                while (itr.hasNext()) {
                    Measurement singleResult = itr.next();

                    Date startDate = singleResult.getPointInTime();

                    double timeInMS = singleResult.getDuration();
                    double timeInSecs = convertMilliSecsToSeconds(timeInMS);

                    series.add(new Day(startDate), timeInSecs);
                }

                while (medianItr.hasNext()) {
                    DatePoint singleResult = medianItr.next();

                    Day day = new Day(singleResult.getPointInTime());
                    double value = convertMilliSecsToSeconds(singleResult.getValue());

                    mediaSeries.add(day, value);
                }

                collection.addSeries(series);
                collection.addSeries(mediaSeries);
            }

            final JFreeChart chart = createChart(testId, collection);

            saveChartAsSVG(chart, svgFilename);

            System.out.println(String.format("Written %s", chartFile.toString()));

            return new ChartMetaData().withFilename(chartFile.getName()).withWidth(DEFAULT_CHAR_WIDTH)
                    .withHeight(DEFAULT_CHAR_HEIGHT).withFormat("SVG");

        } catch (Exception ioe) {
            // @todo Throw an better exception!
            ioe.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
        }

        return null;
    }

    private void saveChartAsSVG(JFreeChart chartToSave, String svgFilename)
            throws IOException, FileNotFoundException {

        File chartFile = new File(baseDir, svgFilename);

        DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
        final Document document = domImpl.createDocument(null, "svg", null);

        SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
        //
        Rectangle2D.Double area = new Rectangle2D.Double(0.0, 0.0, DEFAULT_CHAR_WIDTH, DEFAULT_CHAR_HEIGHT);
        chartToSave.draw(svgGenerator, area);
        //
        //            // Write svg file
        OutputStream outputStream = new FileOutputStream(chartFile);
        Writer out = new FileWriter(chartFile);// new OutputStreamWriter(System.out, "UTF-8");
        //            ChartUtilities.writeChartAsPNG(outputStream, chart, 800, 400);
        svgGenerator.stream(out, true /* use css */);

    }

    private double convertMilliSecsToSeconds(double timestampInMs) {
        return timestampInMs / 1000;
    }
}