Skip to content

Commit fd82ac0

Browse files
committed
Make nested arc the default type for interaction track. Minor refactorings.
1 parent b0be5af commit fd82ac0

2 files changed

Lines changed: 91 additions & 142 deletions

File tree

src/main/java/org/igv/bedpe/HicInteractionTrack.java

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.igv.renderer.ContinuousColorScale;
55
import org.igv.track.RenderContext;
66
import org.igv.track.TrackClickEvent;
7+
import org.igv.ui.IGV;
78
import org.igv.ui.panel.FrameManager;
89
import org.igv.ui.panel.IGVPopupMenu;
910
import org.igv.ui.panel.ReferenceFrame;
@@ -31,6 +32,7 @@ public HicInteractionTrack(ResourceLocator locator, HicSource source) {
3132
maxFeatureCount = 5000;
3233
graphType = GraphType.NESTED_ARC;
3334
useScore = true;
35+
isHIC = true;
3436
setColor(Color.red);
3537
}
3638

@@ -54,8 +56,61 @@ protected List<BedPE> filterFeaturesForZoom(List<BedPE> features, LoadedInterval
5456
return features;
5557
}
5658

57-
@Override
58-
protected void addFormatSpecificMenuItems(IGVPopupMenu menu, TrackClickEvent te) {
59+
void addHICItems(TrackClickEvent te, IGVPopupMenu menu) {
60+
61+
final JMenuItem transparencyItem = new JMenuItem("Set Transparency...");
62+
transparencyItem.addActionListener(e -> {
63+
final JSlider slider = new JSlider(1, 100, (int) (this.transparency * 100));
64+
slider.setMajorTickSpacing(10);
65+
slider.setPaintTicks(true);
66+
67+
// Create a label to show the current value
68+
final JLabel valueLabel = new JLabel(String.format("%.2f", this.transparency));
69+
70+
slider.addChangeListener(changeEvent -> {
71+
JSlider source = (JSlider) changeEvent.getSource();
72+
float value = source.getValue() / 100.0f;
73+
this.transparency = value;
74+
valueLabel.setText(String.format("%.2f", value));
75+
this.repaint();
76+
});
77+
78+
JPanel panel = new JPanel(new BorderLayout());
79+
panel.add(slider, BorderLayout.CENTER);
80+
panel.add(valueLabel, BorderLayout.SOUTH);
81+
82+
final Frame parent = IGV.hasInstance() ? IGV.getInstance().getMainFrame() : null;
83+
JOptionPane.showMessageDialog(parent, panel, "Set Transparency for " + this.getDisplayName(), JOptionPane.PLAIN_MESSAGE);
84+
});
85+
menu.add(transparencyItem);
86+
87+
88+
final JMenuItem maxFeatureCountItem = new JMenuItem("Set Maximum Feature Count...");
89+
maxFeatureCountItem.addActionListener(e -> {
90+
final JSlider slider = new JSlider(1000, 20000, this.maxFeatureCount);
91+
slider.setMajorTickSpacing(5000);
92+
slider.setPaintTicks(true);
93+
94+
final JLabel valueLabel = new JLabel(String.valueOf(this.maxFeatureCount));
95+
96+
slider.addChangeListener(changeEvent -> {
97+
JSlider source = (JSlider) changeEvent.getSource();
98+
int value = source.getValue();
99+
this.maxFeatureCount = value;
100+
valueLabel.setText(String.valueOf(value));
101+
this.loadedIntervalMap.clear();
102+
this.repaint();
103+
});
104+
105+
JPanel panel = new JPanel(new BorderLayout());
106+
panel.add(slider, BorderLayout.CENTER);
107+
panel.add(valueLabel, BorderLayout.SOUTH);
108+
109+
final Frame parent = IGV.hasInstance() ? IGV.getInstance().getMainFrame() : null;
110+
JOptionPane.showMessageDialog(parent, panel, "Set Max Feature Count for " + this.getDisplayName(), JOptionPane.PLAIN_MESSAGE);
111+
});
112+
menu.add(maxFeatureCountItem);
113+
59114
// Add normalization options for HiC tracks
60115
List<String> normalizationTypes = featureSource.getNormalizationTypes();
61116
if (normalizationTypes != null && normalizationTypes.size() > 1) {
@@ -92,25 +147,7 @@ protected void addFormatSpecificMenuItems(IGVPopupMenu menu, TrackClickEvent te)
92147
menu.add(mapItem);
93148
}
94149

95-
@Override
96-
protected boolean supportsGraphTypeSelection() {
97-
return false;
98-
}
99-
100-
@Override
101-
protected boolean supportsCircularView() {
102-
return false;
103-
}
104-
105-
@Override
106-
protected boolean supportsAutoscaleMenu() {
107-
return false;
108-
}
109150

110-
@Override
111-
protected boolean supportsFeatureWindowMenu() {
112-
return false;
113-
}
114151

115152
@Override
116153
public void marshalXML(Document document, Element element) {

src/main/java/org/igv/bedpe/InteractionTrack.java

Lines changed: 34 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,17 @@
33
import org.igv.Globals;
44
import org.igv.event.IGVEvent;
55
import org.igv.event.IGVEventObserver;
6-
import org.igv.hic.HicFile;
76
import org.igv.jbrowse.CircularViewUtilities;
87
import org.igv.logging.LogManager;
98
import org.igv.logging.Logger;
109
import org.igv.prefs.Constants;
1110
import org.igv.prefs.PreferencesManager;
12-
import org.igv.renderer.ContinuousColorScale;
1311
import org.igv.renderer.GraphicUtils;
1412
import org.igv.track.AbstractTrack;
1513
import org.igv.track.RenderContext;
1614
import org.igv.track.TrackClickEvent;
1715
import org.igv.track.TrackMenuUtils;
1816
import org.igv.ui.FontManager;
19-
import org.igv.ui.IGV;
2017
import org.igv.ui.panel.FrameManager;
2118
import org.igv.ui.panel.IGVPopupMenu;
2219
import org.igv.ui.panel.ReferenceFrame;
@@ -67,18 +64,22 @@ enum ArcOption {ALL, ONE_END, BOTH_ENDS}
6764
private JMenuItem maxScoreItem;
6865

6966
InteractionTrack.Direction direction = UP; //DOWN;
70-
protected GraphType graphType; // GraphType.block; //
67+
protected GraphType graphType = GraphType.NESTED_ARC; // GraphType.block; //
7168
private ArcOption arcOption = ArcOption.ALL;
7269
int thickness = 1;
7370
boolean autoscale = true;
7471
double maxScore = -1;
7572
int gap = 5;
7673
boolean showBlocks = false;
7774
protected boolean useScore = false;
75+
protected boolean isHIC = false;
7876
private Map<GraphType, BedPERenderer> renderers;
7977

78+
private Color defaultColor = new Color(180, 25, 137);
79+
80+
8081
ContactMapView contactMapView;
81-
float transparency = 0.1f;
82+
float transparency = 1.0f;
8283
protected String normalization = "NONE";
8384
protected int maxFeatureCount = 20000;
8485

@@ -98,7 +99,6 @@ public InteractionTrack(ResourceLocator locator, InteractionSource src) {
9899
this.featureSource = src;
99100

100101
setHeight(250, true);
101-
setColor(new Color(180, 25, 137));
102102

103103
renderers = new HashMap<>();
104104
renderers.put(GraphType.NESTED_ARC, new NestedArcRenderer(this));
@@ -111,10 +111,7 @@ public InteractionTrack(ResourceLocator locator, InteractionSource src) {
111111
graphType = GraphType.valueOf(typeString);
112112
} catch (IllegalArgumentException e) {
113113
log.error("Illegal graph type: " + typeString, e);
114-
graphType = GraphType.NESTED_ARC; // default
115114
}
116-
} else {
117-
graphType = GraphType.PROPORTIONAL_ARC;
118115
}
119116

120117
String directionString = PreferencesManager.getPreferences().get(Constants.ARC_DIRECTION);
@@ -308,7 +305,7 @@ public IGVPopupMenu getPopupMenu(TrackClickEvent te) {
308305
item.addActionListener(evt -> TrackMenuUtils.changeTrackColor(Collections.singleton(InteractionTrack.this)));
309306
menu.add(item);
310307

311-
if (supportsGraphTypeSelection()) {
308+
if (!isHIC) {
312309
menu.addSeparator();
313310
menu.add(new JLabel("<html><b>Graph Type</b>"));
314311
//enum GraphType {BLOCK, ARC, PROPORTIONAL_ARC}
@@ -322,7 +319,7 @@ public IGVPopupMenu getPopupMenu(TrackClickEvent te) {
322319
JRadioButtonMenuItem mm = new JRadioButtonMenuItem(entry.getKey());
323320
mm.setSelected(InteractionTrack.this.graphType == entry.getValue());
324321
mm.addActionListener(evt -> {
325-
setGraphType(entry.getValue());
322+
this.graphType = entry.getValue();
326323
PreferencesManager.getPreferences().put(Constants.ARC_TYPE, entry.getValue().toString());
327324
autoscaleCB.setEnabled(graphType == GraphType.PROPORTIONAL_ARC);
328325
maxScoreItem.setEnabled(graphType == GraphType.PROPORTIONAL_ARC);
@@ -363,7 +360,7 @@ public IGVPopupMenu getPopupMenu(TrackClickEvent te) {
363360
});
364361
menu.add(showBlocksCB);
365362

366-
if (supportsAutoscaleMenu()) {
363+
if (!isHIC) {
367364
menu.addSeparator();
368365
autoscaleCB = new JCheckBoxMenuItem("Autoscale");
369366
autoscaleCB.setSelected(autoscale);
@@ -424,127 +421,42 @@ public IGVPopupMenu getPopupMenu(TrackClickEvent te) {
424421
menu.add(item);
425422

426423

427-
final JMenuItem transparencyItem = new JMenuItem("Set Transparency...");
428-
transparencyItem.addActionListener(e -> {
429-
final JSlider slider = new JSlider(1, 100, (int) (InteractionTrack.this.transparency * 100));
430-
slider.setMajorTickSpacing(10);
431-
slider.setPaintTicks(true);
432-
433-
// Create a label to show the current value
434-
final JLabel valueLabel = new JLabel(String.format("%.2f", InteractionTrack.this.transparency));
435-
436-
slider.addChangeListener(changeEvent -> {
437-
JSlider source = (JSlider) changeEvent.getSource();
438-
float value = source.getValue() / 100.0f;
439-
InteractionTrack.this.transparency = value;
440-
valueLabel.setText(String.format("%.2f", value));
441-
InteractionTrack.this.repaint();
442-
});
443-
444-
JPanel panel = new JPanel(new BorderLayout());
445-
panel.add(slider, BorderLayout.CENTER);
446-
panel.add(valueLabel, BorderLayout.SOUTH);
447-
448-
final Frame parent = IGV.hasInstance() ? IGV.getInstance().getMainFrame() : null;
449-
JOptionPane.showMessageDialog(parent, panel, "Set Transparency for " + InteractionTrack.this.getDisplayName(), JOptionPane.PLAIN_MESSAGE);
450-
});
451-
menu.add(transparencyItem);
452-
453-
454-
final JMenuItem maxFeatureCountItem = new JMenuItem("Set Maximum Feature Count...");
455-
maxFeatureCountItem.addActionListener(e -> {
456-
final JSlider slider = new JSlider(1000, 20000, InteractionTrack.this.maxFeatureCount);
457-
slider.setMajorTickSpacing(5000);
458-
slider.setPaintTicks(true);
459-
460-
final JLabel valueLabel = new JLabel(String.valueOf(InteractionTrack.this.maxFeatureCount));
424+
if (isHIC) {
425+
addHICItems(te, menu);
461426

462-
slider.addChangeListener(changeEvent -> {
463-
JSlider source = (JSlider) changeEvent.getSource();
464-
int value = source.getValue();
465-
InteractionTrack.this.maxFeatureCount = value;
466-
valueLabel.setText(String.valueOf(value));
467-
InteractionTrack.this.loadedIntervalMap.clear();
468-
InteractionTrack.this.repaint();
469-
});
470-
471-
JPanel panel = new JPanel(new BorderLayout());
472-
panel.add(slider, BorderLayout.CENTER);
473-
panel.add(valueLabel, BorderLayout.SOUTH);
474-
475-
final Frame parent = IGV.hasInstance() ? IGV.getInstance().getMainFrame() : null;
476-
JOptionPane.showMessageDialog(parent, panel, "Set Max Feature Count for " + InteractionTrack.this.getDisplayName(), JOptionPane.PLAIN_MESSAGE);
477-
});
478-
menu.add(maxFeatureCountItem);
479-
480-
481-
// Hook for subclass-specific menu items (e.g., HiC normalization options)
482-
addFormatSpecificMenuItems(menu, te);
483-
484-
if (supportsFeatureWindowMenu()) {
427+
} else {
428+
// Not hic
485429
menu.addSeparator();
486430
menu.add(TrackMenuUtils.getChangeFeatureWindow(Collections.singletonList(this)));
487-
}
488431

489-
// Experimental JBrowse.
490-
if (PreferencesManager.getPreferences().getAsBoolean(Constants.CIRC_VIEW_ENABLED) &&
491-
CircularViewUtilities.ping() &&
492-
supportsCircularView()) {
493-
menu.addSeparator();
494-
JMenuItem circViewItem = new JMenuItem("Add Features to Circular View");
495-
circViewItem.addActionListener(e -> {
496-
List<ReferenceFrame> frames = te.getFrame() != null ?
497-
Collections.singletonList(te.getFrame()) :
498-
FrameManager.getFrames();
499-
List<? extends BedPE> visibleFeatures = getVisibleFeatures(frames);
500-
CircularViewUtilities.sendBedpeToJBrowse(visibleFeatures, InteractionTrack.this.getName(), InteractionTrack.this.getColor());
501-
});
502-
menu.add(circViewItem);
503-
menu.addSeparator();
432+
433+
// Experimental JBrowse.
434+
if (PreferencesManager.getPreferences().getAsBoolean(Constants.CIRC_VIEW_ENABLED) &&
435+
CircularViewUtilities.ping()) {
436+
menu.addSeparator();
437+
JMenuItem circViewItem = new JMenuItem("Add Features to Circular View");
438+
circViewItem.addActionListener(e -> {
439+
List<ReferenceFrame> frames = te.getFrame() != null ?
440+
Collections.singletonList(te.getFrame()) :
441+
FrameManager.getFrames();
442+
List<? extends BedPE> visibleFeatures = getVisibleFeatures(frames);
443+
CircularViewUtilities.sendBedpeToJBrowse(visibleFeatures, InteractionTrack.this.getName(), InteractionTrack.this.getColor());
444+
});
445+
menu.add(circViewItem);
446+
menu.addSeparator();
447+
}
504448
}
505449

506450
return menu;
507451
}
508452

509-
private void setGraphType(GraphType value) {
510-
// TODO adjust height
511-
this.graphType = value;
512-
}
513-
514-
/**
515-
* Hook method for subclasses to add format-specific menu items.
516-
* Default implementation does nothing.
517-
*/
518-
protected void addFormatSpecificMenuItems(IGVPopupMenu menu, TrackClickEvent te) {
519-
// Default: no additional menu items
520-
}
521-
522-
/**
523-
* Hook method for subclasses to indicate if graph type selection is supported.
524-
*/
525-
protected boolean supportsGraphTypeSelection() {
526-
return true;
453+
void addHICItems(TrackClickEvent te, IGVPopupMenu menu) {
454+
// Override in HIC subclass
527455
}
528456

529-
/**
530-
* Hook method for subclasses to indicate if circular view is supported.
531-
*/
532-
protected boolean supportsCircularView() {
533-
return true;
534-
}
535-
536-
/**
537-
* Hook method for subclasses to indicate if autoscale menu is supported.
538-
*/
539-
protected boolean supportsAutoscaleMenu() {
540-
return true;
541-
}
542-
543-
/**
544-
* Hook method for subclasses to indicate if feature window menu is supported.
545-
*/
546-
protected boolean supportsFeatureWindowMenu() {
547-
return true;
457+
@Override
458+
public void setColor(Color color) {
459+
super.setColor(color);
548460
}
549461

550462
@Override

0 commit comments

Comments
 (0)