private void adjustEndingPoint(Point2D start, Point2D end, VisualItem source, VisualItem target) { Rectangle2D sourceBounds = source.getBounds(); Rectangle2D targetBounds = target.getBounds(); if (source.getShape() == Constants.SHAPE_ELLIPSE) { m_edgeTrans.setToTranslation(start.getX(), start.getY()); m_edgeTrans.rotate( -HALF_PI + Math.atan2(start.getY() - end.getY(), start.getX() - end.getX())); start.setLocation(0, -sourceBounds.getWidth() / 2.0D); m_edgeTrans.transform(start, start); } else if (GraphicsLib.intersectLineRectangle(start, end, sourceBounds, m_isctPoints) > 0) { start.setLocation(m_isctPoints[0]); } if (target.getShape() == Constants.SHAPE_ELLIPSE) { m_edgeTrans.setToTranslation(end.getX(), end.getY()); m_edgeTrans.rotate( -HALF_PI + Math.atan2(end.getY() - start.getY(), end.getX() - start.getX())); end.setLocation(0, -targetBounds.getWidth() / 2.0D); m_edgeTrans.transform(end, end); } else if (GraphicsLib.intersectLineRectangle(start, end, targetBounds, m_isctPoints) > 0) { end.setLocation(m_isctPoints[0]); } }
private static void addPoint(double[] pts, int idx, VisualItem item, int growth) { Rectangle2D b = item.getBounds(); double minX = (b.getMinX()) - growth, minY = (b.getMinY()) - growth; double maxX = (b.getMaxX()) + growth, maxY = (b.getMaxY()) + growth; pts[idx] = minX; pts[idx + 1] = minY; pts[idx + 2] = minX; pts[idx + 3] = maxY; pts[idx + 4] = maxX; pts[idx + 5] = minY; pts[idx + 6] = maxX; pts[idx + 7] = maxY; }
public void run(double frac) { // first pass double w = 0, h = 0; Iterator iter = m_vis.items(); while (iter.hasNext()) { VisualItem item = (VisualItem) iter.next(); item.setSize(1.0); h += item.getBounds().getHeight(); } double scale = h > m_maxHeight ? m_maxHeight / h : 1.0; Display d = m_vis.getDisplay(0); Insets ins = d.getInsets(); // second pass h = ins.top; double ih, y = 0, x = ins.left; iter = m_vis.items(); while (iter.hasNext()) { VisualItem item = (VisualItem) iter.next(); item.setSize(scale); item.setEndSize(scale); Rectangle2D b = item.getBounds(); w = Math.max(w, b.getWidth()); ih = b.getHeight(); y = h + (ih / 2); setX(item, null, x); setY(item, null, y); h += ih; } // set the display size to fit text setSize( d, (int) Math.round(2 * m_scale * w + ins.left + ins.right), (int) Math.round(h + ins.bottom)); }
/** @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; }