Mercurial > hg > ThermostatQA
changeset 121:8c4a2784ba04
Added 1st version of a results graph generator.
author | Pavel Tisnovsky <ptisnovs@redhat.com> |
---|---|
date | Mon, 11 Nov 2013 13:07:52 +0100 |
parents | 8c867e89e12e |
children | 178e1d1ccc9e |
files | ChangeLog src/org/thermostat/qa/reporter/ResultsGraphGenerator.java |
diffstat | 2 files changed, 231 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Fri Nov 08 10:01:04 2013 +0100 +++ b/ChangeLog Mon Nov 11 13:07:52 2013 +0100 @@ -1,3 +1,8 @@ +2013-11-11 Pavel Tisnovsky <ptisnovs@redhat.com> + + * src/org/thermostat/qa/reporter/ResultsGraphGenerator.java: + Added 1st version of a results graph generator. + 2013-11-08 Pavel Tisnovsky <ptisnovs@redhat.com> * src/org/thermostat/qa/reporter/GraphPagesGenerator.java:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/org/thermostat/qa/reporter/ResultsGraphGenerator.java Mon Nov 11 13:07:52 2013 +0100 @@ -0,0 +1,226 @@ +/* + + ThermostatQA - test framework for Thermostat Monitoring Tool + + Copyright 2013 Red Hat, Inc. + +This file is part of ThermostatQA + +ThermostatQA is distributed under the GNU General Public License, +version 2 or any later version (with a special exception described +below, commonly known as the "Classpath Exception"). + +A copy of GNU General Public License (GPL) is included in this +distribution, in the file COPYING. + +Linking ThermostatQA code with other modules is making a combined work +based on ThermostatQA. Thus, the terms and conditions of the GPL +cover the whole combination. + +As a special exception, the copyright holders of ThermostatQA give you +permission to link this code with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on ThermostatQA code. If you modify ThermostatQA, you may +extend this exception to your version of the software, but you are +not obligated to do so. If you do not wish to do so, delete this +exception statement from your version. +*/ + +package org.thermostat.qa.reporter; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; + + + +/** + * Simple generator for a graph (pie chart) containing test results which is + * used on the index.html page. + * + * @author Pavel Tisnovsky <ptisnovs@redhat.com> + */ +public class ResultsGraphGenerator implements CommonGenerator +{ + /** + * + */ + private static final int ARC_BORDER = 20; + + private int width; + private int height; + private int arcX; + private int arcY; + private int arcWidth; + private int arcHeight; + private Graphics2D graphics; + + /** + * @param testResult + * @param graphSize + * @param string + * @throws IOException + */ + private void generateGraph(TestResult testResult, Dimension graphSize, String fileName) throws IOException { + setupGeometry(graphSize); + BufferedImage bitmap = createBitmap(); + setGraphics(bitmap); + clearCanvas(); + + int totalTests = testResult.getPassed() + testResult.getFailed() + testResult.getError() + testResult.getIgnored(); + int[] results = new int[4]; + results[0] = testResult.getPassed(); + results[1] = testResult.getFailed(); + results[2] = testResult.getError(); + results[3] = testResult.getIgnored(); + Color[] arcColors = {Color.green, Color.red, Color.blue, Color.gray}; + + float startAngle = 0.0f; + float arcAngle; + + for (int i = 0; i < results.length; i++) { + arcAngle = calcArcAngle(results[i], totalTests); + fillArc(arcColors[i], startAngle, arcAngle); + startAngle += arcAngle; + } + + arcAngle = 0; + for (int i = 0; i < results.length; i++) { + arcAngle = calcArcAngle(results[i], totalTests); + drawArc(startAngle, arcAngle); + drawLabels(calcResultsPercentage(results[i], totalTests), startAngle, arcAngle); + startAngle += arcAngle; + } + + ImageIO.write(bitmap, "png", new File(fileName)); + } + + /** + * @param testCount + * @param totalTests + * @return + */ + private float calcArcAngle(int testCount, int totalTests) { + return (360.0f * testCount) / totalTests; + } + + /** + * @param testCount + * @param totalTests + * @return + */ + private int calcResultsPercentage(int testCount, int totalTests) { + return (int)((100.0f * testCount) / totalTests); + } + + /** + * @param graphSize + */ + private void setupGeometry(Dimension graphSize) { + this.width = graphSize.width; + this.height = graphSize.height; + this.arcX = ARC_BORDER; + this.arcY = ARC_BORDER; + this.arcWidth = this.width - (ARC_BORDER << 1); + this.arcHeight = this.height - (ARC_BORDER << 1); + } + + /** + * @return + */ + private BufferedImage createBitmap() { + return new BufferedImage(this.width, this.height, BufferedImage.TYPE_4BYTE_ABGR); + } + + /** + * @param bitmap + */ + private void setGraphics(BufferedImage bitmap) { + this.graphics = (Graphics2D) bitmap.getGraphics(); + setRenderingHints(); + } + + /** + * Set the required rendering hints. + */ + private void setRenderingHints() { + this.graphics.addRenderingHints(new RenderingHints(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)); + this.graphics.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)); + } + + /** + * + */ + private void clearCanvas() { + final int rectWidth = this.width - 2; + final int rectHeight = this.height - 2; + this.graphics.setColor(Color.black); + this.graphics.setBackground(Color.white); + this.graphics.clearRect(1, 1, rectWidth, rectHeight); + } + + /** + * @param startAngle + * @param arcAngle + */ + private void drawArc(float startAngle, float arcAngle) { + final int centerX = this.width >> 1; + final int centerY = this.height >> 1; + final int radius = this.arcHeight >> 1; + double x1 = centerX + radius * Math.cos(Math.PI * startAngle / 180.0); + double y1 = centerY - radius * Math.sin(Math.PI * startAngle / 180.0); + //double x2 = centerX + radius * Math.cos(startAngle + arcAngle); + //double y2 = centerY + radius * Math.sin(startAngle + arcAngle); + this.graphics.setColor(Color.black); + this.graphics.drawArc(this.arcX, this.arcY, this.arcWidth, this.arcHeight, (int)startAngle, (int)arcAngle + 1); + this.graphics.drawLine(centerX, centerY, (int)x1, (int)y1); + } + + /** + * @param percentage + * @param startAngle + * @param arcAngle + */ + private void drawLabels(int percentage, float startAngle, float arcAngle) { + final int centerX = this.width >> 1; + final int centerY = this.height >> 1; + final int radius = (this.arcHeight >> 1) + 15; + final float angle = startAngle + arcAngle / 2.0f; + double x1 = centerX + radius * Math.cos(Math.PI * angle / 180.0); + double y1 = centerY - radius * Math.sin(Math.PI * angle / 180.0); + // TODO: getStringBounds or something like it would be much better + x1 -= 8; + this.graphics.drawString(percentage + "%", (int)x1, (int)y1); + } + + /** + * @param arcColor + * @param startAngle + * @param arcAngle + */ + private void fillArc(Color arcColor, float startAngle, float arcAngle) { + this.graphics.setColor(arcColor); + this.graphics.fillArc(this.arcX, this.arcY, this.arcWidth, this.arcHeight, (int)startAngle, (int)arcAngle + 1); + } + + /** + * @param args + * @throws IOException + */ + public static void main(String[] args) throws IOException { + Dimension graphSize = new Dimension(256, 256); + TestResult testResult = new TestResult(100, 10, 5, 20); + new ResultsGraphGenerator().generateGraph(testResult, graphSize, "graph.png"); + } + +}