List of usage examples for com.google.common.graph Network isDirected
@Override
boolean isDirected();
From source file:edu.uci.ics.jung.graph.util.TreeUtils.java
/** * A graph is "forest-shaped" if it is directed, acyclic, and each node has at most one * predecessor./*w ww .j a v a 2 s . c o m*/ */ public static <N> boolean isForestShaped(Network<N, ?> graph) { checkNotNull(graph, "graph"); return graph.isDirected() && !Graphs.hasCycle(graph) && graph.nodes().stream().allMatch(node -> graph.predecessors(node).size() <= 1); }
From source file:org.apache.beam.runners.dataflow.worker.graph.Networks.java
/** Returns a set of nodes sorted in topological order. */ public static <N, E> Set<N> topologicalOrder(Network<N, E> network) { // TODO: Upgrade Guava and remove this method if topological sorting becomes // supported externally or remove this comment if its not going to be supported externally. checkArgument(network.isDirected(), "Only directed networks are supported, given %s", network); checkArgument(!network.allowsSelfLoops(), "Only networks without self loops are supported, given %s", network);/*from w w w. ja v a 2s. com*/ // Linked hashset will prevent duplicates from appearing and will maintain insertion order. LinkedHashSet<N> nodes = new LinkedHashSet<>(network.nodes().size()); Queue<N> processingOrder = new ArrayDeque<>(); // Add all the roots for (N node : network.nodes()) { if (network.inDegree(node) == 0) { processingOrder.add(node); } } while (!processingOrder.isEmpty()) { N current = processingOrder.remove(); // If all predecessors have already been added, then we can add this node, otherwise // we need to add the node to the back of the processing queue. if (nodes.containsAll(network.predecessors(current))) { nodes.add(current); processingOrder.addAll(network.successors(current)); } else { processingOrder.add(current); } } return nodes; }
From source file:edu.uci.ics.jung.visualization.renderers.BasicEdgeRenderer.java
/** * Draws the edge <code>e</code>, whose endpoints are at <code>(x1,y1)</code> and <code>(x2,y2) * </code>, on the graphics context <code>g</code>. The <code>Shape</code> provided by the <code> * EdgeShapeFunction</code> instance is scaled in the x-direction so that its width is equal to * the distance between <code>(x1,y1)</code> and <code>(x2,y2)</code>. * * @param e the edge to be drawn//from w ww . java 2s . c o m */ protected void drawSimpleEdge(RenderContext<N, E> renderContext, VisualizationModel<N, E> visualizationModel, E e) { int[] coords = new int[4]; boolean[] loop = new boolean[1]; Shape edgeShape = prepareFinalEdgeShape(renderContext, visualizationModel, e, coords, loop); int x1 = coords[0]; int y1 = coords[1]; int x2 = coords[2]; int y2 = coords[3]; boolean isLoop = loop[0]; GraphicsDecorator g = renderContext.getGraphicsContext(); Network<N, E> network = visualizationModel.getNetwork(); Paint oldPaint = g.getPaint(); // get Paints for filling and drawing // (filling is done first so that drawing and label use same Paint) Paint fill_paint = renderContext.getEdgeFillPaintFunction().apply(e); if (fill_paint != null) { g.setPaint(fill_paint); g.fill(edgeShape); } Paint draw_paint = renderContext.getEdgeDrawPaintFunction().apply(e); if (draw_paint != null) { g.setPaint(draw_paint); g.draw(edgeShape); } float scalex = (float) g.getTransform().getScaleX(); float scaley = (float) g.getTransform().getScaleY(); // see if arrows are too small to bother drawing if (scalex < .3 || scaley < .3) { return; } if (renderContext.renderEdgeArrow()) { Stroke new_stroke = renderContext.getEdgeArrowStrokeFunction().apply(e); Stroke old_stroke = g.getStroke(); if (new_stroke != null) { g.setStroke(new_stroke); } Shape destNodeShape = renderContext.getNodeShapeFunction().apply(network.incidentNodes(e).nodeV()); AffineTransform xf = AffineTransform.getTranslateInstance(x2, y2); destNodeShape = xf.createTransformedShape(destNodeShape); AffineTransform at = edgeArrowRenderingSupport.getArrowTransform(renderContext, edgeShape, destNodeShape); if (at == null) { return; } Shape arrow = renderContext.getEdgeArrow(); arrow = at.createTransformedShape(arrow); g.setPaint(renderContext.getArrowFillPaintFunction().apply(e)); g.fill(arrow); g.setPaint(renderContext.getArrowDrawPaintFunction().apply(e)); g.draw(arrow); if (!network.isDirected()) { Shape nodeShape = renderContext.getNodeShapeFunction().apply(network.incidentNodes(e).nodeU()); xf = AffineTransform.getTranslateInstance(x1, y1); nodeShape = xf.createTransformedShape(nodeShape); at = edgeArrowRenderingSupport.getReverseArrowTransform(renderContext, edgeShape, nodeShape, !isLoop); if (at == null) { return; } arrow = renderContext.getEdgeArrow(); arrow = at.createTransformedShape(arrow); g.setPaint(renderContext.getArrowFillPaintFunction().apply(e)); g.fill(arrow); g.setPaint(renderContext.getArrowDrawPaintFunction().apply(e)); g.draw(arrow); } // restore paint and stroke if (new_stroke != null) { g.setStroke(old_stroke); } } // restore old paint g.setPaint(oldPaint); }
From source file:edu.uci.ics.jung.visualization.renderers.ReshapingEdgeRenderer.java
/** * Draws the edge <code>e</code>, whose endpoints are at <code>(x1,y1)</code> and <code>(x2,y2) * </code>, on the graphics context <code>g</code>. The <code>Shape</code> provided by the <code> * EdgeShapeFunction</code> instance is scaled in the x-direction so that its width is equal to * the distance between <code>(x1,y1)</code> and <code>(x2,y2)</code>. *///from www . j av a 2 s.c o m protected void drawSimpleEdge(RenderContext<N, E> renderContext, VisualizationModel<N, E> visualizationModel, E e) { TransformingGraphics g = (TransformingGraphics) renderContext.getGraphicsContext(); Network<N, E> graph = visualizationModel.getNetwork(); EndpointPair<N> endpoints = graph.incidentNodes(e); N v1 = endpoints.nodeU(); N v2 = endpoints.nodeV(); Point p1 = visualizationModel.getLayoutModel().apply(v1); Point p2 = visualizationModel.getLayoutModel().apply(v2); Point2D p12d = renderContext.getMultiLayerTransformer().transform(Layer.LAYOUT, new Point2D.Double(p1.x, p1.y)); Point2D p22d = renderContext.getMultiLayerTransformer().transform(Layer.LAYOUT, new Point2D.Double(p2.x, p2.y)); float x1 = (float) p12d.getX(); float y1 = (float) p12d.getY(); float x2 = (float) p22d.getX(); float y2 = (float) p22d.getY(); float flatness = 0; MutableTransformer transformer = renderContext.getMultiLayerTransformer().getTransformer(Layer.VIEW); if (transformer instanceof LensTransformer) { LensTransformer ht = (LensTransformer) transformer; RectangularShape lensShape = ht.getLens().getLensShape(); if (lensShape.contains(x1, y1) || lensShape.contains(x2, y2)) { flatness = .05f; } } boolean isLoop = v1.equals(v2); Shape s2 = renderContext.getNodeShapeFunction().apply(v2); Shape edgeShape = renderContext.getEdgeShapeFunction().apply(Context.getInstance(graph, e)); AffineTransform xform = AffineTransform.getTranslateInstance(x1, y1); if (isLoop) { // this is a self-loop. scale it is larger than the node // it decorates and translate it so that its nadir is // at the center of the node. Rectangle2D s2Bounds = s2.getBounds2D(); xform.scale(s2Bounds.getWidth(), s2Bounds.getHeight()); xform.translate(0, -edgeShape.getBounds2D().getWidth() / 2); } else { // this is a normal edge. Rotate it to the angle between // node endpoints, then scale it to the distance between // the nodes float dx = x2 - x1; float dy = y2 - y1; float thetaRadians = (float) Math.atan2(dy, dx); xform.rotate(thetaRadians); float dist = (float) Math.sqrt(dx * dx + dy * dy); xform.scale(dist, 1.0); } edgeShape = xform.createTransformedShape(edgeShape); Paint oldPaint = g.getPaint(); // get Paints for filling and drawing // (filling is done first so that drawing and label use same Paint) Paint fill_paint = renderContext.getEdgeFillPaintFunction().apply(e); if (fill_paint != null) { g.setPaint(fill_paint); g.fill(edgeShape, flatness); } Paint draw_paint = renderContext.getEdgeDrawPaintFunction().apply(e); if (draw_paint != null) { g.setPaint(draw_paint); g.draw(edgeShape, flatness); } float scalex = (float) g.getTransform().getScaleX(); float scaley = (float) g.getTransform().getScaleY(); // see if arrows are too small to bother drawing if (scalex < .3 || scaley < .3) { return; } if (renderContext.renderEdgeArrow()) { Shape destNodeShape = renderContext.getNodeShapeFunction().apply(v2); AffineTransform xf = AffineTransform.getTranslateInstance(x2, y2); destNodeShape = xf.createTransformedShape(destNodeShape); AffineTransform at = edgeArrowRenderingSupport.getArrowTransform(renderContext, new GeneralPath(edgeShape), destNodeShape); if (at == null) { return; } Shape arrow = renderContext.getEdgeArrow(); arrow = at.createTransformedShape(arrow); g.setPaint(renderContext.getArrowFillPaintFunction().apply(e)); g.fill(arrow); g.setPaint(renderContext.getArrowDrawPaintFunction().apply(e)); g.draw(arrow); if (!graph.isDirected()) { Shape nodeShape = renderContext.getNodeShapeFunction().apply(v1); xf = AffineTransform.getTranslateInstance(x1, y1); nodeShape = xf.createTransformedShape(nodeShape); at = edgeArrowRenderingSupport.getReverseArrowTransform(renderContext, new GeneralPath(edgeShape), nodeShape, !isLoop); if (at == null) { return; } arrow = renderContext.getEdgeArrow(); arrow = at.createTransformedShape(arrow); g.setPaint(renderContext.getArrowFillPaintFunction().apply(e)); g.fill(arrow); g.setPaint(renderContext.getArrowDrawPaintFunction().apply(e)); g.draw(arrow); } } // use existing paint for text if no draw paint specified if (draw_paint == null) { g.setPaint(oldPaint); } // restore old paint g.setPaint(oldPaint); }