package StevensLevel.screens; import java.util.Map; import java.util.Timer; import StevensLevel.listeners.ScreenChangeListener; import StevensLevel.listeners.ScreenUpdateListener; import StevensLevel.listeners.StevensLevelViewListener; import common.condition.ConditionMaps; import common.condition.DotHueType; import common.condition.DotStyleType; import correlation.Distribution2D; import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.BufferedImage; import java.util.HashMap; import java.util.TimerTask; import render.GraphStyleSheet; import screens.ManyCorrelationScreen; import util.Util; import static StevensLevel.EventBusHelper.*; /** *Screen which generates three correlation graphs as output. Each image is cached separately to avoid repeated work/calculations from being performed * when it is possible to avoid extra work. * @author Tristan Goffman(tgoffman@gmail.com) */ public class TaskScreen extends ManyCorrelationScreen implements StevensLevelViewListener { final int TIMERTASK_WAIT = 1200; private final double DEF_ERROR = 0.0001; private int totGWidth = (int) (width * 0.6); //width taking up by graphs private int remWidth = width - totGWidth; //width measurements private int padInner = (remWidth / 7); private int offsetLeft = padInner * 2; private int gWidth = totGWidth / 3; //height measurements private int gHeight = gWidth; private int offTop = (height - gHeight) / 2; //Timer for sending off screen needs re-writing events protected Timer deferredNotify = null; private Map<Graphs, GraphStyleSheet> latestUpdates = new HashMap<Graphs, GraphStyleSheet>(3); public TaskScreen() { listen(this, StevensLevelViewListener.class); } /** * Data object to hold update information for a point graph which draws different correlation levels. * Members(correlation value, number of points to draw) */ public static class StevensLevelUpdateViewEvent { public double corr; public int numPoints; public Graphs graph; public GraphStyleSheet stylesheet; public StevensLevelUpdateViewEvent(double c, int pts, Graphs graph, GraphStyleSheet sheet) { this.corr = c; this.numPoints = pts; this.graph = graph; this.stylesheet = sheet; } } /** * Take a 'payload' object and using the data found within updates a particular graph within this * screen. After update the screen is denoted as dirty and a draw will be written out at a later time. * @param payload */ public void update(StevensLevelUpdateViewEvent payload) { /** * Takes an id (enum) of a graph within this screen and updates the distribution with the information held within. */ Distribution2D dist = getDistribution(payload.graph); if (dist != null) { dist.turnIntoTransformedCorrelatedGaussian(payload.corr, payload.numPoints, DEF_ERROR); //update distribution (re-calculate points) } latestUpdates.put(payload.graph, payload.stylesheet); setDirty(true); } /** * Enum to describe the different graphs painted on this particular screen. */ public enum Graphs { HIGH, USER_DEFINED, LOW } protected Image generateImage() { BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = bi.createGraphics(); setGraphicDefaults(g2); drawImage(Graphs.HIGH, g2); drawImage(Graphs.USER_DEFINED, g2); drawImage(Graphs.LOW, g2); //System.out.println("R = " + mydist.getPearsonCorrelation()); // Free resources g2.dispose(); return Util.toImage(bi); } public Image getImage() { if (!isDirty() && currentImage != null) { return currentImage; } setDirty(false); return generateImage(); } /** * Draws a single distrubtion into its spot on the Graphics2D object given. * @param graph * @param g */ private void drawImage(Graphs graph, Graphics2D g) { Distribution2D dist = getDistribution(graph); GraphStyleSheet styles = latestUpdates.get(graph); // Draw the distribution in the centre of the screen Image im; if (styles != null) { dist.setDrawAxis(styles.isAxisOn()); dist.setDrawLabels(styles.isLabelsOn()); im = dist.getImage(gWidth, gHeight, dist.size(), styles.getDotScaling(),styles.getDotSize(), styles.getDotStyle(), styles.getDotHue()); } else { //backup drawing when map is missing stylesheets im = dist.getImage(gWidth, gHeight, dist.size(), 1, 3, DotStyleType.Filled, DotHueType.Black); } int x = 0; int y = 0; switch (graph) { case HIGH: //Right x = offsetLeft + 2 * (gWidth + padInner); break; case USER_DEFINED: //Middle x = offsetLeft + gWidth + padInner; break; case LOW: //Left x = offsetLeft; break; } y = offTop; g.drawImage(im, x, y, null); } }