Reputation: 542
In GraphStream visualizations Graphs can be dense. The enableAutoLayout
method gives a global visualization of the Graph and so zooming is needed. How to zoom into a GraphStream View?
Graph go=...;
Viewer viewer = new Viewer(go, Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD);
viewer.enableAutoLayout();
View view = viewer.addDefaultView(false);
swingNode.setContent((JComponent) view);
Upvotes: 4
Views: 2621
Reputation: 1732
This is not supposed to be a new answer, but rather an improvement of @MichaG 's answer (https://stackoverflow.com/a/52929241/5036964). Thanks for the great work!
When implementing this I realized, that the zoom center is off, when the graph is rotated. Below is my updated version, that also works when the graph was rotated:
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
e.consume();
int i = e.getWheelRotation();
double factor = Math.pow(1.25, i);
Camera cam = viewPanel.getCamera();
double zoom = cam.getViewPercent() * factor;
Point2 pxCenter = cam.transformGuToPx(cam.getViewCenter().x, cam.getViewCenter().y, 0);
Point3 guClicked = cam.transformPxToGu(e.getX(), e.getY());
double newRatioPx2Gu = cam.getMetrics().ratioPx2Gu/factor;
/*
* patch begins here.
* the offset is calculated as before, but afterwards rotated according to
* the current rotation of the view.
*/
Point2 offset = new Point2();
offset.x = (pxCenter.x - e.getX()) / newRatioPx2Gu;
offset.y = (pxCenter.y - e.getY()) / newRatioPx2Gu;
Point2 rotatedOffset = rotateOffset(offset, -cam.getViewRotation());
double x = guClicked.x + rotatedOffset.x;
double y = guClicked.y - rotatedOffset.y;
cam.setViewCenter(x, y, 0);
cam.setViewPercent(zoom);
}
/**
* Rotates a given offset by the supplied angle in degrees.
*
* @param offset the offset that needs to be rotated
* @param degrees the degree in angles of the rotation
* @return rotated offset
*/
private Point2 rotateOffset(Point2 offset, double degrees) {
double sin = Math.sin(Math.toRadians(degrees));
double cos = Math.cos(Math.toRadians(degrees));
double rotOffsetX = offset.x * cos - offset.y * sin;
double rotOffsetY = offset.x * sin + offset.y * cos;
return new Point2(rotOffsetX, rotOffsetY);
}
Upvotes: 0
Reputation: 309
Here a simple code to show you how you can zoom a graph:
public class zoomGraph{
public zoomGraph(){
}
//the methode that will zoom the graph
public static void zoomGraphMouseWheelMoved(MouseWheelEvent mwe, ViewPanel view_panel){
if (Event.ALT_MASK != 0) {
if (mwe.getWheelRotation() > 0) {
double new_view_percent = view_panel.getCamera().getViewPercent() + 0.05;
view_panel.getCamera().setViewPercent(new_view_percent);
} else if (mwe.getWheelRotation() < 0) {
double current_view_percent = view_panel.getCamera().getViewPercent();
if(current_view_percent > 0.05){
view_panel.getCamera().setViewPercent(current_view_percent - 0.05);
}
}
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setLayout(new GridLayout());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setBounds(0, 0, 700, 500);
frame.setPreferredSize(new Dimension(700, 500));
//Components
JPanel panel = new JPanel();
panel.setLayout(new GridLayout());
frame.add(panel);
//create a simple graph
Graph graph = new SingleGraph("tuto_zoom", false, true);
graph.addNode("node_1");
graph.addNode("node_2");
graph.addEdge("edge_1_2", "node_1","node_2");
//show the graph in the panel
Viewer viewer = new Viewer(graph, Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD);
viewer.enableAutoLayout();
ViewPanel view_panel = viewer.addDefaultView(false);
Rectangle rec = panel.getBounds();
view_panel.setBounds(0, 0, rec.width, rec.height);
view_panel.setPreferredSize(new Dimension(rec.width, rec.height));
panel.add(view_panel);
//add a mouse wheel listener to the ViewPanel for zooming the graph
view_panel.addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent mwe) {
zoomGraph.zoomGraphMouseWheelMoved(mwe, view_panel);
}
});
frame.setVisible(true);
}
}
Upvotes: 2
Reputation: 487
I tried to find a way to zoom to the mouse cursor using the mouse wheel and stumbled across this thread, hoping to find an answer. I figured out how to zoom to the mouse eventually with GraphStream:
The zoom-factor for each mouse wheel rotation in my case is 1.25 (or 0.8 when zooming out). The code calculates the new center of the graph based on the original center of the graph, the clicked point in the graph, the zoom and eventually the ratio of Px to Gu which can be retrieved from the camera.
final Viewer viewer = new Viewer(graph, Viewer.ThreadingModel.GRAPH_IN_ANOTHER_THREAD);
viewer.enableAutoLayout();
final View view = viewer.addDefaultView(false);
view.getCamera().setViewPercent(1);
((Component) view).addMouseWheelListener(new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
e.consume();
int i = e.getWheelRotation();
double factor = Math.pow(1.25, i);
Camera cam = view.getCamera();
double zoom = cam.getViewPercent() * factor;
Point2 pxCenter = cam.transformGuToPx(cam.getViewCenter().x, cam.getViewCenter().y, 0);
Point3 guClicked = cam.transformPxToGu(e.getX(), e.getY());
double newRatioPx2Gu = cam.getMetrics().ratioPx2Gu/factor;
double x = guClicked.x + (pxCenter.x - e.getX())/newRatioPx2Gu;
double y = guClicked.y - (pxCenter.y - e.getY())/newRatioPx2Gu;
cam.setViewCenter(x, y, 0);
cam.setViewPercent(zoom);
}
});
Upvotes: 6
Reputation: 566
From the official documentation at http://graphstream-project.org/doc/Tutorials/Graph-Visualisation:
You can also zoom in or out using:
view.getCamera().setViewPercent(0.5);
This will zoom of 200% on the view center.
Upvotes: 2