X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fviewmodel%2Fseqfeatures%2FFeatureRendererModel.java;h=7e28c7febb0b93c4eea12e0012b98a41915aa24a;hb=d8084ce0043bb2454cfc48fe9c87f9aef12c0cf8;hp=848f565e01222587375cd85610af9ac10f3140bd;hpb=2facc9ee2fdb025b5cc79b005e7eb5bd915cd9ba;p=jalview.git diff --git a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java index 848f565..7e28c7f 100644 --- a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java +++ b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java @@ -74,6 +74,12 @@ public abstract class FeatureRendererModel implements */ private Map minmax = new Hashtable(); + /* + * List of feature types where getFeatureNumber() > 0 is found + * - a heuristic for 'features have an explicit ordering' + */ + private List ordinalFeatures = new ArrayList(); + @Override public AlignViewportI getViewport() { @@ -309,7 +315,7 @@ public abstract class FeatureRendererModel implements * Searches alignment for all features and updates colours * * @param newMadeVisible - * if true newly added feature types will be rendered immediatly + * if true newly added feature types will be rendered immediately * TODO: check to see if this method should actually be proxied so * repaint events can be propagated by the renderer code */ @@ -325,14 +331,15 @@ public abstract class FeatureRendererModel implements } findingFeatures = true; + ordinalFeatures.clear(); if (av.getFeaturesDisplayed() == null) { av.setFeaturesDisplayed(new FeaturesDisplayed()); } FeaturesDisplayedI featuresDisplayed = av.getFeaturesDisplayed(); - ArrayList allfeatures = new ArrayList(); - ArrayList oldfeatures = new ArrayList(); + List allfeatures = new ArrayList(); + List oldfeatures = new ArrayList(); if (renderOrder != null) { for (int i = 0; i < renderOrder.length; i++) @@ -348,9 +355,8 @@ public abstract class FeatureRendererModel implements minmax = new Hashtable(); } AlignmentI alignment = av.getAlignment(); - for (int i = 0; i < alignment.getHeight(); i++) + for (SequenceI asq : alignment.getSequences()) { - SequenceI asq = alignment.getSequenceAt(i); SequenceFeature[] features = asq.getSequenceFeatures(); if (features == null) @@ -358,12 +364,12 @@ public abstract class FeatureRendererModel implements continue; } - int index = 0; - while (index < features.length) + for (SequenceFeature feature : features) { - if (!featuresDisplayed.isRegistered(features[index].getType())) + String type = feature.getType(); + if (!featuresDisplayed.isRegistered(type)) { - String fgrp = features[index].getFeatureGroup(); + String fgrp = feature.getFeatureGroup(); if (fgrp != null) { Boolean groupDisplayed = featureGroups.get(fgrp); @@ -374,57 +380,60 @@ public abstract class FeatureRendererModel implements } if (!groupDisplayed.booleanValue()) { - index++; continue; } } - if (!(features[index].begin == 0 && features[index].end == 0)) + if (!(feature.begin == 0 && feature.end == 0)) { // If beginning and end are 0, the feature is for the whole sequence // and we don't want to render the feature in the normal way if (newMadeVisible - && !oldfeatures.contains(features[index].getType())) + && !oldfeatures.contains(type)) { // this is a new feature type on the alignment. Mark it for // display. - featuresDisplayed.setVisible(features[index].getType()); - setOrder(features[index].getType(), 0); + featuresDisplayed.setVisible(type); + setOrder(type, 0); } } } - if (!allfeatures.contains(features[index].getType())) + if (!allfeatures.contains(type)) { - allfeatures.add(features[index].getType()); + allfeatures.add(type); } - if (!Float.isNaN(features[index].score)) + float score = feature.score; + if (!Float.isNaN(score)) { - int nonpos = features[index].getBegin() >= 1 ? 0 : 1; - float[][] mm = minmax.get(features[index].getType()); + int nonpos = feature.getBegin() >= 1 ? 0 : 1; + float[][] mm = minmax.get(type); if (mm == null) { mm = new float[][] { null, null }; - minmax.put(features[index].getType(), mm); + minmax.put(type, mm); } if (mm[nonpos] == null) { - mm[nonpos] = new float[] { features[index].score, - features[index].score }; + mm[nonpos] = new float[] { score, score }; } else { - if (mm[nonpos][0] > features[index].score) - { - mm[nonpos][0] = features[index].score; - } - if (mm[nonpos][1] < features[index].score) - { - mm[nonpos][1] = features[index].score; - } + mm[nonpos][0] = Math.min(mm[nonpos][0], score); + mm[nonpos][1] = Math.max(mm[nonpos][1], score); + } + } + + /* + * add to 'ordinal feature types' if it has featureNumber > 0 + */ + if (!ordinalFeatures.contains(type)) + { + if (feature.getFeatureNumber() > 0) + { + ordinalFeatures.add(type); } } - index++; } } updateRenderOrder(allfeatures); @@ -449,7 +458,8 @@ public abstract class FeatureRendererModel implements List allfeatures = new ArrayList(allFeatures); String[] oldRender = renderOrder; renderOrder = new String[allfeatures.size()]; - Object mmrange, fc = null; + float[][] mmrange; + Object fc; boolean initOrders = (featureOrder == null); int opos = 0; if (oldRender != null && oldRender.length > 0) @@ -464,8 +474,8 @@ public abstract class FeatureRendererModel implements } if (allfeatures.contains(oldRender[j])) { - renderOrder[opos++] = oldRender[j]; // existing features always - // appear below new features + renderOrder[opos++] = oldRender[j]; + // existing features always appear below new features allfeatures.remove(oldRender[j]); if (minmax != null) { @@ -477,8 +487,8 @@ public abstract class FeatureRendererModel implements && ((GraduatedColor) fc).isAutoScale()) { ((GraduatedColor) fc).updateBounds( - ((float[][]) mmrange)[0][0], - ((float[][]) mmrange)[0][1]); + mmrange[0][0], + mmrange[0][1]); } } } @@ -509,8 +519,8 @@ public abstract class FeatureRendererModel implements if (fc != null && fc instanceof GraduatedColor && ((GraduatedColor) fc).isAutoScale()) { - ((GraduatedColor) fc).updateBounds(((float[][]) mmrange)[0][0], - ((float[][]) mmrange)[0][1]); + ((GraduatedColor) fc).updateBounds(mmrange[0][0], + mmrange[0][1]); } } } @@ -1009,4 +1019,9 @@ public abstract class FeatureRendererModel implements return _gps; } + @Override + public boolean isOrdinal(String featureType) + { + return ordinalFeatures.contains(featureType); + } }