1

经过大量调查,我无法找到以下问题的方便答案:如何以编程方式使用 Jung 平移 VisualizationViewer?

我有一个带有图形顶点列表的 GUI,我希望双击列表中的一项(即节点描述)为单击的节点执行 VisualizationViewer 的“居中操作”。如何编码这样的行为?看起来很简单,但我没有找到方便的答案。

如果有人可以帮忙,谢谢!

詹姆斯

4

6 回答 6

4

以下是在 JUNG2 中右键单击一个节点然后选择居中到该节点后如何弹出菜单:

graphMouse.add(new MyPopupGraphMousePlugin());

/**
 * a GraphMousePlugin that offers popup
 * menu support
 */
protected class MyPopupGraphMousePlugin extends AbstractPopupGraphMousePlugin
implements MouseListener {

    public MyPopupGraphMousePlugin() {
        this(MouseEvent.BUTTON3_MASK);
    }
    public MyPopupGraphMousePlugin(int modifiers) {
        super(modifiers);
    }

    /**
     * If this event is over a node, pop up a menu to
     * allow the user to center view to the node
     *
     * @param e
     */
    protected void handlePopup(MouseEvent e) {
        final VisualizationViewer<Node,Link> vv =
            (VisualizationViewer<Node,Link>)e.getSource();
        final Point2D p = e.getPoint(); 

        GraphElementAccessor<Node,Link> pickSupport = vv.getPickSupport();
        if(pickSupport != null) {
            final Node station = pickSupport.getVertex(vv.getGraphLayout(), p.getX(), p.getY());
            if(station != null) {
                JPopupMenu popup = new JPopupMenu();

                String center = "Center to Node";

                popup.add(new AbstractAction("<html><center>" + center) {
                    public void actionPerformed(ActionEvent e) {

                        MutableTransformer view = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW);
                        MutableTransformer layout = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT);

                        Point2D ctr = vv.getCenter(); 
                        Point2D pnt = view.inverseTransform(ctr);

                        double scale = vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW).getScale();

                        double deltaX = (ctr.getX() - p.getX())*1/scale;
                        double deltaY = (ctr.getY() - p.getY())*1/scale;
                        Point2D delta = new Point2D.Double(deltaX, deltaY);

                        layout.translate(deltaX, deltaY);
                    }
                });

                popup.show(vv, e.getX(), e.getY());
            } else {

            }
        }
    }
}

编辑:终于!具有比例因子计算的正确节点到中心视图...

于 2011-04-21T15:11:55.787 回答
1
public void centerViewsOnVertex(SynsetVertex v) {
  //the following location have sense in the space of the layout
  Point2D v_location = layout.transform(v);
  Point2D vv1_center_location = vv1.getRenderContext()
                .getMultiLayerTransformer()
                .inverseTransform(Layer.LAYOUT, vv1.getCenter());

  double scale = vv1.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW).getScale();

  vv1.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).translate(
                        -(v_location.getX() - vv1_center_location.getX()) * 1
                                / scale,
                        -(v_location.getY() - vv1_center_location.getY()) * 1
                                / scale);

  refreshViews();
}
于 2011-04-26T13:24:54.133 回答
1

因为我只是在寻找这个问题的答案,而上面的工作非常糟糕;这是我在 AnimatedPickingGraphMousePlugin 中找到的一个代码片段,它将重新定位:

Layout<V,E> layout = vv.getGraphLayout();
Point2D q = layout.transform(vertex);
Point2D lvc = 
    vv.getRenderContext().getMultiLayerTransformer().inverseTransform(vv.getCenter());
final double dx = (lvc.getX() - q.getX());
final double dy = (lvc.getY() - q.getY());
vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).translate(dx, dy);
于 2012-10-04T14:49:13.183 回答
0

实际上,我通过下一个解决方案找到了:

//the following location have sense in the space of the layout
    Point2D v_location = layout.transform(v);
    Point2D vv1_center_location = vv1.getRenderContext()
            .getMultiLayerTransformer()
            .inverseTransform(Layer.LAYOUT, vv1.getCenter());

    vv1.getRenderContext()
            .getMultiLayerTransformer()
            .getTransformer(Layer.LAYOUT)
            .translate(-(v_location.getX() - vv1_center_location.getX()),
                    -(v_location.getY() - vv1_center_location.getY()));
于 2011-04-22T12:37:34.493 回答
0

在 AnimatedPickingGraphMousePlugin 中已经实现了以节点为中心的功能

http://sourceforge.net/p/jung/discussion/252062/thread/18b4b941

在拾取模式 ctrl+单击一个顶点以使其居中。

@SuppressWarnings("unchecked")
public void mouseReleased(MouseEvent e) {
    if (e.getModifiers() == modifiers) {
        final VisualizationViewer<V,E> vv = (VisualizationViewer<V,E>) e.getSource();
        if (vertex != null) {
            Layout<V,E> layout = vv.getGraphLayout();
            Point2D q = layout.transform(vertex);
            Point2D lvc = vv.getRenderContext().getMultiLayerTransformer().inverseTransform(vv.getCenter());
            final double dx = (lvc.getX() - q.getX()) / 10;
            final double dy = (lvc.getY() - q.getY()) / 10;

            Runnable animator = new Runnable() {

                public void run() {
                    for (int i = 0; i < 10; i++) {
                        vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.LAYOUT).translate(dx, dy);
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException ex) {
                        }
                    }
                }
            };
            Thread thread = new Thread(animator);
            thread.start();
        }
    }
}
于 2013-06-19T14:01:59.763 回答
0

我试图弄清楚如何以给定顶点为中心并遇到了这个问题,但不幸的是它并不是特别有用,我花了相当多的时间来弄清楚如何去做。因此,在这里分享我的经验,以防对其他人有所帮助。

我正在编写的应用程序有一个 VisualizationViewer,它加载在 GraphZoomScrollPane 中。我有一个已添加到 VisualizationViewer 的 GraphMouseListener,它允许用户右键单击滚动窗格的可视区域中的顶点,并且在弹出菜单中他们可以选择以顶点为中心。

该线程上投票最多的答案引用了来自 LAYOUT 层的 MutableTransformer 的用法,它使用该转换器的 translate 方法来执行居中操作。不幸的是,如果您使用缩放/滚动,那么您并不真正知道布局层相对于视图层的大小和位置,而无需进行大量额外的数学运算。

使用缩放/滚动窗格时,我建议在窗格表示的图形的可视区域中找到顶点的位置,然后调整视图窗格的位置。

这是我编写的代码片段:

void center(MouseEvent me, GraphZoomScrollPane gzsp) {
  VisualizationViewer<V,E> vv = 
    (VisualizationViewer<V,E>)me.getSource();
  MutableTransformer viewTransformer = 
    vv.getRenderContext().getMultiLayerTransformer().getTransformer(Layer.VIEW);
  double scaleFromViewTransformer = viewTransformer.getScale();
  Dimension paneSize = gzsp.getSize();
  Point2D positionOfVertexInPane = me.getPoint();
  double[] centerOfPane = new double[] {
    paneSize.getWidth()/2d, 
    paneSize.getHeight()/2d
  };
  double[] amountToMovePane = new double[] {
    (centerOfPane[0]-positionOfVertexInPane.getX())/scaleFromViewTransformer,
    (centerOfPane[1]-positionOfVertexInPane.getY())/scaleFromViewTransformer
  };
  viewTransformer.translate(amountToMovePane[0], amountToMovePane[1]);
}
于 2016-08-05T22:50:38.937 回答