/*
* #%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.ui.app.heatmap.drawer.header;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import org.gitools.heatmap.Heatmap;
import org.gitools.heatmap.HeatmapDimension;
import org.gitools.heatmap.header.HeatmapColoredLabelsHeader;
import org.gitools.heatmap.header.HeatmapDecoratorHeader;
import org.gitools.heatmap.header.HeatmapHeader;
import org.gitools.heatmap.header.HeatmapTextLabelsHeader;
import org.gitools.ui.app.heatmap.drawer.AbstractHeatmapDrawer;
import org.gitools.ui.app.heatmap.drawer.AbstractHeatmapHeaderDrawer;
import org.gitools.ui.core.HeatmapPosition;
import java.awt.*;
import java.util.*;
import java.util.List;
public class HeatmapHeaderIntersectionDrawer extends AbstractHeatmapDrawer {
private final HeatmapHeaderDrawer colDrawer;
private final HeatmapHeaderDrawer rowDrawer;
private Multimap headerLegendDrawers;
private Map<Object, Integer> XCoordinates;
private Map<Object, Integer> YCoordinates;
/* Map that contains the header that are responsible for drawing the
* legend of a header from the other dimension (row,cols) as for example:
* HeatmapColoredLabelsHeader --> draws for --> HeatmapDataHeatmapHeader */
private static final Map<Class<?>, Class<?>> headerRelationsMap = new HashMap<>();
static {
headerRelationsMap.put(HeatmapColoredLabelsHeader.class, HeatmapDecoratorHeader.class);
headerRelationsMap.put(HeatmapTextLabelsHeader.class, HeatmapDecoratorHeader.class);
}
public HeatmapHeaderIntersectionDrawer(Heatmap heatmap, HeatmapHeaderDrawer colDrawer, HeatmapHeaderDrawer rowDrawer) {
super(heatmap);
this.colDrawer = colDrawer;
this.rowDrawer = rowDrawer;
updateDrawers(null);
}
private boolean isCompatiblePair(HeatmapHeader thisHeader, HeatmapHeader oppositeHeader) {
boolean answer = false;
if (headerRelationsMap.get(thisHeader.getClass()) == oppositeHeader.getClass()) {
String pattern1 = thisHeader.getAnnotationPattern();
String pattern2 = oppositeHeader.getAnnotationPattern();
answer = pattern1 != null && pattern2 != null &&
thisHeader.getAnnotationPattern().equals(oppositeHeader.getAnnotationPattern());
}
return answer;
}
public final void updateDrawers(HeatmapDimension evtSrc) {
if (getHeatmap().getRows() == evtSrc) {
rowDrawer.update();
}
if (getHeatmap().getColumns() == evtSrc) {
colDrawer.update();
}
getHeaderDrawers();
}
private void getHeaderDrawers() {
XCoordinates = new HashMap<>();
YCoordinates = new HashMap<>();
List<AbstractHeatmapHeaderDrawer> colHeaderDrawers = colDrawer.getDrawers();
List<AbstractHeatmapHeaderDrawer> rowHeaderDrawers = rowDrawer.getDrawers();
List<HeatmapHeader> rowHeaders = getHeatmap().getRows().getHeaders();
List<HeatmapHeader> colHeaders = getHeatmap().getColumns().getHeaders();
headerLegendDrawers = HashMultimap.create();
int XPosition = 0;
for (AbstractHeatmapHeaderDrawer d : rowHeaderDrawers) {
HeatmapHeader thisH = rowHeaders.get(rowHeaderDrawers.indexOf(d));
XCoordinates.put(d, XPosition);
XCoordinates.put(thisH, XPosition);
for (HeatmapHeader oppositeH : colHeaders) {
if (isCompatiblePair(thisH, oppositeH)) {
headerLegendDrawers.put(d, oppositeH);
}
}
XPosition += d.getSize().width;
}
int colHeaderSize = 0;
for (AbstractHeatmapDrawer d : colHeaderDrawers) {
colHeaderSize += d.getSize().height;
}
for (AbstractHeatmapDrawer d : colHeaderDrawers) {
HeatmapHeader thisH = colHeaders.get(colHeaderDrawers.indexOf(d));
int size = d.getSize().height;
colHeaderSize -= size;
YCoordinates.put(d, colHeaderSize);
YCoordinates.put(thisH, colHeaderSize);
for (HeatmapHeader oppositeH : rowHeaders) {
if (isCompatiblePair(thisH, oppositeH)) {
headerLegendDrawers.put(d, oppositeH);
}
}
}
}
@Override
public Dimension getSize() {
return new Dimension(rowDrawer.getSize().width, colDrawer.getSize().height);
}
@Override
public void draw(Graphics2D g, Rectangle box, Rectangle clip) {
// Clear background
g.setColor(Color.WHITE);
g.fillRect(clip.x, clip.y, clip.width, clip.height);
Dimension d = getSize();
int width = d.width < box.width ? d.width : box.width;
int height = box.height;
/* g.setColor(Color.pink);
g.fillRect(box.x,box.y,width,height); */
drawHeaderIntersection(g, new Rectangle(box.x, box.y, width, height));
}
@Override
public HeatmapPosition getPosition(Point p) {
return new HeatmapPosition(getHeatmap(), colDrawer.getSize().width, 0);
}
@Override
public Point getPoint(HeatmapPosition p) {
return new Point(0, 0);
}
void drawHeaderIntersection(Graphics2D g, Rectangle headerIntersection) {
getHeaderDrawers();
if (headerLegendDrawers == null || headerLegendDrawers.size() == 0) {
return;
}
Set legendDrawers = headerLegendDrawers.keySet();
for (Object d : legendDrawers) {
AbstractHeatmapHeaderDrawer drawer = (AbstractHeatmapHeaderDrawer) d;
Collection headers = headerLegendDrawers.get(d);
for (Object h : headers) {
HeatmapHeader header = (HeatmapHeader) h;
if (!header.isVisible()) {
continue;
}
int x;
int y;
int width;
int height;
if (drawer.isHorizontal()) {
x = XCoordinates.get(header);
y = YCoordinates.get(drawer);
width = header.getSize();
height = drawer.getSize().height;
} else {
x = XCoordinates.get(drawer);
y = YCoordinates.get(header);
width = drawer.getSize().width;
height = header.getSize();
}
Rectangle legendLimits = new Rectangle(x + headerIntersection.x, y + headerIntersection.y, width, height);
drawer.drawHeaderLegend(g, legendLimits, header);
}
}
}
}