/** * Copyright (C) 2001-2017 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero 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 * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.gui.graphs; import java.awt.Component; import java.awt.Dimension; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import com.rapidminer.gui.look.Colors; import edu.uci.ics.jung.algorithms.layout.Layout; import edu.uci.ics.jung.graph.Graph; import edu.uci.ics.jung.graph.util.Context; import edu.uci.ics.jung.graph.util.Pair; import edu.uci.ics.jung.visualization.Layer; import edu.uci.ics.jung.visualization.RenderContext; import edu.uci.ics.jung.visualization.renderers.EdgeLabelRenderer; import edu.uci.ics.jung.visualization.renderers.Renderer; import edu.uci.ics.jung.visualization.transform.shape.GraphicsDecorator; /** * This code is the basic edge label renderer from Jung (unfortunately there was no author given in * the original source) but it was changed so that the labels are always painted in the center * location of the edge. * * @author Ingo Mierswa */ public class TreeModelEdgeLabelRenderer<V, E> implements Renderer.EdgeLabel<V, E> { public Component prepareRenderer(RenderContext<V, E> rc, EdgeLabelRenderer graphLabelRenderer, Object value, boolean isSelected, E edge) { return rc.getEdgeLabelRenderer().<E> getEdgeLabelRendererComponent(rc.getScreenDevice(), value, rc.getEdgeFontTransformer().transform(edge), isSelected, edge); } @Override public void labelEdge(RenderContext<V, E> rc, Layout<V, E> layout, E e, String label) { if (label == null || label.length() == 0) { return; } Graph<V, E> graph = layout.getGraph(); // don't draw edge if either incident vertex is not drawn Pair<V> endpoints = graph.getEndpoints(e); V v1 = endpoints.getFirst(); V v2 = endpoints.getSecond(); if (!rc.getVertexIncludePredicate().evaluate(Context.<Graph<V, E>, V> getInstance(graph, v1)) || !rc.getVertexIncludePredicate().evaluate(Context.<Graph<V, E>, V> getInstance(graph, v2))) { return; } Point2D p1 = layout.transform(v1); Point2D p2 = layout.transform(v2); p1 = rc.getMultiLayerTransformer().transform(Layer.LAYOUT, p1); p2 = rc.getMultiLayerTransformer().transform(Layer.LAYOUT, p2); float x1 = (float) p1.getX(); float y1 = (float) p1.getY(); float x2 = (float) p2.getX(); float y2 = (float) p2.getY(); GraphicsDecorator g = rc.getGraphicsContext(); float distX = x2 - x1; float distY = y2 - y1; double totalLength = Math.sqrt(distX * distX + distY * distY); double closeness = rc.getEdgeLabelClosenessTransformer().transform(Context.<Graph<V, E>, E> getInstance(graph, e)) .doubleValue(); int posX = (int) (x1 + closeness * distX); int posY = (int) (y1 + closeness * distY); int xDisplacement = 0; int yDisplacement = 0; xDisplacement = (int) (rc.getLabelOffset() * (distX / totalLength)); yDisplacement = (int) (rc.getLabelOffset() * (-distY / totalLength)); AffineTransform old = g.getTransform(); AffineTransform xform = new AffineTransform(old); xform.translate(posX + xDisplacement, posY + yDisplacement); double parallelOffset = 0.0d; Component component = prepareRenderer(rc, rc.getEdgeLabelRenderer(), label, rc.getPickedEdgeState().isPicked(e), e); Dimension d = component.getPreferredSize(); xform.translate(-d.width / 2.0d, -(d.height / 2.0d - parallelOffset)); g.setTransform(xform); g.setColor(Colors.WHITE); g.draw(component, rc.getRendererPane(), 0, 0, d.width, d.height, true); g.setTransform(old); } }