package jalview.renderer.seqfeatures;
import jalview.api.AlignViewportI;
+import jalview.datamodel.Range;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.util.Comparison;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
+import java.util.List;
public class FeatureRenderer extends FeatureRendererModel
{
private static final AlphaComposite NO_TRANSPARENCY = AlphaComposite
.getInstance(AlphaComposite.SRC_OVER, 1.0f);
- protected SequenceI lastSeq;
-
- private volatile SequenceFeature[] lastSequenceFeatures;
-
- int sfSize;
-
/**
* Constructor given a viewport
*
return null;
}
- SequenceFeature[] sequenceFeatures = seq.getSequenceFeatures();
- if (seq != lastSeq)
- {
- lastSeq = seq;
- lastSequenceFeatures = sequenceFeatures;
- if (lastSequenceFeatures != null)
- {
- sfSize = lastSequenceFeatures.length;
- }
- }
- else
- {
- if (lastSequenceFeatures != sequenceFeatures)
- {
- lastSequenceFeatures = sequenceFeatures;
- if (lastSequenceFeatures != null)
- {
- sfSize = lastSequenceFeatures.length;
- }
- }
- }
-
- if (lastSequenceFeatures == null || sfSize == 0)
- {
- return null;
- }
-
- if (Comparison.isGap(lastSeq.getCharAt(column)))
+ if (Comparison.isGap(seq.getCharAt(column)))
{
return Color.white;
}
* transparency case - draw all visible features in render order to
* build up a composite colour on the graphics context
*/
- renderedColour = drawSequence(g, lastSeq, column, column, 0, true);
+ renderedColour = drawSequence(g, seq, column, column, 0, true);
}
return renderedColour;
}
final SequenceI seq, int start, int end, int y1,
boolean colourOnly)
{
- SequenceFeature[] sequenceFeatures = seq.getSequenceFeatures();
- if (sequenceFeatures == null || sequenceFeatures.length == 0)
+ if (!seq.getFeatures().hasFeatures())
{
return null;
}
updateFeatures();
- if (lastSeq == null || seq != lastSeq
- || sequenceFeatures != lastSequenceFeatures)
- {
- lastSeq = seq;
- lastSequenceFeatures = sequenceFeatures;
- }
-
if (transparency != 1f && g != null)
{
Graphics2D g2 = (Graphics2D) g;
transparency));
}
- int startPos = lastSeq.findPosition(start);
- int endPos = lastSeq.findPosition(end);
+ /*
+ * get range of sequence positions within column range
+ */
+ Range seqRange = seq.findPositions(start, end);
+ if (seqRange == null)
+ {
+ return null;
+ }
- sfSize = lastSequenceFeatures.length;
Color drawnColour = null;
/*
continue;
}
- // loop through all features in sequence to find
- // current feature to render
- for (int sfindex = 0; sfindex < sfSize; sfindex++)
+ List<SequenceFeature> overlaps = seq.findFeatures(seqRange.start,
+ seqRange.end, type);
+ for (SequenceFeature sequenceFeature : overlaps)
{
- final SequenceFeature sequenceFeature = lastSequenceFeatures[sfindex];
- if (!sequenceFeature.type.equals(type))
- {
- continue;
- }
-
/*
* a feature type may be flagged as shown but the group
* an instance of it belongs to may be hidden
continue;
}
- /*
- * check feature overlaps the target range
- * TODO: efficient retrieval of features overlapping a range
- */
- if (sequenceFeature.getBegin() > endPos
- || sequenceFeature.getEnd() < startPos)
- {
- continue;
- }
-
Color featureColour = getColour(sequenceFeature);
boolean isContactFeature = sequenceFeature.isContactFeature();
+ // todo overload findIndex using Location data
+ int featureStartCol = seq.findIndex(sequenceFeature.begin);
+ int featureEndCol = seq.findIndex(sequenceFeature.end);
if (isContactFeature)
{
boolean drawn = renderFeature(g, seq,
- seq.findIndex(sequenceFeature.begin) - 1,
- seq.findIndex(sequenceFeature.begin) - 1, featureColour,
+ featureStartCol - 1,
+ featureStartCol - 1, featureColour,
start, end, y1, colourOnly);
drawn |= renderFeature(g, seq,
- seq.findIndex(sequenceFeature.end) - 1,
- seq.findIndex(sequenceFeature.end) - 1, featureColour,
+ featureEndCol - 1,
+ featureEndCol - 1, featureColour,
start, end, y1, colourOnly);
if (drawn)
{
}
else if (showFeature(sequenceFeature))
{
+ /*
+ * showing feature score by height of colour
+ * is not implemented as a selectable option
+ *
if (av.isShowSequenceFeaturesHeight()
&& !Float.isNaN(sequenceFeature.score))
{
}
else
{
+ */
boolean drawn = renderFeature(g, seq,
- seq.findIndex(sequenceFeature.begin) - 1,
- seq.findIndex(sequenceFeature.end) - 1, featureColour,
+ featureStartCol - 1,
+ featureEndCol - 1, featureColour,
start, end, y1, colourOnly);
if (drawn)
{
drawnColour = featureColour;
}
- }
+ /*}*/
}
}
}
}
/**
- * Answers true if the feature belongs to a feature group which is not
- * currently displayed, else false
- *
- * @param sequenceFeature
- * @return
- */
- protected boolean featureGroupNotShown(
- final SequenceFeature sequenceFeature)
- {
- return featureGroups != null
- && sequenceFeature.featureGroup != null
- && sequenceFeature.featureGroup.length() != 0
- && featureGroups.containsKey(sequenceFeature.featureGroup)
- && !featureGroups.get(sequenceFeature.featureGroup)
- .booleanValue();
- }
-
- /**
* Called when alignment in associated view has new/modified features to
* discover and display.
*
@Override
public void featuresAdded()
{
- lastSeq = null;
findAllFeatures();
}
*/
Color findFeatureColour(SequenceI seq, int pos)
{
- SequenceFeature[] sequenceFeatures = seq.getSequenceFeatures();
- if (sequenceFeatures == null || sequenceFeatures.length == 0)
- {
- return null;
- }
-
/*
* check for new feature added while processing
*/
continue;
}
- for (int sfindex = 0; sfindex < sequenceFeatures.length; sfindex++)
+ List<SequenceFeature> overlaps = seq.findFeatures(pos, pos, type);
+ for (SequenceFeature sequenceFeature : overlaps)
{
- SequenceFeature sequenceFeature = sequenceFeatures[sfindex];
- if (!sequenceFeature.type.equals(type))
- {
- continue;
- }
-
- if (featureGroupNotShown(sequenceFeature))
- {
- continue;
- }
-
- /*
- * check the column position is within the feature range
- * (or is one of the two contact positions for a contact feature)
- */
- boolean featureIsAtPosition = sequenceFeature.begin <= pos
- && sequenceFeature.end >= pos;
- if (sequenceFeature.isContactFeature())
- {
- featureIsAtPosition = sequenceFeature.begin == pos
- || sequenceFeature.end == pos;
- }
- if (featureIsAtPosition)
+ if (!featureGroupNotShown(sequenceFeature))
{
return getColour(sequenceFeature);
}