1

I'm trying to use Gephi Toolkit to create a graph Applet and intergrate it into our JavaEE web site. But the problem is Gephi Toolkit (the Preview API) has nearly no interactive features supported.

According to this topic on Gephi forum, one should implement a mouse listener to handle mouse event such as clicking on a node. However, I didn't figure it out... Can anyone help me on this?

Code: I create a class to show a random graph (no problem for this), and then I add a new class who implements PreviewMouseListener and just print a msg when a node is clicked.

 /* Copyright 2008-2010 Gephi Authors : Mathieu Bastian <[email protected]> Website : http://www.gephi.org This file is part of Gephi. Gephi is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Gephi is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with Gephi. If not, see <http://www.gnu.org/licenses/>. */ import java.awt.BorderLayout; import java.awt.Color; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.File; import javax.swing.JFrame; import org.gephi.graph.api.GraphController; import org.gephi.graph.api.GraphModel; import org.gephi.graph.api.NodeIterator; import org.gephi.io.generator.plugin.RandomGraph; import org.gephi.io.importer.api.Container; import org.gephi.io.importer.api.ContainerFactory; import org.gephi.io.importer.api.ImportController; import org.gephi.io.processor.plugin.DefaultProcessor; import org.gephi.layout.plugin.random.Random; import org.gephi.layout.plugin.random.RandomLayout; import org.gephi.preview.api.PreviewController; import org.gephi.preview.api.PreviewModel; import org.gephi.preview.api.PreviewProperty; import org.gephi.preview.api.ProcessingTarget; import org.gephi.preview.api.RenderTarget; import org.gephi.preview.types.DependantOriginalColor; import org.gephi.project.api.ProjectController; import org.gephi.project.api.Workspace; import org.openide.util.Lookup; import processing.core.PApplet; /** * * @author Mathieu Bastian */ public class PreviewJFrame { public void script() { //Init a project - and therefore a workspace ProjectController pc = Lookup.getDefault().lookup(ProjectController.class); pc.newProject(); Workspace workspace = pc.getCurrentWorkspace(); //Generate a random graph Container container = Lookup.getDefault().lookup(ContainerFactory.class).newContainer(); RandomGraph randomGraph = new RandomGraph(); randomGraph.setNumberOfNodes(50); randomGraph.setWiringProbability(0.005); randomGraph.generate(container.getLoader()); //Append imported data to GraphAPI ImportController importController = Lookup.getDefault().lookup(ImportController.class); importController.process(container, new DefaultProcessor(), workspace); GraphModel graphModel = Lookup.getDefault().lookup(GraphController.class).getModel(); //Preview configuration PreviewController previewController = Lookup.getDefault().lookup(PreviewController.class); PreviewModel previewModel = previewController.getModel(); previewModel.getProperties().putValue(PreviewProperty.SHOW_NODE_LABELS, Boolean.TRUE); previewModel.getProperties().putValue(PreviewProperty.NODE_LABEL_COLOR, new DependantOriginalColor(Color.WHITE)); previewModel.getProperties().putValue(PreviewProperty.EDGE_CURVED, Boolean.TRUE); previewModel.getProperties().putValue(PreviewProperty.EDGE_OPACITY, 50); previewModel.getProperties().putValue(PreviewProperty.EDGE_RADIUS, 10f); previewModel.getProperties().putValue(PreviewProperty.BACKGROUND_COLOR, Color.BLACK); previewController.refreshPreview(); //New Processing target, get the PApplet ProcessingTarget target = (ProcessingTarget) previewController. getRenderTarget(RenderTarget.PROCESSING_TARGET); PApplet applet = target.getApplet(); applet.init(); //Refresh the preview and reset the zoom previewController.render(target); RandomLayout layout = new RandomLayout(new Random(),1500); layout.setGraphModel(graphModel); layout.initAlgo(); layout.goAlgo(); layout.endAlgo(); //Add the applet to a JFrame and display-------------------------------------- JFrame frame = new JFrame("Test Preview"); frame.setLayout(new BorderLayout()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(applet, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); target.refresh(); target.resetZoom(); } public static void main(String[] args) { PreviewJFrame previewJFrame = new PreviewJFrame(); previewJFrame.script(); } } 

MouseListener:

 import org.gephi.preview.api.PreviewMouseEvent; import org.gephi.preview.api.PreviewProperties; import org.gephi.preview.spi.MouseResponsiveRenderer; import org.gephi.preview.spi.PreviewMouseListener; import org.gephi.project.api.Workspace; import org.openide.util.lookup.ServiceProvider; @ServiceProvider(service = PreviewMouseListener.class) public class AtosPreviewMouseListener implements PreviewMouseListener{ @Override public void mouseClicked(PreviewMouseEvent event, PreviewProperties properties, Workspace workspace) { System.out.println("I'm clicked!!"); } @Override public void mousePressed(PreviewMouseEvent event, PreviewProperties properties, Workspace workspace) {} @Override public void mouseDragged(PreviewMouseEvent event, PreviewProperties properties, Workspace workspace) {} @Override public void mouseReleased(PreviewMouseEvent event, PreviewProperties properties, Workspace workspace) {} } 

Thanks a lot!

PS: I've tried to reply that topic, but my account is not activated yet even thought I registered many days ago...

1
  • PreviewJFrame.java - launching this official demo will display a window with clickable nodes, while printing them to stdout as well. Commented Apr 7 at 6:54

2 Answers 2

2

I played with gephi for a few days and I'm pretty sure there's no way to get the exact node clicked. It really doesn't seem that their API was built with interactivity in mind. However I've found that this works relatively well for a 2D graph.

Main Class:

import java.awt.BorderLayout; import java.awt.Color; import javax.swing.JFrame; import org.gephi.graph.api.*; import org.gephi.io.processor.plugin.DefaultProcessor; import org.gephi.preview.api.PreviewController; import org.gephi.preview.api.PreviewModel; import org.gephi.preview.api.PreviewProperty; import org.gephi.preview.api.ProcessingTarget; import org.gephi.preview.api.RenderTarget; import org.gephi.preview.types.DependantOriginalColor; import org.gephi.project.api.ProjectController; import org.gephi.project.api.Workspace; import org.openide.util.Lookup; import processing.core.PApplet; /** * This demo shows basic features from GraphAPI, how to create and query a graph * programmatically. * * @author Mathieu Bastian */ public class TestGraph { public void script() { //Init a project - and therefore a workspace ProjectController pc = Lookup.getDefault().lookup(ProjectController.class); pc.newProject(); Workspace workspace = pc.getCurrentWorkspace(); //Get a graph model - it exists because we have a workspace GraphModel graphModel = Lookup.getDefault().lookup(GraphController.class).getModel(); //Create three nodes Node n0 = graphModel.factory().newNode("n0"); n0.getNodeData().setLabel("Node 0"); Node n1 = graphModel.factory().newNode("n1"); n1.getNodeData().setLabel("Node 1"); Node n2 = graphModel.factory().newNode("n2"); n2.getNodeData().setLabel("Node 2"); //Create three edges Edge e1 = graphModel.factory().newEdge(n1, n2, 1f, true); Edge e2 = graphModel.factory().newEdge(n0, n2, 2f, true); Edge e3 = graphModel.factory().newEdge(n2, n0, 2f, true); //This is e2's mutual edge //Append as a Directed Graph DirectedGraph directedGraph = graphModel.getDirectedGraph(); directedGraph.addNode(n0); directedGraph.addNode(n1); directedGraph.addNode(n2); directedGraph.addEdge(e1); directedGraph.addEdge(e2); directedGraph.addEdge(e3); //Count nodes and edges System.out.println("Nodes: "+directedGraph.getNodeCount()+" Edges: "+directedGraph.getEdgeCount()); //Get a UndirectedGraph now and count edges UndirectedGraph undirectedGraph = graphModel.getUndirectedGraph(); GraphView view = undirectedGraph.getView(); System.out.println("Edges: "+undirectedGraph.getEdgeCount()); //The mutual edge is automatically merged //Iterate over nodes for(Node n : directedGraph.getNodes()) { Node[] neighbors = directedGraph.getNeighbors(n).toArray(); System.out.println(n.getNodeData().getLabel()+" has "+neighbors.length+" neighbors"); } //Iterate over edges for(Edge e : directedGraph.getEdges()) { System.out.println(e.getSource().getNodeData().getId()+" -> "+e.getTarget().getNodeData().getId()); } //Find node by id Node node2 = directedGraph.getNode("n2"); //Get degree System.out.println("Node2 degree: "+directedGraph.getDegree(node2)); //Preview configuration PreviewController previewController = Lookup.getDefault().lookup(PreviewController.class); PreviewModel previewModel = previewController.getModel(); previewModel.getProperties().putValue(PreviewProperty.SHOW_NODE_LABELS, Boolean.FALSE); previewModel.getProperties().putValue(PreviewProperty.NODE_LABEL_COLOR, new DependantOriginalColor(Color.WHITE)); previewModel.getProperties().putValue(PreviewProperty.EDGE_CURVED, Boolean.FALSE); previewModel.getProperties().putValue(PreviewProperty.EDGE_OPACITY, 50); previewModel.getProperties().putValue(PreviewProperty.EDGE_RADIUS, 10f); previewModel.getProperties().putValue(PreviewProperty.BACKGROUND_COLOR, Color.BLACK); previewController.refreshPreview(); //New Processing target, get the PApplet ProcessingTarget target = (ProcessingTarget) previewController.getRenderTarget(RenderTarget.PROCESSING_TARGET); PApplet applet = target.getApplet(); applet.init(); //Refresh the preview and reset the zoom previewController.render(target); target.refresh(); target.resetZoom(); //Add the applet to a JFrame and display JFrame frame = new JFrame("Test Preview"); frame.setLayout(new BorderLayout()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(applet, BorderLayout.CENTER); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { TestGraph previewJFrame = new TestGraph(); previewJFrame.script(); } } 

Mouse Listener substitute:

import org.gephi.graph.api.Graph; import org.gephi.graph.api.GraphModel; import org.gephi.graph.api.Node; import org.gephi.graph.api.NodeData; import org.gephi.graph.api.NodeIterable; import org.gephi.graph.api.NodeIterator; import org.gephi.preview.api.PreviewModel; import org.gephi.preview.api.PreviewMouseEvent; import org.gephi.preview.api.PreviewProperties; import org.gephi.preview.spi.PreviewMouseListener; import org.gephi.project.api.Workspace; import org.openide.util.Lookup; import org.openide.util.lookup.ServiceProvider; /** * * @author ksexton */ @ServiceProvider(service = PreviewMouseListener.class) public class MyMouseListener implements PreviewMouseListener { public void mouseClicked(PreviewMouseEvent event, PreviewProperties properties, Workspace workspace) { System.out.println("(" + event.x + "," + event.y + ")"); Lookup lookup = workspace.getLookup(); GraphModel lookup1 = lookup.lookup(GraphModel.class); Graph graph = lookup1.getGraph(); NodeIterable nodes = graph.getNodes(); NodeIterator iterator = nodes.iterator(); Node selectedNode = null; while (iterator.hasNext()) { Node next = iterator.next(); NodeData nodeData = next.getNodeData(); float x = nodeData.x(); float y = -nodeData.y(); // event y is always wrong. float z = nodeData.z(); float size = nodeData.getSize(); final int minX = Math.round(x - size); final int maxX = Math.round(x + size); final int minY = Math.round(y - size); final int maxY = Math.round(y + size); System.out.println("(" + minX + "," + minY+")" + ", (" + maxX + "," + maxY+")"); if (minX <= event.x && event.x <= maxX && minY <= event.y && event.y <= maxY) { selectedNode = next; } } if (selectedNode != null) { System.out.println("Found a Node!: (" + selectedNode.getNodeData().x() + "," + selectedNode.getNodeData().y() + ")"); } } public void mousePressed(PreviewMouseEvent event, PreviewProperties properties, Workspace workspace) { } public void mouseDragged(PreviewMouseEvent event, PreviewProperties properties, Workspace workspace) { } public void mouseReleased(PreviewMouseEvent event, PreviewProperties properties, Workspace workspace) { } } 

Renderer:

import org.gephi.preview.plugin.renderers.NodeRenderer; import org.gephi.preview.spi.MouseResponsiveRenderer; import org.gephi.preview.spi.PreviewMouseListener; import org.gephi.preview.spi.Renderer; import org.openide.util.lookup.ServiceProvider; /** * * @author ksexton */ @ServiceProvider(service = Renderer.class) public class NodeRenderer2 extends NodeRenderer implements MouseResponsiveRenderer { public boolean needsPreviewMouseListener(PreviewMouseListener previewMouseListener) { return true; } } 

If anyone has a better, less error prone way I'd like to know.

Sign up to request clarification or add additional context in comments.

1 Comment

They refer in this tutorial to some node click events. gephi.org/tutorials/gephi-tutorial-visualization.pdf
0

In fact, you need a render to use the PreviewMouseListener. I think this topic will help you a lot. And the top comes from the Gephi Forum. Do not forget to implement the MouseReseponsiveRenderer to your Renderer. Draw your painting in the render method.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.