Как программно панорамировать VisualizationViewer с помощью Jung (библиотеки Java)? - PullRequest
1 голос
/ 21 апреля 2011

После многих исследований я не могу найти удобный ответ на следующий вопрос: как программно панорамировать VisualizationViewer с помощью Jung?

У меня есть графический интерфейс со списком вершинмой график, и я хочу, чтобы двойной щелчок по одному элементу списка (то есть описание узла) выполнял «центрирующее действие» моего VisualizationViewer для выбранного узла.Как кодировать такое поведение?это кажется простым, но я не нашел удобного ответа.

Если кто-то может помочь, спасибо!

njames

Ответы [ 6 ]

4 голосов
/ 21 апреля 2011

Вот как вывести всплывающее меню после щелчка правой кнопкой мыши на узле в 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 {

            }
        }
    }
}

Отредактировано: Наконец-то! правильный вид узла-центр с вычислением масштабного коэффициента ...

1 голос
/ 04 октября 2012

Так как я просто искал ответ на этот вопрос, вышеперечисленное сработало ужасно; вот фрагмент кода, который я нашел в 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);
1 голос
/ 26 апреля 2011
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();
}
0 голосов
/ 06 августа 2016

Я пытался выяснить, как центрироваться на данной вершине, и натолкнулся на это, но, к сожалению, это было не особо полезно, и я потратил немало времени, пытаясь понять, как это сделать. Итак, делюсь своим опытом здесь на случай, если он будет полезен другим.

Приложение, которое я пишу, имеет VisualizationViewer, который загружается внутри GraphZoomScrollPane. У меня есть GraphMouseListener, который я добавил в VisualizationViewer, который позволяет пользователю щелкнуть правой кнопкой мыши по вершине в видимой области панели прокрутки, и во всплывающем меню они могут выбрать центр по вершине.

Ответ с наибольшим количеством голосов в этом потоке ссылается на использование MutableTransformer из уровня LAYOUT и использует метод translate этого преобразователя для выполнения центрирующего действия. К сожалению, если вы используете масштабирование / прокрутку, то вы на самом деле не знаете размер и расположение слоя макета по отношению к слою вида, не прибегая к куче дополнительной математики.

При использовании панели масштабирования / прокрутки я бы порекомендовал найти расположение вершины в видимой области графика, представленной панелью, а затем отрегулировать положение области просмотра.

Вот фрагмент кода, который я разработал:

* * 1010
0 голосов
/ 19 июня 2013

Функция центра по узлу уже реализована в AnimatedPickingGraphMousePlugin

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

В режиме выбора Ctrl + клик по вершине, чтобы центрировать ее.

0 голосов
/ 22 апреля 2011

Собственно, я нашел следующее решение:

//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()));
...