/* * #%L * gitools-ui-app * %% * 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% */ /******************************************************************************* * Copyright 2013 Lars Behnke * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package org.gitools.ui.app.analysis.clustering.visualization; import org.gitools.heatmap.header.HierarchicalCluster; import java.awt.*; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.List; public class ClusterComponent implements Paintable { private HierarchicalCluster cluster; private VCoord linkPoint; private VCoord initPoint; private boolean printName; private int dotRadius = 2; private int namePadding = 6; private List<ClusterComponent> children; public List<ClusterComponent> getChildren() { if (children == null) { children = new ArrayList<ClusterComponent>(); } return children; } public int getNamePadding() { return namePadding; } public void setNamePadding(int namePadding) { this.namePadding = namePadding; } public int getDotRadius() { return dotRadius; } public void setDotRadius(int dotRadius) { this.dotRadius = dotRadius; } public void setChildren(List<ClusterComponent> children) { this.children = children; } public VCoord getLinkPoint() { return linkPoint; } public void setLinkPoint(VCoord linkPoint) { this.linkPoint = linkPoint; } public VCoord getInitPoint() { return initPoint; } public void setInitPoint(VCoord initPoint) { this.initPoint = initPoint; } public HierarchicalCluster getCluster() { return cluster; } public void setCluster(HierarchicalCluster cluster) { this.cluster = cluster; } public boolean isPrintName() { return printName; } public void setPrintName(boolean printName) { this.printName = printName; } public ClusterComponent(HierarchicalCluster cluster, boolean printName, VCoord initPoint) { this.printName = printName; this.cluster = cluster; this.initPoint = initPoint; this.linkPoint = initPoint; } @Override public void paint(Graphics2D g, int xDisplayOffset, int yDisplayOffset, double xDisplayFactor, double yDisplayFactor, boolean decorated) { int x1, y1, x2, y2; FontMetrics fontMetrics = g.getFontMetrics(); x1 = (int) (initPoint.getX() * xDisplayFactor + xDisplayOffset); y1 = (int) (initPoint.getY() * yDisplayFactor + yDisplayOffset); x2 = (int) (linkPoint.getX() * xDisplayFactor + xDisplayOffset); y2 = y1; g.fillOval(x1 - dotRadius, y1 - dotRadius, dotRadius * 2, dotRadius * 2); g.drawLine(x1, y1, x2, y2); if (cluster.isLeaf()) { g.drawString(cluster.getName(), x1 + namePadding, y1 + (fontMetrics.getHeight() / 2) - 2); } if (decorated && cluster.getDistance() != null && !cluster.getDistance().isNaN() && cluster.getDistance() > 0) { String s = String.format("%.2f", cluster.getDistance()); Rectangle2D rect = fontMetrics.getStringBounds(s, g); g.drawString(s, x1 - (int) rect.getWidth(), y1 - 2); } x1 = x2; y1 = y2; y2 = (int) (linkPoint.getY() * yDisplayFactor + yDisplayOffset); g.drawLine(x1, y1, x2, y2); for (ClusterComponent child : children) { child.paint(g, xDisplayOffset, yDisplayOffset, xDisplayFactor, yDisplayFactor, decorated); } } public double getRectMinX() { // TODO Better use closure / callback here assert initPoint != null && linkPoint != null; double val = Math.min(initPoint.getX(), linkPoint.getX()); for (ClusterComponent child : getChildren()) { val = Math.min(val, child.getRectMinX()); } return val; } public double getRectMinY() { // TODO Better use closure here assert initPoint != null && linkPoint != null; double val = Math.min(initPoint.getY(), linkPoint.getY()); for (ClusterComponent child : getChildren()) { val = Math.min(val, child.getRectMinY()); } return val; } public double getRectMaxX() { // TODO Better use closure here assert initPoint != null && linkPoint != null; double val = Math.max(initPoint.getX(), linkPoint.getX()); for (ClusterComponent child : getChildren()) { val = Math.max(val, child.getRectMaxX()); } return val; } public double getRectMaxY() { // TODO Better use closure here assert initPoint != null && linkPoint != null; double val = Math.max(initPoint.getY(), linkPoint.getY()); for (ClusterComponent child : getChildren()) { val = Math.max(val, child.getRectMaxY()); } return val; } public int getNameWidth(Graphics2D g, boolean includeNonLeafs) { int width = 0; if (includeNonLeafs || cluster.isLeaf()) { Rectangle2D rect = g.getFontMetrics().getStringBounds(cluster.getName(), g); width = (int) rect.getWidth(); } return width; } public int getMaxNameWidth(Graphics2D g, boolean includeNonLeafs) { int width = getNameWidth(g, includeNonLeafs); for (ClusterComponent comp : getChildren()) { int childWidth = comp.getMaxNameWidth(g, includeNonLeafs); if (childWidth > width) { width = childWidth; } } return width; } }