Class SequenceGraph
- java.lang.Object
-
- com.biomatters.geneious.publicapi.plugin.SequenceGraph
-
- All Implemented Interfaces:
java.awt.event.MouseListener
,java.awt.event.MouseMotionListener
,java.util.EventListener
public abstract class SequenceGraph extends java.lang.Object implements java.awt.event.MouseListener, java.awt.event.MouseMotionListener
A sequence graph is displayed in the SequenceViewer. For example, hydrophobicity or similarity or sequence logo graphs. A SequenceGraph is created via aSequenceGraphFactory
which is provided from a plugin viaGeneiousPlugin.getSequenceGraphFactories()
. Simple SequenceGraphs (for example, hydrophobicity and similarity) can be created by via helper functionality inDefaultSequenceGraphFactories
. More complex graphs (such as the sequence logos) are created via your ownSequenceGraphFactory
andSequenceGraph
implementations.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
SequenceGraph.Location
static class
SequenceGraph.SequencePropertyRetriever
Provides additional information about the sequence(s) (e.g.
-
Constructor Summary
Constructors Constructor Description SequenceGraph()
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description abstract void
draw(GeneiousGraphics2D graphics, int startResidue, int endResidue, int startX, int startY, int endX, int endY, double averageResidueWidth, int previousSectionWidth, int nextSectionWidth, int previousSectionResidueCount, int nextSectionResidueCount)
Draws a section of this graph.void
drawScaleBar(GeneiousGraphics2D graphics, int startX, int startY, int endX, int endY)
Optionally draw a scale bar next to the name of the graph.int
getApproximateCalculationWorkRequiredPerResidue()
Estimate an amount of work required to calculate graph values per residue.protected java.awt.Color
getCurrentBackgroundColorFor(char residue)
Get the current background color for a given residue using the current sequence viewer color scheme.protected java.awt.Color
getCurrentForegroundColorFor(char residue)
Get the current foreground color for a given residue using the current sequence viewer color scheme.java.awt.Cursor
getCursor()
Returns a cursor that will appear when the mouse is over the graph.int
getDefaultHeight()
Supply a default height for this graph.SequenceGraph.Location
getDefaultLocation()
Determines whether this graph should appear above or below the sequence residues.boolean
getDefaultVisibility()
Returns whether this graph is visible by default.java.lang.String
getDescription()
Provides a more verbose description for this graph thangetName()
.java.lang.String
getLegendName()
Provides an alternative name displayed to the user.abstract java.lang.String
getName()
Provides the name displayed to the user.Options
getOptions()
Provides options associated with this graph.int
getScaleBarWidth()
Supply a width of the scale bar for this graph.SequenceGraph.SequencePropertyRetriever
getSequencePropertyRetriever()
Gets a SequencePropertyRetriever for providing additional information (e.g.java.lang.Double
getValue(int position)
boolean
hasValues()
boolean
isAnimated()
boolean
isProOnly()
Does this graph require an active license? The default implementation returns false.void
mouseClicked(java.awt.event.MouseEvent event)
The mouse has been clicked in this sequence graph.void
mouseDragged(java.awt.event.MouseEvent event)
The mouse has been dragged in this sequence graph (with a drag starting inside the graph, not outside it).void
mouseEntered(java.awt.event.MouseEvent event)
The mouse has left this sequence graph.void
mouseExited(java.awt.event.MouseEvent event)
The mouse has left this sequence graph.void
mouseMoved(java.awt.event.MouseEvent event)
The mouse has been moved in this sequence graph.void
mousePressed(java.awt.event.MouseEvent event)
The mouse has been pressed in this sequence graph.void
mouseReleased(java.awt.event.MouseEvent event)
The mouse has been released in this sequence graph.void
performBackgroundCalculations(jebl.util.ProgressListener progress)
Perform some background calculations in a non AWT thread before this graph is drawn.void
setCurrentColorScheme(java.awt.Color[] backgroundColors, java.awt.Color[] foregroundColors)
Sets the current color scheme used by the sequence viewer.void
setPropertyRetrievalCallback(SequenceGraph.SequencePropertyRetriever sequencePropertyRetriever)
Sets the SequencePropertyRetriever that will be returned from future calls togetSequencePropertyRetriever()
.void
setResidues(java.util.List<java.lang.CharSequence> sequences, java.util.List<NucleotideGraph> nucleotideGraphs, boolean ignoreEndGaps)
Sets the residues of the sequence or alignment document that the graph applies to.boolean
supportsRenderingLargeRegions()
True if the graph supports rendering large regions at one time.boolean
supportsSlidingWindows()
Determine if the "sliding window size" option should apply to this graph.
-
-
-
Method Detail
-
getName
public abstract java.lang.String getName()
Provides the name displayed to the user. For example "hydrophobicity".- Returns:
- the name
-
getLegendName
public java.lang.String getLegendName()
Provides an alternative name displayed to the user. This is the name displayed to the left of the graph in the SequenceViewer.getName()
is displayed in the controls on the right. For example, the chromatogram graph does not display its name to the left of the graph (since it is obvious what graph it is) The default implementation returnsgetName()
.- Returns:
- an alternative name displayed to the user or "" to provide no alternative name.
-
getDescription
public java.lang.String getDescription()
Provides a more verbose description for this graph thangetName()
. Displayed as a tool tip.- Returns:
- a description for this graph or null to provide no description.
-
setResidues
public void setResidues(java.util.List<java.lang.CharSequence> sequences, java.util.List<NucleotideGraph> nucleotideGraphs, boolean ignoreEndGaps)
Sets the residues of the sequence or alignment document that the graph applies to. The SequenceGraph should remember these residues for future calls todraw
. This method will only be called on residue based graphs (seeSequenceGraphFactory
). Only residue based graphs should and must implement this method. This method will be called each time the user modifies a sequence or alignment (potentially after each residue is typed). Therefore any implementation of this method should do very little work and instead calculate anything necessary on demand when drawing. Further information about the sequences (e.g. sequences names) can be obtained viagetSequencePropertyRetriever()
.- Parameters:
sequences
- The sequence residues the graph applies to. If this is not an alignment graph then this will be a one element array. For those wondering why this is a CharSequence rather than a String, it is so that sequence editing can rapidly insert residues into large sequences without being forced to construct new String instances every time a residue is typed.nucleotideGraphs
- An array equal in length to residues.length. Each element will be non-null if that sequence has an associated NucleotideGraph (chromatogram trace).ignoreEndGaps
- If gaps at either end of sequences should be ignored when calcuating the graph.
-
getCursor
public java.awt.Cursor getCursor()
Returns a cursor that will appear when the mouse is over the graph. Return null to have the sequence viewer choose its own cursor- Returns:
- the cursor, or null
-
setPropertyRetrievalCallback
public final void setPropertyRetrievalCallback(SequenceGraph.SequencePropertyRetriever sequencePropertyRetriever)
Sets the SequencePropertyRetriever that will be returned from future calls togetSequencePropertyRetriever()
. A plugin should not need not call this method. The sequence viewer sets it immediately after being given the graph by aSequenceGraphFactory
.- Parameters:
sequencePropertyRetriever
- the SequencePropertyRetriever that will be returned from future calls togetSequencePropertyRetriever()
.
-
getSequencePropertyRetriever
public final SequenceGraph.SequencePropertyRetriever getSequencePropertyRetriever()
Gets a SequencePropertyRetriever for providing additional information (e.g. the sequence name) about the sequence(s) for which the graph is being drawn.- Returns:
- a SequencePropertyRetriever for providing additional information (e.g. the sequence name) about the sequence(s) for which the graph is being drawn.
-
draw
public abstract void draw(GeneiousGraphics2D graphics, int startResidue, int endResidue, int startX, int startY, int endX, int endY, double averageResidueWidth, int previousSectionWidth, int nextSectionWidth, int previousSectionResidueCount, int nextSectionResidueCount)
Draws a section of this graph. Drawing is allowed between startX and endX, startY and endY inclusive. Usually, startResidue and endResidue will be identical. These only become different when zoomed out far enough such that multiple residues would be condensed into a single horizontal coordinate or this graph returns true fromsupportsRenderingLargeRegions()
, and/orsupportsSlidingWindows()
and the user has set the sliding window size is something greater than 1. For example this method may receive calls like:draw(g, 0, 0, 10, 0, 12, 20, 3.5, 4, 4, 1, 1)
// draw a graph section for residue 0 between x coordinates 10 and 12 inclusive.draw(g, 1, 1, 13, 0, 16, 20, 3.5, 3, 3, 1, 1)
// draw a graph section for residue 1 between x coordinates 13 and 16 inclusive.draw(g, 2, 2, 17, 0, 19, 20, 3.5, 4, 4, 1, 1)
// draw a graph section for residue 2 between x coordinates 17 and 19 inclusive.
draw(g, 0, 1, 10, 0, 10, 20, 0.4, 1, 1, 2, 3)
// draw a graph section averaged over residues 0 and 1 at x coordinate 10.draw(g, 2, 4, 11, 0, 11, 20, 0.4, 1, 1, 2, 2)
// draw a graph section averaged over residues 2 to 4 at x coordinate 11.draw(g, 5, 6, 12, 0, 12, 20, 0.4, 1, 1, 3, 2)
// draw a graph section averaged over residues 5 and 6 at x coordinate 12.
supportsRenderingLargeRegions()
draw(g, 0, 99, 10, 10, 389, 20, 3.8, 0, 0, 0, 0)
// draw a graph section for residues 0 to 99 between x coordinates 10 and 389 inclusive.
Graphics.drawRect(int, int, int, int)
rather thanGraphics2D.draw(java.awt.Shape)
The reason is that on large sequences, where co-ordinates can be in the millions, floating point numbers do not provide sufficient accuracy to draw in the correct location. Alternatively, translate the graphics by -startX,-startY before drawing using floating point accuracy, then undo the translation afterwards.- Parameters:
graphics
- graphics to draw tostartResidue
- the first residue number which this graph section applies to (0 being the first residue)endResidue
- the last residue number (inclusive) which this graph section applies to (0 being the first residue)startX
- leftmost coordinate the graph section is allowed to render to.startY
- topmost coordinate the graph section is allowed to render to.endX
- rightmost coordinate the graph section is allowed to render to.endY
- bottommost coordinate the graph section is allowed to render to.averageResidueWidth
- the average horizontal width per residue. Useful in situations where you want to vary behaviour depending on the width available. The difference between startX and endX is not useful for doing this as it may alternate between 1 and 2 if for example the average width is 2.5. For example, the sequence logo graph does not wish to render text when then average width is less than 3.previousSectionWidth
- (endX-startX+1) for the section drawn immediately to the left of this section. Useful when drawing line graphs between sections and we need to know exactly where the previous section was rendered. If there is no section immediately to the left of this section, this value is the section width of this section.nextSectionWidth
- (endX-startX+1) for the section drawn immediately to the right of this section. Useful when drawing line graphs between sections and we need to know exactly where the previous section was rendered. If there is no section immediately to the right of this section, this value is the section width of this section.previousSectionResidueCount
- (endResidue-startResidue+1) for the section drawn immediately to the left of this section. Useful when drawing line graphs between sections and we need to know exactly where the previous section was rendered. If there is no section immediately to the left of this section, this value is the residue count of this section.nextSectionResidueCount
- (endResidue-startResidue+1) for the section drawn immediately to the right of this section. Useful when drawing line graphs between sections and we need to know exactly where the previous section was rendered. If there is no section immediately to the right of this section, this value is the residue count of this section.
-
hasValues
public boolean hasValues()
- Returns:
- true if this graph provides values from
getValue(int)
. These graphs will be exportable to CSV or WIG files and their value will be displayed in the sequence viewer when the mouse is over the a point in the graph. - Since:
- API 4.700 (Geneious 7.0.0)
- See Also:
getValue(int)
-
getValue
public java.lang.Double getValue(int position)
- Parameters:
position
- the 0-based position in the graph to get the value for- Returns:
- the value of the graph at the given position. Graphs that return false from
hasValues()
will always return null. Graphs that return true fromhasValues()
may return null for position which they don't assign a value to. - Since:
- API 4.700 (Geneious 7.0.0)
- See Also:
hasValues()
-
getDefaultHeight
public int getDefaultHeight()
Supply a default height for this graph. The user is able to customise this.- Returns:
- a default height for this graph in graphics coordinates. The default implementation returns 25.
-
getDefaultVisibility
public boolean getDefaultVisibility()
Returns whether this graph is visible by default.- Returns:
- true if this graph is visible by default. The default implementation returns true.
-
getScaleBarWidth
public int getScaleBarWidth()
Supply a width of the scale bar for this graph.- Returns:
- a width in graphics coordinates of the scale bar for this graph or 0 of this graph is not have a scale bar. The default implementation returns 0.
-
drawScaleBar
public void drawScaleBar(GeneiousGraphics2D graphics, int startX, int startY, int endX, int endY)
Optionally draw a scale bar next to the name of the graph. Any graph which it wishes to implement this should overridegetScaleBarWidth()
to return something greater than 0. The default implementation of this method does nothing.- Parameters:
graphics
- graphics to draw tostartX
- leftmost coordinate the scale bar is allowed to render to.startY
- topmost coordinate the scale bar is allowed to render to.endX
- rightmost coordinate the scale bar is allowed to render to.endY
- bottommost coordinate the scale bar is allowed to render to.
-
supportsSlidingWindows
public boolean supportsSlidingWindows()
Determine if the "sliding window size" option should apply to this graph. The default implementation returns false. For example, if the sliding window size is 5, then thedraw
method may receive calls like:draw(0,4,g,10,0,12,20,3.0)
// draw a graph section averaged over residues 0 to 4 between x coordinates 10 and 12 inclusive.draw(1,5,g,13,0,15,20,3.0)
// draw a graph section averaged over residues 1 to 5 between x coordinates 13 and 15 inclusive.draw(2,6,g,16,0,18,20,3.0)
// draw a graph section averaged over residues 2 to 6 between x coordinates 16 and 18 inclusive.
- Returns:
- true if the "sliding window size" option should apply to this graph.
- See Also:
draw(GeneiousGraphics2D,int,int,int,int,int,int,double,int,int,int,int)
-
isAnimated
public boolean isAnimated()
- Returns:
- true if this graph uses animation. If so, the sequence viewer will regularly repaint it.
- Since:
- API 4.61 (Geneious 5.6.1)
-
getOptions
public Options getOptions()
Provides options associated with this graph. The graph's constructor should create the options and store them in a field variable. This method should then return this field and the rendering/calculation code should check the option values each time it is called. The Sequence View will automatically re-draw the graph if the options are changed. The default implementation returns null.- Returns:
- some options, or null if this graph has no options.
-
supportsRenderingLargeRegions
public boolean supportsRenderingLargeRegions()
True if the graph supports rendering large regions at one time.- Returns:
- whether this graph supports rendering large regions. The default implementation returns false.
- See Also:
draw(GeneiousGraphics2D, int, int, int, int, int, int, double, int, int, int, int)
-
getDefaultLocation
public SequenceGraph.Location getDefaultLocation()
Determines whether this graph should appear above or below the sequence residues. This is just the default location. In future versions of Geneious, we will allow dragging graphs to new locations/ orderings. Therefore, you should not provide the user with an option to change the default location.- Returns:
- the location of this graph. The default implementation returns
SequenceGraph.Location.BELOW_RESIDUES
-
getApproximateCalculationWorkRequiredPerResidue
public int getApproximateCalculationWorkRequiredPerResidue()
Estimate an amount of work required to calculate graph values per residue. Geneious uses this to estimate when it's appropriate to callperformBackgroundCalculations(jebl.util.ProgressListener)
. For example, when zoomed out viewing a large sequence, Geneious may request that the graph render a range of 10,000 residues into the region a single horizontal coordinate wide. Calculating the value the graph at this point is probably too time-consuming to be performed in the AWT thread for every graph point. Geneious evaluates the total work required to render the currently visible section of the graph. If this is greater than 500,000, it will callperformBackgroundCalculations
instead of calling draw. The default implementation of this returns 0, which means thatperformBackgroundCalculations(jebl.util.ProgressListener)
is never called. Graphs may also wish to returnInteger.MAX_VALUE
. For example those that need to calculate all values before drawing the scale bar, or those where the value of a single residue depends on all others should do this. Geneious will then callperformBackgroundCalculations
before any calls todraw
ordrawScaleBar
are made. As a guideline, if it would take longer than about 1/2 a second of calculation before anything can be drawn, returnInteger.MAX_VALUE
from this method. Any implementation may (and is recommended to) vary its result depending on the sequence lengths, so that for short sequences, it may choose not to returnInteger.MAX_VALUE
setResidues
(for residue based graphs) is guaranteed to be called before this method.- Returns:
- an estimate of an amount of work required to calculate graph values per residue.
Generally should be 1 for single sequences (or equal to the number of sequences)
or
Integer.MAX_VALUE
for graphs that need to calculate everything before drawing anything
-
performBackgroundCalculations
public void performBackgroundCalculations(jebl.util.ProgressListener progress)
Perform some background calculations in a non AWT thread before this graph is drawn. Geneious will only call this method on graphs that require a large enough amount of work as defined bygetApproximateCalculationWorkRequiredPerResidue()
The implementation of this may take as long as it needs to, but should very frequently callprogress.isCanceled()
and return immediately if that method returns true. Failure do so will seriously degrade performance when editing a sequence or alignment or when zooming in/out. Geneious will not simultaneously make calls todraw
orsetResidues(java.util.List, java.util.List, boolean)
while this method is executing. Geneious will never invoke this method simultaneously on the same SequenceGraph instance.- Parameters:
progress
- Currently this progress is unused, except for its cancellation functionality. Nevertheless, it would be wise to report progress in case it is reported to the user in future versions.
-
getCurrentBackgroundColorFor
protected final java.awt.Color getCurrentBackgroundColorFor(char residue)
Get the current background color for a given residue using the current sequence viewer color scheme.- Parameters:
residue
- the residue to get the color for.- Returns:
- the current color, for this residue or null if the current scheme does not define a color for this residue.
-
getCurrentForegroundColorFor
protected final java.awt.Color getCurrentForegroundColorFor(char residue)
Get the current foreground color for a given residue using the current sequence viewer color scheme.- Parameters:
residue
- the residue to get the color for.- Returns:
- the current color, for this residue or null if the current scheme does not define a color for this residue.
-
setCurrentColorScheme
public final void setCurrentColorScheme(java.awt.Color[] backgroundColors, java.awt.Color[] foregroundColors)
Sets the current color scheme used by the sequence viewer. The default implementation stores these for access viagetCurrentBackgroundColorFor(char)
orgetCurrentForegroundColorFor(char)
.- Parameters:
backgroundColors
- an array of colors to be used where the array index is the character. e.g. backgroundColors['A']==backgroundColors['a]==Color.REDforegroundColors
- an array of colors to be used where the array index is the character. e.g. backgroundColors['A']==backgroundColors['a]==Color.RED
-
isProOnly
public boolean isProOnly()
Does this graph require an active license? The default implementation returns false.- Returns:
- true if this graph requires an active license.
-
mouseClicked
public void mouseClicked(java.awt.event.MouseEvent event)
The mouse has been clicked in this sequence graph. The graph should callInputEvent.consume()
if it processes the click and doesn't want the sequence viewer to continue processing.- Specified by:
mouseClicked
in interfacejava.awt.event.MouseListener
- Parameters:
event
- the MouseEvent where the y value is relative to the top of the graph and the x value is the logical x co-ordinate in the sequence viewer.
-
mousePressed
public void mousePressed(java.awt.event.MouseEvent event)
The mouse has been pressed in this sequence graph. The graph should callInputEvent.consume()
if it processes the press and doesn't want the sequence viewer to continue processing.- Specified by:
mousePressed
in interfacejava.awt.event.MouseListener
- Parameters:
event
- the MouseEvent where the y value is relative to the top of the graph and the x value is the logical x co-ordinate in the sequence viewer.
-
mouseReleased
public void mouseReleased(java.awt.event.MouseEvent event)
The mouse has been released in this sequence graph.- Specified by:
mouseReleased
in interfacejava.awt.event.MouseListener
- Parameters:
event
- the MouseEvent where the y value is relative to the top of the graph and the x value is the logical x co-ordinate in the sequence viewer.
-
mouseEntered
public void mouseEntered(java.awt.event.MouseEvent event)
The mouse has left this sequence graph.- Specified by:
mouseEntered
in interfacejava.awt.event.MouseListener
- Parameters:
event
- the MouseEvent where the y value is relative to the top of the graph and the x value is the logical x co-ordinate in the sequence viewer.
-
mouseExited
public void mouseExited(java.awt.event.MouseEvent event)
The mouse has left this sequence graph.- Specified by:
mouseExited
in interfacejava.awt.event.MouseListener
- Parameters:
event
- the MouseEvent x and y are both 0 as of Geneious 5.3.
-
mouseDragged
public void mouseDragged(java.awt.event.MouseEvent event)
The mouse has been dragged in this sequence graph (with a drag starting inside the graph, not outside it). The graph should callInputEvent.consume()
if it processes the event to cause a repaint of the view- Specified by:
mouseDragged
in interfacejava.awt.event.MouseMotionListener
- Parameters:
event
- the MouseEvent where the y value is relative to the top of the graph and the x value is the logical x co-ordinate in the sequence viewer.
-
mouseMoved
public void mouseMoved(java.awt.event.MouseEvent event)
The mouse has been moved in this sequence graph.- Specified by:
mouseMoved
in interfacejava.awt.event.MouseMotionListener
- Parameters:
event
- the MouseEvent where the y value is relative to the top of the graph and the x value is the logical x co-ordinate in the sequence viewer.
-
-