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

org.jungrapht.visualization.layout.algorithms.util.TreeView Maven / Gradle / Ivy

The newest version!
package org.jungrapht.visualization.layout.algorithms.util;

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.jgrapht.Graph;
import org.jgrapht.graph.builder.GraphTypeBuilder;
import org.jungrapht.visualization.layout.algorithms.Layered;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TreeView {

  public static class Builder, B extends Builder> {
    protected Predicate rootPredicate = v -> true;
    protected Comparator rootComparator = (v1, v2) -> 0;
    protected Predicate vertexPredicate = Layered.truePredicate;
    protected Predicate edgePredicate = Layered.truePredicate;
    protected Comparator vertexComparator = Layered.noopComparator;
    protected Comparator edgeComparator = Layered.noopComparator;

    /** {@inheritDoc} */
    protected B self() {
      return (B) this;
    }

    /** {@inheritDoc} */
    public B rootPredicate(Predicate rootPredicate) {
      this.rootPredicate = rootPredicate;
      return self();
    }

    public B rootComparator(Comparator rootComparator) {
      this.rootComparator = rootComparator;
      return self();
    }

    /**
     * @param vertexPredicate {@link Predicate} to apply to vertices
     * @return this Builder
     */
    public B vertexPredicate(Predicate vertexPredicate) {
      this.vertexPredicate = vertexPredicate;
      return self();
    }

    /**
     * @param edgePredicate {@link Predicate} to apply to edges
     * @return this Builder
     */
    public B edgePredicate(Predicate edgePredicate) {
      this.edgePredicate = edgePredicate;
      return self();
    }

    /**
     * @param vertexComparator {@link Comparator} to sort vertices
     * @return this Builder
     */
    public B vertexComparator(Comparator vertexComparator) {
      this.vertexComparator = vertexComparator;
      return self();
    }

    /**
     * @param edgeComparator {@link Comparator} to sort edges
     * @return this Builder
     */
    public B edgeComparator(Comparator edgeComparator) {
      this.edgeComparator = edgeComparator;
      return self();
    }

    /** {@inheritDoc} */
    public T build() {
      return (T) new TreeView<>(this);
    }
  }
  /**
   * @param  vertex type
   * @param  edge type
   * @return a Builder ready to configure
   */
  public static  Builder builder() {
    return new Builder<>();
  }

  private static final Logger log = LoggerFactory.getLogger(TreeView.class);
  protected Predicate rootPredicate;
  protected Comparator rootComparator;
  protected Predicate vertexPredicate;
  protected Predicate edgePredicate;
  protected Comparator vertexComparator;
  protected Comparator edgeComparator;

  TreeView(Builder builder) {
    this(
        builder.rootPredicate,
        builder.rootComparator,
        builder.vertexPredicate,
        builder.edgePredicate,
        builder.vertexComparator,
        builder.edgeComparator);
  }

  TreeView(
      Predicate rootPredicate,
      Comparator rootComparator,
      Predicate vertexPredicate,
      Predicate edgePredicate,
      Comparator vertexComparator,
      Comparator edgeComparator) {
    this.rootPredicate = rootPredicate;
    this.rootComparator = rootComparator;
    this.vertexPredicate = vertexPredicate;
    this.edgePredicate = edgePredicate;
    this.vertexComparator = vertexComparator;
    this.edgeComparator = edgeComparator;
  }

  public Graph buildTree(Graph graph) {

    Graph tree = GraphTypeBuilder.directed().buildGraph();

    Set seen = new HashSet<>();
    List roots =
        graph
            .vertexSet()
            .stream()
            .filter(rootPredicate)
            .sorted(rootComparator)
            .collect(Collectors.toList());
    // add all the graph roots to the tree. some my have no incident edges
    roots.forEach(tree::addVertex);
    for (V root : roots) {
      buildTree(graph, tree, seen, root);
    }
    return tree;
  }

  private void buildTree(Graph graph, Graph tree, Set seen, V vertex) {
    if (seen.add(vertex)) {
      for (E edge :
          graph
              .outgoingEdgesOf(vertex)
              .stream()
              .sorted(edgeComparator)
              .collect(Collectors.toCollection(LinkedHashSet::new))) {
        if (edgePredicate.test(edge)
            || graph.incomingEdgesOf(graph.getEdgeTarget(edge)).stream().noneMatch(edgePredicate)) {
          V v = graph.getEdgeTarget(edge);
          if (!rootPredicate.test(v) && !seen.contains(v)) {
            tree.addVertex(vertex);
            tree.addVertex(v);
            tree.addEdge(vertex, v, edge);
            buildTree(graph, tree, seen, v);
          }
        }
      }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy