/* * #%L * gitools-core * %% * Copyright (C) 2013 Universitat Pompeu Fabra - Biomedical Genomics group * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ package org.gitools.heatmap; import com.google.common.base.Objects; import com.google.common.base.Strings; import com.jgoodies.binding.beans.Model; import org.gitools.api.matrix.IMatrix; import org.gitools.api.matrix.IMatrixLayer; import org.gitools.api.matrix.IMatrixLayers; import org.gitools.api.matrix.view.IMatrixViewLayers; import org.gitools.heatmap.decorator.DetailsDecoration; import org.gitools.matrix.model.MatrixLayers; import org.gitools.matrix.model.matrix.element.LayerDef; import org.gitools.utils.events.EventUtils; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import java.util.*; @XmlAccessorType(XmlAccessType.FIELD) public class HeatmapLayers extends Model implements IMatrixViewLayers<HeatmapLayer> { public static final String PROPERTY_TOP_LAYER_INDEX = "topLayerIndex"; public static final String PROPERTY_TOP_LAYER = "topLayer"; public static final String PROPERTY_LAYERS = "layers"; public static final String PROPERTY_SELECTED_GROUP = "selectedGroup"; @XmlElement(name = "top-layer") private int topLayer; @XmlElement(name = "layer") private List<HeatmapLayer> layers; private transient Map<String, Integer> layersIdToIndex; private transient List<String> layerNames; private String selectedGroup; private transient HashSet<String> groups; public HeatmapLayers() { this.topLayer = 0; } public HeatmapLayers(IMatrix matrix) { this(); createLayers(matrix); init(matrix); } private void createLayers(IMatrix matrix) { IMatrixLayers<? extends IMatrixLayer> matrixLayers = matrix.getLayers(); this.layers = new ArrayList<>(matrixLayers.size()); this.layerNames = null; this.layersIdToIndex = null; for (IMatrixLayer layer : matrixLayers) { initLayer(layer); } } public void initLayer(IMatrixLayer layer) { this.layers.add(new HeatmapLayer(layer)); } public void init(IMatrix matrix) { IMatrixLayers<?> matrixLayers = matrix.getLayers(); // Check if there is a new data layer for (IMatrixLayer dataLayer : matrixLayers) { HeatmapLayer newLayer = null; for (HeatmapLayer heatmapLayer : this.layers) { if (heatmapLayer.getId().equals(dataLayer.getId())) { newLayer = heatmapLayer; break; } } // This is a new layer if (newLayer == null) { this.layers.add(new HeatmapLayer(dataLayer)); } } initTransient(); } public void updateLayers() { initTransient(); firePropertyChange(PROPERTY_LAYERS, null, null); } private void initTransient() { this.layersIdToIndex = new HashMap<>(layers.size()); this.layerNames = new ArrayList<>(layers.size()); // Init transient parameters for (int i = 0; i < layers.size(); i++) { this.layersIdToIndex.put(layers.get(i).getId(), i); this.layerNames.add(layers.get(i).getName()); } } public HeatmapLayer getTopLayer() { return layers.get(topLayer); } public void setTopLayer(HeatmapLayer topLayer) { setTopLayerIndex(layers.indexOf(topLayer)); } @Deprecated public int getTopLayerIndex() { return topLayer; } @Deprecated public void setTopLayerById(String id) { int layer = indexOf(id); if (layer != -1) { setTopLayerIndex(layer); } } @Deprecated public void setTopLayerIndex(int layerIndex) { int old = this.topLayer; // Move listeners HeatmapLayer oldLayer = layers.get(old); HeatmapLayer newLayer = layers.get(layerIndex); if (oldLayer == newLayer) { return; } this.topLayer = layerIndex; firePropertyChange(PROPERTY_TOP_LAYER_INDEX, old, layerIndex); firePropertyChange(PROPERTY_TOP_LAYER, layers.get(old), layers.get(layerIndex)); EventUtils.moveListeners(oldLayer.getDecorator(), newLayer.getDecorator()); EventUtils.moveListeners(oldLayer, newLayer); } public void remove(HeatmapLayer layer) { if(getTopLayer() == layer) { int idx = layers.indexOf(layer) - 1; if (idx < 0) { setTopLayer(get(idx)); } else { setTopLayer(get(0)); } } else if(layers.indexOf(getTopLayer()) == layers.size()-1 ) { setTopLayer(layers.get(layers.size()-2)); } this.layers.remove(layer); this.updateLayers(); } @Override public String[] getIds() { return layersIdToIndex.keySet().toArray(new String[size()]); } @Override public HeatmapLayer get(String layer) { if (layer == null) { return null; } return layers.get(indexOf(layer)); } @Override public HeatmapLayer get(int layer) { return layers.get(layer); } public int indexOf(String id) { Integer layer = layersIdToIndex.get(id); if (layer == null) { return -1; } return layer; } public void setSelectedGroup(String selectedGroup) { String old = this.selectedGroup; this.selectedGroup = selectedGroup; firePropertyChange(PROPERTY_SELECTED_GROUP, old, selectedGroup); } @Override public String getSelectedGroup() { if (Strings.isNullOrEmpty(selectedGroup)) { return LayerDef.ALL_DATA_GROUP; } return selectedGroup; } @Override public Set<String> getGroups() { if (this.groups == null) { HashSet groups = new HashSet<>(); for (IMatrixLayer layer : layers) { groups.addAll(layer.getGroups()); } this.groups = groups; } return groups; } public String getId() { return MatrixLayers.LAYERS_ID; } @Override public int size() { return layers.size(); } public String getLabel(int index) { return layers.get(index).getId(); } public List<String> getLayerNames() { return layerNames; } public List<HeatmapLayer> asList() { return layers; } public void populateDetails(List<DetailsDecoration> details, IMatrix matrix, String row, String column) { int i = -1; String displayedGroup = getSelectedGroup(); for (HeatmapLayer layer : layers) { i++; boolean isSelected = (i == topLayer); if (!isSelected && displayedGroup != null && !layer.getGroups().contains(displayedGroup)) { continue; } layer.populateDetails(details, matrix, row, column, i, isSelected); } } @Override public Iterator<HeatmapLayer> iterator() { return layers.iterator(); } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; HeatmapLayers strings = (HeatmapLayers) o; return Objects.equal(getId(), strings.getId()); } @Override public int hashCode() { return getId().hashCode(); } }