// TODO: cache required protected int getEdgeIndex(EdgeItem e) { if (isIgnored(e)) { return -1; } NodeItem sourceItem = e.getSourceItem(); NodeItem targetItem = e.getTargetItem(); Iterator<EdgeItem> edges = sourceItem.edges(); // number of equal edges = same target and source int equalEdges = 0; // number of nearequal edges = same nodes, but any order target and source int sameEdges = 0; int edgeIndex = 0; int row = e.getRow(); while (edges.hasNext()) { EdgeItem edge = edges.next(); int edgeRow = edge.getRow(); if (isIgnored(edge)) { continue; } if (edge.getSourceItem() == sourceItem && edge.getTargetItem() == targetItem) { if (row == edgeRow) { edgeIndex = equalEdges; } equalEdges++; sameEdges++; } else if (edge.getSourceItem() == targetItem && edge.getTargetItem() == sourceItem) { sameEdges++; } } // draw the line straight if we found one edge if (lineForSingleEdge && edgeIndex == 0 && sameEdges == 1) { return -1; } else if (sameEdges > 1) { edgeIndex++; } return edgeIndex; }
protected boolean isDirected(EdgeItem e) { return e.isDirected(); }
protected boolean isIgnored(EdgeItem e) { return e.isAggregating(); }
/** @see prefuse.render.AbstractShapeRenderer#getRawShape(prefuse.visual.VisualItem) */ @Override protected Shape getRawShape(VisualItem item) { EdgeItem e = (EdgeItem) item; VisualItem source = e.getSourceItem(); VisualItem target = e.getTargetItem(); int type = m_edgeType; int edgeIndex = -1; getAlignedPoint(m_tmpPoints[0], source.getBounds(), m_xAlign1, m_yAlign1); getAlignedPoint(m_tmpPoints[1], target.getBounds(), m_xAlign2, m_yAlign2); m_curWidth = (float) (m_width * getLineWidth(item)); boolean curveCtrlPtsReady = false; Polygon arrowHead; // create the arrow head, if needed if (isDirected(e) && m_edgeArrow != Constants.EDGE_ARROW_NONE && (arrowHead = getArrowHead(e)) != null) { // get starting and ending edge endpoints boolean forward = (m_edgeArrow == Constants.EDGE_ARROW_FORWARD); Point2D start = null, end = null; start = m_tmpPoints[forward ? 0 : 1]; end = m_tmpPoints[forward ? 1 : 0]; // compute the intersection with the source/target bounding box VisualItem src = getSourceItem(e, forward); VisualItem dest = getTargetItem(e, forward); if (edgeBounded && !e.isAggregating()) { adjustEndingPoint(start, end, src, dest); } else if (GraphicsLib.intersectLineRectangle(start, end, dest.getBounds(), m_isctPoints) > 0) { end.setLocation(m_isctPoints[0]); } // create the arrow head shape AffineTransform arrowTrans; if (multipleEdge) { edgeIndex = adjustEndingPointByMultipleEdge(e, start, end); if (lineForSingleEdge && edgeIndex < 0) { type = Constants.EDGE_TYPE_LINE; arrowTrans = getArrowTrans(start, end, m_curWidth); } else { getCurveControlPoints( edgeIndex, m_ctrlPoints, start.getX(), start.getY(), end.getX(), end.getY()); curveCtrlPtsReady = true; arrowTrans = getArrowTrans(m_ctrlPoints[0], end, m_curWidth); } } else { arrowTrans = getArrowTrans(start, end, m_curWidth); } m_curArrow = m_tmpArrow.set(arrowHead, arrowTrans); // update the endpoints for the edge shape // need to bias this by arrow head size adjustLineEndByArrowHead(e, end); arrowTrans.transform(end, end); } else { m_curArrow = null; if (edgeBounded && !e.isAggregating()) { adjustEndingPoint(m_tmpPoints[0], m_tmpPoints[1], source, target); } if (multipleEdge) { edgeIndex = adjustEndingPointByMultipleEdge(e, m_tmpPoints[0], m_tmpPoints[1]); if (lineForSingleEdge && edgeIndex < 0) { type = Constants.EDGE_TYPE_LINE; } else { getCurveControlPoints( edgeIndex, m_ctrlPoints, m_tmpPoints[0].getX(), m_tmpPoints[0].getY(), m_tmpPoints[1].getX(), m_tmpPoints[1].getY()); curveCtrlPtsReady = true; } } } // create the edge shape Shape shape = null; double sx = m_tmpPoints[0].getX(); double sy = m_tmpPoints[0].getY(); double ex = m_tmpPoints[1].getX(); double ey = m_tmpPoints[1].getY(); switch (type) { case Constants.EDGE_TYPE_LINE: m_line.setLine(sx, sy, ex, ey); shape = m_line; break; case Constants.EDGE_TYPE_CURVE: if (!curveCtrlPtsReady) { getCurveControlPoints(e, m_ctrlPoints, sx, sy, ex, ey); } m_quad.setCurve(sx, sy, m_ctrlPoints[0].getX(), m_ctrlPoints[0].getY(), ex, ey); shape = m_quad; break; default: throw new IllegalStateException("Unknown edge type"); } // return the edge shape return shape; }
protected VisualItem getTargetItem(EdgeItem e, boolean forward) { VisualItem target = forward ? e.getTargetItem() : e.getSourceItem(); return target; }
public Display getGraphDisplay( GraphLayoutType glType, final ExperimentPanel expPanel, String highlightName) { Display display = new Display(); int X = expPanel.getDetailWidth(); int Y = expPanel.getDetailHeight(); display.setSize(X, Y); // set display size // display.setHighQuality(true); // display.setPreferredSize(new Dimension(600,600)); display.addControlListener(new DragControl()); // drag items around display.addControlListener(new PanControl()); // pan with background left-drag display.addControlListener(new WheelZoomControl()); // zoom with vertical right-drag display.addControlListener( new ZoomToFitControl(Visualization.ALL_ITEMS, 50, 500, Control.MIDDLE_MOUSE_BUTTON)); display.addControlListener(new NeighborHighlightControl()); Visualization vis = new Visualization(); if (clusterGraph == null) { clusterGraph = this.toGraph(); } vis.add("graph", clusterGraph); LabelRenderer r = new LabelRenderer("name"); r.setHorizontalAlignment(Constants.CENTER); // r.setRoundedCorner(8, 8); // round the corners DefaultRendererFactory rf = new DefaultRendererFactory(r); rf.setDefaultEdgeRenderer(new EdgeRenderer(Constants.EDGE_TYPE_CURVE)); vis.setRendererFactory(rf); int[] palette = new int[] {ColorLib.rgb(255, 180, 180), ColorLib.rgb(190, 190, 255)}; DataColorAction fill = new DataColorAction( "graph.nodes", "type", Constants.NOMINAL, VisualItem.FILLCOLOR, palette); fill.add(VisualItem.FIXED, ColorLib.rgb(255, 100, 100)); fill.add(VisualItem.HIGHLIGHT, ColorLib.rgb(255, 200, 125)); int[] text_palette = new int[] {ColorLib.gray(0), ColorLib.gray(255)}; DataColorAction text = new DataColorAction( "graph.nodes", "indeterminate", Constants.NUMERICAL, VisualItem.TEXTCOLOR, text_palette); // ColorAction text = new ColorAction("graph.nodes", VisualItem.TEXTCOLOR, ColorLib.gray(0)); ColorAction edges = new ColorAction("graph.edges", VisualItem.STROKECOLOR, ColorLib.gray(200)); ActionList color = new ActionList(Activity.INFINITY); color.add(text); color.add(fill); color.add(edges); color.add(new RepaintAction()); if (highlightName != null) { String pred = "name='" + highlightName + "'"; Iterator iter = vis.items("graph.nodes", ExpressionParser.predicate(pred)); while (iter.hasNext()) { NodeItem ni = (NodeItem) iter.next(); highlightedItem = ni; ni.setFixed(true); Iterator iterEdge = ni.edges(); while (iterEdge.hasNext()) { EdgeItem eItem = (EdgeItem) iterEdge.next(); NodeItem nItem = eItem.getAdjacentItem(ni); if (eItem.isVisible()) { eItem.setHighlighted(true); nItem.setHighlighted(true); } } } } ActionList layout = new ActionList(); switch (glType) { case BALLOON_TREE: layout.add(new BalloonTreeLayout("graph")); break; case FORCE_DIRECTED: layout = new ActionList(Activity.INFINITY); layout.add(new ForceDirectedLayout("graph")); break; case NODE_LINK_TREE: layout.add(new NodeLinkTreeLayout("graph")); break; case RADIAL_TREE: layout.add(new RadialTreeLayout("graph")); break; } // layout.add(fill); layout.add(new RepaintAction()); vis.putAction("color", color); vis.putAction("layout", layout); display.setVisualization(vis); vis.run("color"); vis.run("layout"); // Rectangle2D bounds = vis.getBounds(Visualization.ALL_ITEMS); // GraphicsLib.expand(bounds, 50 + (int)(1/display.getScale())); // DisplayLib.fitViewToBounds(display,bounds,1); // vis.runAfter("layout",1000); Control shutoffHighlight = new HoverActionControl("color") { // public void itemEntered(VisualItem item, MouseEvent evt) { // } public void itemExited(VisualItem item, MouseEvent evt) { if (highlightedItem != null) { highlightedItem.setFixed(false); Iterator iterEdge = highlightedItem.edges(); while (iterEdge.hasNext()) { EdgeItem eItem = (EdgeItem) iterEdge.next(); NodeItem nItem = eItem.getAdjacentItem(highlightedItem); if (eItem.isVisible()) { eItem.setHighlighted(false); nItem.setHighlighted(false); } } highlightedItem = null; } } }; display.addControlListener(shutoffHighlight); Control selectItem = new FocusControl() { public void itemClicked(VisualItem item, MouseEvent evt) { if (item.isInGroup("graph.nodes")) { if (item.getString("type").equals("peptide")) { Peptide pep = minPeptides.get(item.getString("name")); expPanel.showPeptide(pep, true); } if (item.getString("type").equals("protein")) { Protein pro = minProteins.get(item.getString("name")); expPanel.showProtein(pro, true); } String pred = "name='" + item.getString("name") + "'"; Iterator iter = item.getVisualization().items("graph.nodes", ExpressionParser.predicate(pred)); while (iter.hasNext()) { NodeItem ni = (NodeItem) iter.next(); highlightedItem = ni; ni.setFixed(true); Iterator iterEdge = ni.edges(); while (iterEdge.hasNext()) { EdgeItem eItem = (EdgeItem) iterEdge.next(); NodeItem nItem = eItem.getAdjacentItem(ni); if (eItem.isVisible()) { eItem.setHighlighted(true); nItem.setHighlighted(true); } } } } } }; display.addControlListener(selectItem); final JPopupMenu menu = new JPopupMenu(); // Create and add a menu item // JMenuItem printItem = new JMenuItem("Print This"); // printItem.addActionListener(new java.awt.event.ActionListener() { // public void actionPerformed(java.awt.event.ActionEvent evt) { // PrintUtilities.printComponent(display); // } // }); // menu.add(printItem); // Set the component to show the popup menu display.addMouseListener( new MouseAdapter() { public void mousePressed(MouseEvent evt) { if (evt.isPopupTrigger()) { menu.show(evt.getComponent(), evt.getX(), evt.getY()); } } public void mouseReleased(MouseEvent evt) { if (evt.isPopupTrigger()) { menu.show(evt.getComponent(), evt.getX(), evt.getY()); } } }); display.pan(X / 2.0, Y / 2.0); return display; }