Java tutorial
/* * 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; } }