我正在尝试使用Gephi Toolkit创建图表Applet并将其集成到我们的JavaEE网站中。但问题是Gephi Toolkit(预览API)几乎没有支持交互功能。
根据Gephi论坛上的this topic,应该实现鼠标监听器来处理鼠标事件,例如点击节点。但是,我没弄清楚......有人可以帮我吗?
代码: 我创建了一个显示随机图形的类(没有问题),然后我添加了一个实现 PreviewMouseListener 的新类,只需在点击一个节点时打印一个msg。
/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
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) {}
}
非常感谢!
PS:我已经尝试回复该主题,但我的帐户尚未激活,即使我认为我在很多天前注册了...
答案 0 :(得分:1)
我和gephi玩了几天,我很确定没有办法点击确切的节点。它的API似乎并没有考虑到交互性。但是我发现这对2D图形来说效果相当不错。
主类:
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();
}
}
鼠标侦听器替代:
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) {
}
}
渲染器:
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;
}
}
如果有人有更好的,更不容易出错的方式,我想知道。
答案 1 :(得分:0)
实际上,您需要一个渲染才能使用PreviewMouseListener。 我认为这个话题对你有很大的帮助。顶部来自Gephi论坛。 不要忘记将MouseReseponsiveRenderer实现到渲染器。 在渲染方法中绘制绘画。