All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.graphstream.ui.graphicGraph.GraphicEdge Maven / Gradle / Ivy

/*
 * This file is part of GraphStream .
 * 
 * GraphStream is a library whose purpose is to handle static or dynamic
 * graph, create them from scratch, file or any source and display them.
 * 
 * This program is free software distributed under the terms of two licenses, the
 * CeCILL-C license that fits European law, and the GNU Lesser General Public
 * License. You can  use, modify and/ or redistribute the software under the terms
 * of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
 * URL  or under the terms of the GNU LGPL 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 Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 * 
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
 */

/**
 * @since 2009-02-19
 * 
 * @author Guilhelm Savin 
 * @author Antoine Dutot 
 * @author Yoann Pigné 
 * @author Alex Bowen 
 * @author Hicham Brahimi 
 */
package org.graphstream.ui.graphicGraph;

import org.graphstream.graph.Edge;
import org.graphstream.graph.Node;
import org.graphstream.stream.SourceBase.ElementType;
import org.graphstream.ui.graphicGraph.stylesheet.Selector;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * Graphical edge.
 * 
 * 

* The graphic edge defines its source and target node as well as a direction, a * string label and a style from the style sheet. *

* * @see GraphicGraph */ public class GraphicEdge extends GraphicElement implements Edge { // Attributes /** * The first node. */ public GraphicNode from; /** * The second node. */ public GraphicNode to; /** * Is the edge directed ?. */ public boolean directed; /** * In case of a multi-graph this is the index of the edge between to and from. */ public int multi; /** * If non null, this gives the number of edges between the two same nodes. */ public EdgeGroup group; /** * Control points for curved edges or polylines. This contains the control * points of an edge. If the edge is in 2D each sequence of two cells gives the * x and y coordinates of a control point. Else each sequence of three cells * gives the x, y and z coordinates. Therefore the number of control points can * be obtained by dividing by 2 or 3 the length of this array. For example for * cubic Bezier curves in 2D this array contains four cells. The control points * are ordered from node0 to node1. */ public double[] ctrl; // Constructors /** * New graphic edge. * * @param id * The edge unique identifier. * @param from * The source node. * @param to * The target node. * @param dir * True if the edge is directed in the direction from-to. * @param attributes * A set of initial attributes. */ public GraphicEdge(String id, GraphicNode from, GraphicNode to, boolean dir, HashMap attributes) { super(id, from.mygraph); this.from = from; this.to = to; this.directed = dir; if (this.attributes == null) this.attributes = new HashMap(); if (attributes != null) setAttributes(attributes); } @Override public Selector.Type getSelectorType() { return Selector.Type.EDGE; } /** * Obtain the node that is not "n" attached to this edge. * * @param n * One of the node of this edge. * @return The other node of this edge. */ public GraphicNode otherNode(GraphicNode n) { return (GraphicNode) getOpposite(n); } @Override public double getX() { return from.x + ((to.x - from.x) / 2); } @Override public double getY() { return from.y + ((to.y - from.y) / 2); } @Override public double getZ() { return from.z + ((to.z - from.z) / 2); } /** * Control points for curved edges or polylines. This contains the control * points of an edge. If the edge is in 2D each sequence of two cells gives the * x and y coordinates of a control point. Else each sequence of three cells * gives the x, y and z coordinates. Therefore the number of control points can * be obtained by dividing by 2 or 3 the length of this array. For example for * cubic Bezier curves in 2D this array contains four cells. The control points * are ordered from node0 to node1. The units are "graph units". * * @return The control points coordinates or null if this edge is a straight * line. */ public double[] getControlPoints() { return ctrl; } /** * True if the the edge defines control points to draw a curve or polyline. This * does not mean the edge style asks to paint the edge as a curve, only that * control points are defined. * * @return True if control points are available. */ public boolean isCurve() { return ctrl != null; } /** * Change the control points array for this edge. * * @param points * The new set of points. See the {@link #getControlPoints()} method * for an explanation on the organisation of this array. * @see #getControlPoints() */ public void setControlPoints(double points[]) { ctrl = points; } /** * This edge is the i-th between the two same nodes. * * @return The edge index between the two nodes if there are several such edges. */ public int getMultiIndex() { return multi; } @Override public void move(double x, double y, double z) { // NOP on edges !!! } @Override protected void attributeChanged(AttributeChangeEvent event, String attribute, Object oldValue, Object newValue) { super.attributeChanged(event, attribute, oldValue, newValue); if (attribute.startsWith("ui.sprite.")) { mygraph.spriteAttribute(event, this, attribute, newValue); } mygraph.listeners.sendAttributeChangedEvent(getId(), ElementType.EDGE, attribute, event, oldValue, newValue); } /** * Count the number of identical edges between the two nodes of this edge and * create or update the edge group. The edge group contains all the edges * between two same nodes and allows to render faster multiple edges in a * multigraph. * * @param edgeList * The actual set of edges between two nodes (see the connectivity in * the graphic graph). */ protected void countSameEdges(Iterable edgeList) { for (GraphicEdge other : edgeList) { if (other != this) { if ((other.from == from && other.to == to) || (other.to == from && other.from == to)) { group = other.group; if (group == null) group = new EdgeGroup(other, this); else group.increment(this); break; } } } } @Override public void removed() { if (group != null) { group.decrement(this); if (group.getCount() == 1) group = null; } } // Edge interface @Override public Node getNode0() { return from; } @Override public Node getNode1() { return to; } /** * If there are several edges between two nodes, this edge pertains to a group. * Else this method returns null. * * @return The group of edges between two same nodes, null if the edge is alone * between the two nodes. */ public EdgeGroup getGroup() { return group; } @Override public Node getOpposite(Node node) { if (node == from) return to; return from; } @Override public Node getSourceNode() { return from; } @Override public Node getTargetNode() { return to; } public boolean isDirected() { return directed; } public boolean isLoop() { return (from == to); } public void setDirected(boolean on) { directed = on; // / XXX } public void switchDirection() { GraphicNode tmp; // XXX tmp = from; from = to; to = tmp; } // Nested classes /** * An edge group contains the set of edges between two given nodes. This allows * to quickly know how many 'multi' edges there is between two nodes in a * multigraph and to associate invariant indices to edges (the * {@link GraphicEdge#multi} attribute) inside the multi-representation. */ public class EdgeGroup { /** * The set of multiple edges. */ public ArrayList edges; /** * Create a new edge group, starting with two edges. * * @param first * The initial edge. * @param second * The second edge. */ public EdgeGroup(GraphicEdge first, GraphicEdge second) { edges = new ArrayList(); first.group = this; second.group = this; edges.add(first); edges.add(second); first.multi = 0; second.multi = 1; } /** * I-th edge of the group. * * @param i * The edge index. * @return The i-th edge. */ public GraphicEdge getEdge(int i) { return edges.get(i); } /** * Number of edges in this group. * * @return The edge count. */ public int getCount() { return edges.size(); } /** * Add an edge in the group. * * @param edge * The edge to add. */ public void increment(GraphicEdge edge) { edge.multi = getCount(); edges.add(edge); } /** * Remove an edge from the group. * * @param edge * The edge to remove. */ public void decrement(GraphicEdge edge) { edges.remove(edges.indexOf(edge)); for (int i = 0; i < edges.size(); i++) edges.get(i).multi = i; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy