import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
-import java.util.Vector;
+import java.util.List;
public class RotatableCanvas extends Panel implements MouseListener,
MouseMotionListener, KeyListener, RotatableCanvasI
int npoint;
- Vector<SequencePoint> points;
+ List<SequencePoint> points;
Point[] orig;
}
@Override
- public void setPoints(Vector<SequencePoint> points, int npoint)
+ public void setPoints(List<SequencePoint> points, int npoint)
{
this.points = points;
this.npoint = npoint;
for (int i = 0; i < npoint; i++)
{
- SequencePoint sp = points.elementAt(i);
+ SequencePoint sp = points.get(i);
orig[i] = sp.coord;
}
{
for (int i = 0; i < npoint; i++)
{
- SequencePoint sp = points.elementAt(i);
+ SequencePoint sp = points.get(i);
SequenceI sequence = sp.getSequence();
Color sequenceColour = av.getSequenceColour(sequence);
g.setColor(
{
if (evt.getKeyCode() == KeyEvent.VK_UP)
{
- scalefactor = (float) (scalefactor * 1.1);
- scale = findScale();
+ zoom(1.1f);
}
else if (evt.getKeyCode() == KeyEvent.VK_DOWN)
{
- scalefactor = (float) (scalefactor * 0.9);
- scale = findScale();
+ zoom(0.9f);
}
else if (evt.getKeyChar() == 's')
{
int xPos = evt.getX();
int yPos = evt.getY();
- RotatableMatrix rotmat = new RotatableMatrix();
-
- rotmat.rotate(yPos - mouseY, Axis.X);
- rotmat.rotate(xPos - mouseX, Axis.Y);
-
- for (int i = 0; i < npoint; i++)
+ if (xPos == mouseX && yPos == mouseY)
{
- SequencePoint sp = points.elementAt(i);
- sp.translateBack(centre);
-
- // Now apply the rotation matrix
- sp.coord = rotmat.vectorMultiply(sp.coord);
-
- // Now translate back again
- sp.translate(centre);
+ return;
}
- for (int i = 0; i < 3; i++)
- {
- axisEndPoints[i] = rotmat.vectorMultiply(axisEndPoints[i]);
- }
- mouseX = xPos;
- mouseY = yPos;
+ int xDelta = xPos - mouseX;
+ int yDelta = yPos - mouseY;
- paint(this.getGraphics());
+ rotate(xDelta, yDelta);
+ repaint();
}
public void rectSelect(int x1, int y1, int x2, int y2)
// boolean changedSel = false;
for (int i = 0; i < npoint; i++)
{
- SequencePoint sp = points.elementAt(i);
+ SequencePoint sp = points.get(i);
int tmp1 = (int) ((sp.coord.x - centre.x) * scale
+ getSize().width / 2.0);
int tmp2 = (int) ((sp.coord.y - centre.y) * scale
for (int i = 0; i < npoint; i++)
{
- SequencePoint sp = points.elementAt(i);
+ SequencePoint sp = points.get(i);
int px = (int) ((sp.coord.x - centre.x) * scale)
+ halfwidth;
int py = (int) ((sp.coord.y - centre.y) * scale)
if (found != -1)
{
- return points.elementAt(found).getSequence();
+ return points.get(found).getSequence();
}
else
{
resetAxes();
}
+ @Override
+ public void zoom(float factor)
+ {
+ if (factor > 0f)
+ {
+ scalefactor *= factor;
+ }
+ scale = findScale();
+ }
+
+ @Override
+ public void rotate(float x, float y)
+ {
+ if (x == 0f && y == 0f)
+ {
+ return;
+ }
+
+ /*
+ * get the identity transformation...
+ */
+ RotatableMatrix rotmat = new RotatableMatrix();
+
+ /*
+ * rotate around the X axis for change in Y
+ * (mouse movement up/down); note we are equating a
+ * number of pixels with degrees of rotation here!
+ */
+ if (y != 0)
+ {
+ rotmat.rotate(y, Axis.X);
+ }
+
+ /*
+ * rotate around the Y axis for change in X
+ * (mouse movement left/right)
+ */
+ if (x != 0)
+ {
+ rotmat.rotate(x, Axis.Y);
+ }
+
+ /*
+ * apply the composite transformation to sequence points
+ */
+ for (int i = 0; i < npoint; i++)
+ {
+ SequencePoint sp = points.get(i);
+ sp.translate(-centre.x, -centre.y, -centre.z);
+
+ // Now apply the rotation matrix
+ sp.coord = rotmat.vectorMultiply(sp.coord);
+
+ // Now translate back again
+ sp.translate(centre.x, centre.y, centre.z);
+ }
+
+ /*
+ * rotate the x/y/z axis positions
+ */
+ for (int i = 0; i < DIMS; i++)
+ {
+ axisEndPoints[i] = rotmat.vectorMultiply(axisEndPoints[i]);
+ }
+ }
+
}
import jalview.datamodel.SequencePoint;
import jalview.math.RotatableMatrix;
import jalview.math.RotatableMatrix.Axis;
-import jalview.util.ColorUtils;
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
-import java.util.Vector;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
import javax.swing.JPanel;
import javax.swing.ToolTipManager;
* drawn, and rotated or zoomed with the mouse
*/
public class RotatableCanvas extends JPanel implements MouseListener,
- MouseMotionListener, KeyListener, RotatableCanvasI
+ MouseMotionListener, KeyListener, RotatableCanvasI,
+ MouseWheelListener
{
+ private static final float ZOOM_OUT = 0.9f;
+
+ private static final float ZOOM_IN = 1.1f;
+
+ /*
+ * pixels distance within which tooltip shows sequence name
+ */
+ private static final int NEARBY = 3;
+
+ private static final List<String> AXES = Arrays.asList("x", "y", "z");
+
+ private static final Color AXIS_COLOUR = Color.yellow;
+
private static final int DIMS = 3;
- // RubberbandRectangle rubberband;
boolean drawAxes = true;
- int mouseX = 0;
+ int mouseX;
- int mouseY = 0;
+ int mouseY;
Image img;
Graphics ig;
- Dimension prefsize;
-
- Point centre;
+ Dimension prefSize;
- float[] width = new float[DIMS];
-
- float[] max = new float[DIMS];
-
- float[] min = new float[DIMS];
+ /*
+ * the min-max [x, y, z] values of sequence points when the points
+ * were set on the object, or when the view is reset;
+ * x and y ranges are not recomputed as points are rotated, as this
+ * would make scaling (zoom) unstable, but z ranges are (for correct
+ * graduated colour brightness based on z-coordinate)
+ */
+ float[] seqMin;
- float maxwidth;
+ float[] seqMax;
- float scale;
+ /*
+ * a scale factor used in drawing; when equal to 1, the points span
+ * half the available width or height (whichever is less); increase this
+ * factor to zoom in, decrease it to zoom out
+ */
+ float scaleFactor;
int npoint;
- Vector<SequencePoint> points;
-
- Point[] orig;
+ /*
+ * sequences and their (x, y, z) PCA dimension values
+ */
+ List<SequencePoint> sequencePoints;
+ /*
+ * x, y, z axis end points (PCA dimension values)
+ */
Point[] axisEndPoints;
- int startx;
-
- int starty;
-
- int lastx;
-
- int lasty;
-
- int rectx1;
-
- int recty1;
-
- int rectx2;
-
- int recty2;
-
- float scalefactor = 1;
+ // fields for 'select rectangle' (JAL-1124)
+ // int rectx1;
+ // int recty1;
+ // int rectx2;
+ // int recty2;
AlignmentViewport av;
AlignmentPanel ap;
- boolean showLabels = false;
+ boolean showLabels;
- Color bgColour = Color.black;
+ Color bgColour;
- boolean applyToAllViews = false;
-
- boolean first = true;
+ boolean applyToAllViews;
/**
* Constructor
this.av = panel.av;
this.ap = panel;
axisEndPoints = new Point[DIMS];
+ showLabels = false;
+ applyToAllViews = false;
+ bgColour = Color.BLACK;
+ resetAxes();
- addMouseWheelListener(new MouseWheelListener()
- {
- @Override
- public void mouseWheelMoved(MouseWheelEvent e)
- {
- double wheelRotation = e.getPreciseWheelRotation();
- if (wheelRotation > 0)
- {
- /*
- * zoom in
- */
- scale = (float) (scale * 1.1);
- repaint();
- }
- else if (wheelRotation < 0)
- {
- /*
- * zoom out
- */
- scale = (float) (scale * 0.9);
- repaint();
- }
- }
- });
+ ToolTipManager.sharedInstance().registerComponent(this);
+ addMouseListener(this);
+ addMouseMotionListener(this);
+ addMouseWheelListener(this);
}
/**
}
@Override
- public void setPoints(Vector<SequencePoint> points, int npoint)
+ public void setPoints(List<SequencePoint> points, int np)
{
- this.points = points;
- this.npoint = npoint;
- if (first)
- {
- ToolTipManager.sharedInstance().registerComponent(this);
- ToolTipManager.sharedInstance().setInitialDelay(0);
- ToolTipManager.sharedInstance().setDismissDelay(10000);
- }
- prefsize = getPreferredSize();
- orig = new Point[npoint];
-
- for (int i = 0; i < npoint; i++)
- {
- SequencePoint sp = points.elementAt(i);
- orig[i] = sp.coord;
- }
+ this.sequencePoints = points;
+ this.npoint = np;
+ prefSize = getPreferredSize();
- resetAxes();
+ findWidths();
- findCentre();
- findWidth();
-
- scale = findScale();
- if (first)
- {
- addMouseListener(this);
- addMouseMotionListener(this);
- }
- first = false;
+ scaleFactor = 1f;
}
/**
}
/**
- * Computes and saves the maximum and minimum (x, y, z) positions of any
- * sequence point, and also the min-max range (width) for each dimension, and
- * the maximum width for all dimensions
+ * Computes and saves the min-max ranges of x/y/z positions of the sequence
+ * points
*/
- protected void findWidth()
+ protected void findWidths()
{
- max = new float[DIMS];
- min = new float[DIMS];
-
- max[0] = Float.MIN_VALUE;
- max[1] = Float.MIN_VALUE;
- max[2] = Float.MIN_VALUE;
-
+ float[] max = new float[DIMS];
+ float[] min = new float[DIMS];
+
+ max[0] = -Float.MAX_VALUE;
+ max[1] = -Float.MAX_VALUE;
+ max[2] = -Float.MAX_VALUE;
+
min[0] = Float.MAX_VALUE;
min[1] = Float.MAX_VALUE;
min[2] = Float.MAX_VALUE;
-
- for (SequencePoint sp : points)
+
+ for (SequencePoint sp : sequencePoints)
{
max[0] = Math.max(max[0], sp.coord.x);
max[1] = Math.max(max[1], sp.coord.y);
min[1] = Math.min(min[1], sp.coord.y);
min[2] = Math.min(min[2], sp.coord.z);
}
-
- width[0] = Math.abs(max[0] - min[0]);
- width[1] = Math.abs(max[1] - min[1]);
- width[2] = Math.abs(max[2] - min[2]);
-
- maxwidth = Math.max(width[0], Math.max(width[1], width[2]));
+
+ seqMin = min;
+ seqMax = max;
}
/**
- * DOCUMENT ME!
+ * Answers the preferred size if it has been set, else 400 x 400
*
- * @return DOCUMENT ME!
- */
- protected float findScale()
- {
- int dim;
- int w;
- int height;
-
- if (getWidth() != 0)
- {
- w = getWidth();
- height = getHeight();
- }
- else
- {
- w = prefsize.width;
- height = prefsize.height;
- }
-
- if (w < height)
- {
- dim = w;
- }
- else
- {
- dim = height;
- }
-
- return (dim * scalefactor) / (2 * maxwidth);
- }
-
- /**
- * Computes and saves the position of the centre of the view
- */
- protected void findCentre()
- {
- findWidth();
-
- float x = (max[0] + min[0]) / 2;
- float y = (max[1] + min[1]) / 2;
- float z = (max[2] + min[2]) / 2;
-
- centre = new Point(x, y, z);
- }
-
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
+ * @return
*/
@Override
public Dimension getPreferredSize()
{
- if (prefsize != null)
+ if (prefSize != null)
{
- return prefsize;
+ return prefSize;
}
else
{
}
/**
- * DOCUMENT ME!
+ * Answers the preferred size
*
- * @return DOCUMENT ME!
+ * @return
+ * @see RotatableCanvas#getPreferredSize()
*/
@Override
public Dimension getMinimumSize()
}
/**
- * DOCUMENT ME!
+ * Repaints the panel
*
* @param g
- * DOCUMENT ME!
*/
@Override
public void paintComponent(Graphics g1)
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
- if (points == null)
+ if (sequencePoints == null)
{
g.setFont(new Font("Verdana", Font.PLAIN, 18));
g.drawString(
}
else
{
- // Only create the image at the beginning -
- if ((img == null) || (prefsize.width != getWidth())
- || (prefsize.height != getHeight()))
+ /*
+ * create the image at the beginning or after a resize
+ */
+ boolean resized = prefSize.width != getWidth()
+ || prefSize.height != getHeight();
+ if (img == null || resized)
{
- prefsize.width = getWidth();
- prefsize.height = getHeight();
-
- scale = findScale();
+ prefSize.width = getWidth();
+ prefSize.height = getHeight();
- // System.out.println("New scale = " + scale);
img = createImage(getWidth(), getHeight());
ig = img.getGraphics();
}
}
/**
- * Resets the view to initial state (no rotation)
+ * Resets the rotation and choice of axes to the initial state (without change
+ * of scale factor)
*/
public void resetView()
{
img = null;
+ findWidths();
resetAxes();
+ repaint();
}
/**
*/
public void drawAxes(Graphics g)
{
+ g.setColor(AXIS_COLOUR);
- g.setColor(Color.yellow);
+ int midX = getWidth() / 2;
+ int midY = getHeight() / 2;
+ float maxWidth = Math.max(Math.abs(seqMax[0] - seqMin[0]),
+ Math.abs(seqMax[1] - seqMin[1]));
+ int pix = Math.min(getWidth(), getHeight());
+ float scaleBy = pix * scaleFactor / (2f * maxWidth);
for (int i = 0; i < DIMS; i++)
{
- g.drawLine(getWidth() / 2, getHeight() / 2,
- (int) ((axisEndPoints[i].x * scale * max[0]) + (getWidth() / 2)),
- (int) ((axisEndPoints[i].y * scale * max[1]) + (getHeight() / 2)));
+ g.drawLine(midX, midY,
+ midX + (int) (axisEndPoints[i].x * scaleBy * seqMax[0]),
+ midY + (int) (axisEndPoints[i].y * scaleBy * seqMax[1]));
}
}
public void drawBackground(Graphics g, Color col)
{
g.setColor(col);
- g.fillRect(0, 0, prefsize.width, prefsize.height);
+ g.fillRect(0, 0, prefSize.width, prefSize.height);
}
/**
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
+ int pix = Math.min(getWidth(), getHeight());
+ float xWidth = Math.abs(seqMax[0] - seqMin[0]);
+ float yWidth = Math.abs(seqMax[1] - seqMin[1]);
+ float maxWidth = Math.max(xWidth, yWidth);
+ float scaleBy = pix * scaleFactor / (2f * maxWidth);
+
+ float[] centre = getCentre();
for (int i = 0; i < npoint; i++)
{
* sequence point colour as sequence id, but
* gray if sequence is currently selected
*/
- SequencePoint sp = points.elementAt(i);
+ SequencePoint sp = sequencePoints.get(i);
Color sequenceColour = getSequencePointColour(sp);
g.setColor(sequenceColour);
int halfwidth = getWidth() / 2;
int halfheight = getHeight() / 2;
- int x = (int) ((sp.coord.x - centre.x) * scale) + halfwidth;
- int y = (int) ((sp.coord.y - centre.y) * scale) + halfheight;
+ int x = (int) ((sp.coord.x - centre[0]) * scaleBy) + halfwidth;
+ int y = (int) ((sp.coord.y - centre[1]) * scaleBy) + halfheight;
g.fillRect(x - 3, y - 3, 6, 6);
if (showLabels)
g.drawString(sp.getSequence().getName(), x - 3, y - 4);
}
}
-
+ if (showLabels)
+ {
+ g.setColor(AXIS_COLOUR);
+ int midX = getWidth() / 2;
+ int midY = getHeight() / 2;
+ Iterator<String> axes = AXES.iterator();
+ for (Point p : axisEndPoints)
+ {
+ int x = midX + (int) (p.x * scaleBy * seqMax[0]);
+ int y = midY + (int) (p.y * scaleBy * seqMax[1]);
+ g.drawString(axes.next(), x - 3, y - 4);
+ }
+ }
// //Now the rectangle
// if (rectx2 != -1 && recty2 != -1) {
// g.setColor(Color.white);
sequenceColour = Color.gray;
}
}
-
- /*
- * graduate from front (brighter) to back (darker)
- */
- sequenceColour = ColorUtils.getGraduatedColour(sp.coord.z, min[2],
- max[2], sequenceColour);
+ if (sp.coord.z < 0f)
+ {
+ sequenceColour = sequenceColour.darker();
+ }
return sequenceColour;
}
@Override
public void keyPressed(KeyEvent evt)
{
- if (evt.getKeyCode() == KeyEvent.VK_UP)
+ int keyCode = evt.getKeyCode();
+
+ if (keyCode == KeyEvent.VK_UP)
{
- scalefactor = (float) (scalefactor * 1.1);
- scale = findScale();
+ zoom(ZOOM_IN);
}
- else if (evt.getKeyCode() == KeyEvent.VK_DOWN)
+ else if (keyCode == KeyEvent.VK_DOWN)
{
- scalefactor = (float) (scalefactor * 0.9);
- scale = findScale();
+ zoom(ZOOM_OUT);
}
else if (evt.getKeyChar() == 's')
{
// Cache.log.warn("DEBUG: Rectangle selection");
// todo not yet enabled as rectx2, recty2 are always -1
- // need to set them in mouseDragged
- if ((rectx2 != -1) && (recty2 != -1))
- {
- rectSelect(rectx1, recty1, rectx2, recty2);
- }
+ // need to set them in mouseDragged; JAL-1124
+ // if ((rectx2 != -1) && (recty2 != -1))
+ // {
+ // rectSelect(rectx1, recty1, rectx2, recty2);
+ // }
}
repaint();
}
@Override
+ public void zoom(float factor)
+ {
+ if (factor > 0f)
+ {
+ scaleFactor *= factor;
+ }
+ }
+
+ @Override
public void mouseClicked(MouseEvent evt)
{
}
mouseX = x;
mouseY = y;
- startx = x;
- starty = y;
-
- rectx1 = x;
- recty1 = y;
-
- rectx2 = -1;
- recty2 = -1;
+ // rectx1 = x;
+ // recty1 = y;
+ // rectx2 = -1;
+ // recty2 = -1;
SequenceI found = findSequenceAtPoint(x, y);
return;
}
+ int xDelta = xPos - mouseX;
+ int yDelta = yPos - mouseY;
+
// Check if this is a rectangle drawing drag
if ((evt.getModifiers() & InputEvent.BUTTON2_MASK) != 0)
{
}
else
{
- /*
- * get the identity transformation...
- */
- RotatableMatrix rotmat = new RotatableMatrix();
+ rotate(xDelta, yDelta);
- /*
- * rotate around the X axis for change in Y
- * (mouse movement up/down); note we are equating a
- * number of pixels with degrees of rotation here!
- */
- if (yPos != mouseY)
- {
- rotmat.rotate(yPos - mouseY, Axis.X);
- }
+ mouseX = xPos;
+ mouseY = yPos;
- /*
- * rotate around the Y axis for change in X
- * (mouse movement left/right)
- */
- if (xPos != mouseX)
- {
- rotmat.rotate(xPos - mouseX, Axis.Y);
- }
+ // findWidths();
- /*
- * apply the composite transformation to sequence points
- */
- for (int i = 0; i < npoint; i++)
- {
- SequencePoint sp = points.elementAt(i);
- sp.translateBack(centre);
+ repaint();
+ }
+ }
- // Now apply the rotation matrix
- sp.coord = rotmat.vectorMultiply(sp.coord);
+ @Override
+ public void rotate(float x, float y)
+ {
+ if (x == 0f && y == 0f)
+ {
+ return;
+ }
- // Now translate back again
- sp.translate(centre);
- }
+ /*
+ * get the identity transformation...
+ */
+ RotatableMatrix rotmat = new RotatableMatrix();
- /*
- * rotate the x/y/z axis positions
- */
- for (int i = 0; i < DIMS; i++)
- {
- axisEndPoints[i] = rotmat.vectorMultiply(axisEndPoints[i]);
- }
+ /*
+ * rotate around the X axis for change in Y
+ * (mouse movement up/down); note we are equating a
+ * number of pixels with degrees of rotation here!
+ */
+ if (y != 0)
+ {
+ rotmat.rotate(y, Axis.X);
+ }
- mouseX = xPos;
- mouseY = yPos;
+ /*
+ * rotate around the Y axis for change in X
+ * (mouse movement left/right)
+ */
+ if (x != 0)
+ {
+ rotmat.rotate(x, Axis.Y);
+ }
+
+ /*
+ * apply the composite transformation to sequence points;
+ * update z min-max range (affects colour graduation), but not
+ * x or y min-max (as this would affect axis scaling)
+ */
+ float[] centre = getCentre();
+ float zMin = Float.MAX_VALUE;
+ float zMax = -Float.MAX_VALUE;
+
+ for (int i = 0; i < npoint; i++)
+ {
+ SequencePoint sp = sequencePoints.get(i);
+ sp.translate(-centre[0], -centre[1], -centre[2]);
+
+ // Now apply the rotation matrix
+ sp.coord = rotmat.vectorMultiply(sp.coord);
+
+ // Now translate back again
+ sp.translate(centre[0], centre[1], centre[2]);
+
+ zMin = Math.min(zMin, sp.coord.z);
+ zMax = Math.max(zMax, sp.coord.z);
+ }
+
+ seqMin[2] = zMin;
+ seqMax[2] = zMax;
- paint(this.getGraphics());
+ /*
+ * rotate the x/y/z axis positions
+ */
+ for (int i = 0; i < DIMS; i++)
+ {
+ axisEndPoints[i] = rotmat.vectorMultiply(axisEndPoints[i]);
}
}
/**
+ * Answers the x/y/z coordinates that are midway between the maximum and
+ * minimum sequence point values
+ *
+ * @return
+ */
+ private float[] getCentre()
+ {
+ float xCentre = (seqMin[0] + seqMax[0]) / 2f;
+ float yCentre = (seqMin[1] + seqMax[1]) / 2f;
+ float zCentre = (seqMin[2] + seqMax[2]) / 2f;
+
+ return new float[] { xCentre, yCentre, zCentre };
+ }
+
+ /**
* Adds any sequences whose displayed points are within the given rectangle to
* the viewport's current selection. Intended for key 's' after dragging to
* select a region of the PCA.
*/
protected void rectSelect(int x1, int y1, int x2, int y2)
{
+ float[] centre = getCentre();
+
for (int i = 0; i < npoint; i++)
{
- SequencePoint sp = points.elementAt(i);
- int tmp1 = (int) (((sp.coord.x - centre.x) * scale)
+ SequencePoint sp = sequencePoints.get(i);
+ int tmp1 = (int) (((sp.coord.x - centre[0]) * scaleFactor)
+ (getWidth() / 2.0));
- int tmp2 = (int) (((sp.coord.y - centre.y) * scale)
+ int tmp2 = (int) (((sp.coord.y - centre[1]) * scaleFactor)
+ (getHeight() / 2.0));
if ((tmp1 > x1) && (tmp1 < x2) && (tmp2 > y1) && (tmp2 < y2))
int halfheight = getHeight() / 2;
int found = -1;
+ int pix = Math.min(getWidth(), getHeight());
+ float xWidth = Math.abs(seqMax[0] - seqMin[0]);
+ float yWidth = Math.abs(seqMax[1] - seqMin[1]);
+ float maxWidth = Math.max(xWidth, yWidth);
+ float scaleBy = pix * scaleFactor / (2f * maxWidth);
+
+ float[] centre = getCentre();
for (int i = 0; i < npoint; i++)
{
- SequencePoint sp = points.elementAt(i);
- int px = (int) ((sp.coord.x - centre.x) * scale)
+ SequencePoint sp = sequencePoints.get(i);
+ int px = (int) ((sp.coord.x - centre[0]) * scaleBy)
+ halfwidth;
- int py = (int) ((sp.coord.y - centre.y) * scale)
+ int py = (int) ((sp.coord.y - centre[1]) * scaleBy)
+ halfheight;
- if ((Math.abs(px - x) < 3) && (Math.abs(py - y) < 3))
+ if ((Math.abs(px - x) < NEARBY) && (Math.abs(py - y) < NEARBY))
{
found = i;
break;
if (found != -1)
{
- return points.elementAt(found).getSequence();
+ return sequencePoints.get(found).getSequence();
}
else
{
return new AlignmentPanel[] { ap };
}
}
+
+ public Color getBackgroundColour()
+ {
+ return bgColour;
+ }
+
+ /**
+ * Zooms in or out in response to mouse wheel movement
+ */
+ @Override
+ public void mouseWheelMoved(MouseWheelEvent e)
+ {
+ double wheelRotation = e.getPreciseWheelRotation();
+ if (wheelRotation > 0)
+ {
+ zoom(ZOOM_IN);
+ repaint();
+ }
+ else if (wheelRotation < 0)
+ {
+ zoom(ZOOM_OUT);
+ repaint();
+ }
+ }
+
+ /**
+ * Answers the sequence point minimum [x, y, z] values. Note these are derived
+ * when sequence points are set, but x and y values are not updated on
+ * rotation (because this would result in changes to scaling).
+ *
+ * @return
+ */
+ public float[] getSeqMin()
+ {
+ return seqMin;
+ }
+
+ /**
+ * Answers the sequence point maximum [x, y, z] values. Note these are derived
+ * when sequence points are set, but x and y values are not updated on
+ * rotation (because this would result in changes to scaling).
+ *
+ * @return
+ */
+ public float[] getSeqMax()
+ {
+ return seqMax;
+ }
+
+ /**
+ * Sets the minimum and maximum [x, y, z] positions for sequence points. For
+ * use when restoring a saved PCA from state data.
+ *
+ * @param min
+ * @param max
+ */
+ public void setSeqMinMax(float[] min, float[] max)
+ {
+ seqMin = min;
+ seqMax = max;
+ }
}