Package org.graphstream.ui.swingViewer.basicRenderer

Source Code of org.graphstream.ui.swingViewer.basicRenderer.EdgeRenderer

/*
* Copyright 2006 - 2013
*     Stefan Balev     <stefan.balev@graphstream-project.org>
*     Julien Baudry    <julien.baudry@graphstream-project.org>
*     Antoine Dutot    <antoine.dutot@graphstream-project.org>
*     Yoann Pigné      <yoann.pigne@graphstream-project.org>
*     Guilhelm Savin   <guilhelm.savin@graphstream-project.org>
*
* This file is part of GraphStream <http://graphstream-project.org>.
*
* 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 <http://www.cecill.info> 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 <http://www.gnu.org/licenses/>.
*
* 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.
*/
package org.graphstream.ui.swingViewer.basicRenderer;

import org.graphstream.ui.geom.Vector2;
import org.graphstream.ui.graphicGraph.GraphicEdge;
import org.graphstream.ui.graphicGraph.GraphicElement;
import org.graphstream.ui.graphicGraph.GraphicNode;
import org.graphstream.ui.graphicGraph.StyleGroup;
import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants;
import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants.ArrowShape;
import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants.FillMode;
import org.graphstream.ui.graphicGraph.stylesheet.StyleConstants.SizeMode;
import org.graphstream.ui.graphicGraph.stylesheet.Values;
import org.graphstream.ui.view.Camera;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;

public class EdgeRenderer extends ElementRenderer {
  protected Line2D shape = new Line2D.Double();

  protected double width = 1;

  protected double arrowLength = 0;

  protected double arrowWidth = 0;

  @Override
  protected void setupRenderingPass(StyleGroup group, Graphics2D g,
      Camera camera) {
    configureText(group, camera);
  }

  @Override
  protected void pushDynStyle(StyleGroup group, Graphics2D g, Camera camera,
      GraphicElement element) {
    Color color = group.getFillColor(0);

    if (element != null && group.getFillMode() == FillMode.DYN_PLAIN)
      color = interpolateColor(group, element);

    g.setColor(color);

    if (group.getSizeMode() == SizeMode.DYN_SIZE) {
      width = camera.getMetrics().lengthToGu(
          StyleConstants
              .convertValue(element.getAttribute("ui.size")));
      // width = camera.getMetrics().lengthToGu( (double)
      // element.getNumber( "ui.size" ), Units.PX );

      g.setStroke(new BasicStroke((float) width, BasicStroke.CAP_BUTT,
          BasicStroke.JOIN_BEVEL));
    }
  }

  @Override
  protected void pushStyle(StyleGroup group, Graphics2D g, Camera camera) {
    width = camera.getMetrics().lengthToGu(group.getSize(), 0);
    arrowLength = camera.getMetrics().lengthToGu(group.getArrowSize(), 0);
    arrowWidth = camera.getMetrics().lengthToGu(group.getArrowSize(),
        group.getArrowSize().size() > 1 ? 1 : 0);

    g.setColor(group.getFillColor(0));
    g.setStroke(new BasicStroke((float) width, BasicStroke.CAP_BUTT,
        BasicStroke.JOIN_BEVEL));
  }

  @Override
  protected void elementInvisible(StyleGroup group, Graphics2D g,
      Camera camera, GraphicElement element) {
  }

  @Override
  protected void renderElement(StyleGroup group, Graphics2D g, Camera camera,
      GraphicElement element) {
    GraphicEdge edge = (GraphicEdge) element;
    GraphicNode node0 = (GraphicNode) edge.getNode0();
    GraphicNode node1 = (GraphicNode) edge.getNode1();

    shape.setLine(node0.x, node0.y, node1.x, node1.y);
    g.draw(shape);
    renderArrow(group, g, camera, edge);
    renderText(group, g, camera, element);
  }

  protected void renderArrow(StyleGroup group, Graphics2D g, Camera camera,
      GraphicEdge edge) {
    if (edge.isDirected() && arrowWidth > 0 && arrowLength > 0) {
      if (group.getArrowShape() != ArrowShape.NONE) {
        Path2D shape = new Path2D.Double();
        GraphicNode node0 = (GraphicNode) edge.getNode0();
        GraphicNode node1 = (GraphicNode) edge.getNode1();
        double off = evalEllipseRadius(edge, node0, node1, camera);
        Vector2 theDirection = new Vector2(node1.getX() - node0.getX(),
            node1.getY() - node0.getY());

        theDirection.normalize();

        double x = node1.x - (theDirection.data[0] * off);
        double y = node1.y - (theDirection.data[1] * off);
        Vector2 perp = new Vector2(theDirection.data[1],
            -theDirection.data[0]);

        perp.normalize();
        theDirection.scalarMult(arrowLength);
        perp.scalarMult(arrowWidth);

        // Create a polygon.

        shape.reset();
        shape.moveTo(x, y);
        shape.lineTo(x - theDirection.data[0] + perp.data[0], y
            - theDirection.data[1] + perp.data[1]);
        shape.lineTo(x - theDirection.data[0] - perp.data[0], y
            - theDirection.data[1] - perp.data[1]);
        shape.closePath();

        g.fill(shape);
      }
    }
  }

  protected double evalEllipseRadius(GraphicEdge edge, GraphicNode node0,
      GraphicNode node1, Camera camera) {
    Values size = node1.getStyle().getSize();
    double w = camera.getMetrics().lengthToGu(size.get(0), size.getUnits());
    double h = size.size() > 1 ? camera.getMetrics().lengthToGu(
        size.get(1), size.getUnits()) : w;

    w /= 2;
    h /= 2;
       
    if (w == h)
      return w; // Welcome simplification for circles ...

    // Vector of the entering edge.
    double dx = node1.getX() - node0.getX();
    double dy = node1.getY() - node0.getY();

    // The entering edge must be deformed by the ellipse ratio to find the
    // correct angle.

    dy *= (w / h);

    // Find the angle of the entering vector with (1,0).

    double d = Math.sqrt(dx * dx + dy * dy);
    double a = dx / d;

    // Compute the coordinates at which the entering vector and the ellipse
    // cross.

    a = Math.acos(a);
    dx = Math.cos(a) * w;
    dy = Math.sin(a) * h;

    // The distance from the ellipse center to the crossing point of the
    // ellipse and vector:

    return Math.sqrt(dx * dx + dy * dy);
  }
}
TOP

Related Classes of org.graphstream.ui.swingViewer.basicRenderer.EdgeRenderer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.