/* * ScatterPlot.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * BEAST is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.app.gui.chart; import dr.stats.Variate; import java.awt.*; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.List; import java.util.Set; import java.util.Vector; /** * Description: A scatter plot. * * @author Andrew Rambaut * @author Alexei Drummond * @version $Id: ScatterPlot.java,v 1.10 2005/05/24 20:25:59 rambaut Exp $ */ public class ScatterPlot extends Plot.AbstractPlot { protected Vector<Rectangle2D> markBounds = null; protected Stroke hilightedMarkStroke = new BasicStroke(0.5f); protected Paint hilightedMarkPaint = Color.black; protected Paint hilightedMarkFillPaint = Color.blue; /** * Constructor */ public ScatterPlot(Variate.N xData, Variate.N yData) { super(xData, yData); setMarkStyle(CIRCLE_MARK, 5, new BasicStroke(1), Color.black, Color.yellow); setHilightedMarkStyle(new BasicStroke(1), Color.black, Color.blue); } /** * Constructor */ public ScatterPlot(List<Double> xData, List<Double> yData) { super(xData, yData); setMarkStyle(CIRCLE_MARK, 5, new BasicStroke(1), Color.black, Color.yellow); setHilightedMarkStyle(new BasicStroke(1), Color.black, Color.blue); } /** * Set mark style */ public void setHilightedMarkStyle(Stroke hilightedMarkStroke, Paint hilightedMarkPaint, Paint hilightedMarkFillPaint) { this.hilightedMarkStroke = hilightedMarkStroke; this.hilightedMarkPaint = hilightedMarkPaint; this.hilightedMarkFillPaint = hilightedMarkFillPaint; } /** * Draw a mark transforming co-ordinates to each axis */ protected void drawMark(Graphics2D g2, float x, float y, Color color) { Rectangle2D bounds = mark.getBounds2D(); float w = (float) bounds.getWidth(); float h = (float) bounds.getHeight(); x = x - (w / 2); y = y - (h / 2); g2.translate(x, y); if (color == null) { if (markFillPaint != null) { g2.setPaint(markFillPaint); g2.fill(mark); } } else { g2.setPaint(color); g2.fill(mark); } g2.setPaint(markPaint); g2.setStroke(markStroke); g2.draw(mark); g2.translate(-x, -y); Rectangle2D rect = new Rectangle2D.Float(x, y, w, h); markBounds.add(rect); } /** * Draw a mark transforming co-ordinates to each axis */ protected void drawMarkHilighted(Graphics2D g2, float x, float y) { Rectangle2D bounds = mark.getBounds2D(); float w = (float) bounds.getWidth(); float h = (float) bounds.getHeight(); x = x - (w / 2); y = y - (h / 2); g2.translate(x, y); if (hilightedMarkFillPaint != null) { g2.setPaint(hilightedMarkFillPaint); g2.fill(mark); } g2.setPaint(hilightedMarkPaint); g2.setStroke(hilightedMarkStroke); g2.draw(mark); g2.translate(-x, -y); Rectangle2D rect = new Rectangle2D.Float(x, y, w, h); markBounds.add(rect); } /** * Paint data series */ protected void paintData(Graphics2D g2, Variate.N xData, Variate.N yData) { float x, y; markBounds = new java.util.Vector<Rectangle2D>(); Set<Integer> selectedPoints = getSelectedPoints(); int n = xData.getCount(); if (colours != null && colours.size() == n) { for (int i = 0; i < n; i++) { x = (float) transformX(((Number) xData.get(i)).doubleValue()); y = (float) transformY(((Number) yData.get(i)).doubleValue()); if (selectedPoints.contains(i)) { drawMarkHilighted(g2, x, y); } else { drawMark(g2, x, y, colours.get(i)); } } } else { for (int i = 0; i < n; i++) { x = (float) transformX(((Number) xData.get(i)).doubleValue()); y = (float) transformY(((Number) yData.get(i)).doubleValue()); if (selectedPoints.contains(i)) { drawMarkHilighted(g2, x, y); } else { drawMark(g2, x, y, null); } } } } /** * A point on the plot has been clicked */ public void pointClicked(Point2D point, boolean isShiftDown) { double x = untransformX(point.getX()); double y = untransformY(point.getY()); if (markBounds != null) { int mark = -1; for (int i = 0; i < markBounds.size(); i++) { if ((markBounds.get(i)).contains(point)) { mark = i; break; } } fireMarkClickedEvent(mark, x, y, isShiftDown); } firePointClickedEvent(x, y, isShiftDown); } }