wikipedia apiを使ってみたい。- JGraphで表示 2008/05/04



なんとなく可視化に挑戦。
中心におかれた語の関連後を周りに配置しています。

メインページ - Wikipedia-Lab
wikipedia-labのapiを使っています。

前、記事を書いたものをベースにしています。
プログラマメモ2: wikipedia apiを使ってみたい。- Java + axis2

表示するために使ったライブラリは、
Java Graph Visualization and Layout

package util;

import static util.WikipedialabUtils.getThesaurusDS4NetworkView;
import static util.WikipedialabUtils.getTopCandidateIDFromKeyword;

import java.awt.Color;
import java.awt.Point;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;

import org.jgraph.JGraph;
import org.jgraph.graph.DefaultCellViewFactory;
import org.jgraph.graph.DefaultEdge;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.DefaultGraphModel;
import org.jgraph.graph.GraphConstants;
import org.jgraph.graph.GraphModel;
import org.xml.sax.SAXException;

import util.WikipedialabUtils.MNode;

public class TestT {

static JGraph graph() {
GraphModel model = new DefaultGraphModel();
JGraph graph = new JGraph(model);

graph.getGraphLayoutCache().setFactory(new DefaultCellViewFactory());

// Control-drag should clone selection
graph.setCloneable(true);

// Enable edit without final RETURN keystroke
graph.setInvokesStopCellEditing(true);

// When over a cell, jump to its default port (we only have one, anyway)
graph.setJumpToDefaultPort(true);
return graph;
}

static DefaultGraphCell createDefaultGraphCell(String name, int px, int py, int w, int h){
DefaultGraphCell cell = new DefaultGraphCell(name);

GraphConstants.setBounds(cell.getAttributes(),
new Rectangle2D.Double(px,py,w,h));
GraphConstants.setGradientColor(cell.getAttributes(), Color.orange);
GraphConstants.setOpaque(cell.getAttributes(), true);

cell.addPort();
return cell;
}

static Point[] points(int n, final int cx, final int cy, final int R) {
final double d = 360.;
final double d2 = d / n;

Point[] points = new Point[n];
for (int i = 0; i < n; i++) {
int x = (int) (cx + (R * Math.sin(Math.toRadians((d2 * i)))));
int y = (int) (cy + (R * Math.cos(Math.toRadians((d2 * i)))));
points[i] = new Point(x, y);
}
return points;
}

static void c(JGraph graph, MNode parent) {

int n = parent.child.size();

int cx = 200;
int cy = 200;

int R = 200;

List<DefaultGraphCell> list = new ArrayList<DefaultGraphCell>();
Collection<MNode> collection = parent.child.values();

DefaultGraphCell cellParent = createDefaultGraphCell(parent.name, cx, cy, 80, 20);
list.add(cellParent);
int i = 0;
Point[] points = points(n, cx, cy, R);
for (MNode node : collection) {
Point point = points[i++];
DefaultGraphCell cell = createDefaultGraphCell(node.name, point.x, point.y, 80, 20);


list.add(cell);

DefaultEdge edge = new DefaultEdge();
edge.setSource(cellParent.getChildAt(0));
edge.setTarget(cell.getChildAt(0));

int arrow = GraphConstants.ARROW_NONE;
GraphConstants.setLineEnd(edge.getAttributes(), arrow);
GraphConstants.setEndFill(edge.getAttributes(), true);

list.add(edge);
}


graph.getGraphLayoutCache().insert(list.toArray());

}

public static void main(String[] args) throws UnsupportedEncodingException, XPathExpressionException, SAXException, IOException, ParserConfigurationException {
JGraph graph = graph();

String skey = "apple";

int i = getTopCandidateIDFromKeyword(WikipedialabUtils.JAPANESE, skey);
String s = getThesaurusDS4NetworkView(WikipedialabUtils.JAPANESE, i);

MNode node = WikipedialabUtils.createDS4NetworkView(skey, i, s);

c(graph, node);

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(graph));
frame.pack();
frame.setVisible(true);
}
}


wikipedia apiからデータを取得する部分
package util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.axis2.databinding.types.UnsignedInt;
import org.tempuri.ServiceStub;
import org.tempuri.ServiceStub.GetThesaurusDS;
import org.tempuri.ServiceStub.GetThesaurusDS300;
import org.tempuri.ServiceStub.GetThesaurusDS300Response;
import org.tempuri.ServiceStub.GetThesaurusDS4NetworkView;
import org.tempuri.ServiceStub.GetThesaurusDS4NetworkViewResponse;
import org.tempuri.ServiceStub.GetThesaurusDSResponse;
import org.tempuri.ServiceStub.GetTopCandidateIDFromKeyword;
import org.tempuri.ServiceStub.GetTopCandidateIDFromKeywordResponse;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public abstract class WikipedialabUtils {

static public final String JAPANESE = "Japanese";

static int getTopCandidateIDFromKeyword(String lang, String skeyword)
throws RemoteException {
ServiceStub serviceStub = new ServiceStub();

GetTopCandidateIDFromKeyword keyword = new GetTopCandidateIDFromKeyword();
keyword.setKeyword(skeyword);
keyword.setLanguage(lang);

GetTopCandidateIDFromKeywordResponse response = serviceStub
.GetTopCandidateIDFromKeyword(keyword);

return response.getGetTopCandidateIDFromKeywordResult().intValue();
}

static String getThesaurusDS(String lang, int i) throws RemoteException {

ServiceStub serviceStub = new ServiceStub();

GetThesaurusDS getThesaurusDS = new GetThesaurusDS();
getThesaurusDS.setLanguage(lang);
getThesaurusDS.setIFrom(new UnsignedInt(i));

GetThesaurusDSResponse response = serviceStub
.GetThesaurusDS(getThesaurusDS);

return "" + response.getGetThesaurusDSResult().getExtraElement();
}

static String getThesaurusDS300(String lang, int i) throws RemoteException {

ServiceStub serviceStub = new ServiceStub();

GetThesaurusDS300 getThesaurusDS300 = new GetThesaurusDS300();
getThesaurusDS300.setLanguage(lang);
getThesaurusDS300.setIFrom(new UnsignedInt(i));

GetThesaurusDS300Response response = serviceStub
.GetThesaurusDS300(getThesaurusDS300);

return "" + response.getGetThesaurusDS300Result().getExtraElement();
}

static String getThesaurusDS4NetworkView(String lang, int i)
throws RemoteException {

ServiceStub serviceStub = new ServiceStub();

GetThesaurusDS4NetworkView getThesaurusDS4NetworkView = new GetThesaurusDS4NetworkView();
getThesaurusDS4NetworkView.setLanguage(lang);
getThesaurusDS4NetworkView.setIFrom(new UnsignedInt(i));

GetThesaurusDS4NetworkViewResponse response = serviceStub
.GetThesaurusDS4NetworkView(getThesaurusDS4NetworkView);

return ""
+ response.getGetThesaurusDS4NetworkViewResult()
.getExtraElement();
}

static MNode createDS4NetworkView(String name, int n, String sxml)
throws UnsupportedEncodingException, SAXException, IOException,
ParserConfigurationException, XPathExpressionException {
Document document = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse(
new ByteArrayInputStream(sxml.getBytes("utf-8")));
List<Table> list = new ArrayList<Table>();
XPath path = XPathFactory.newInstance().newXPath();

NodeList nodeList = (NodeList) path.evaluate("/diffgram/NewDataSet",
document, XPathConstants.NODESET);

MNode parent = new MNode(name, n);

for (int i = 0; i < nodeList.getLength(); i++) {

Node node = nodeList.item(i);
NodeList nodeList2 = node.getChildNodes();

NodeList o = (NodeList)path.evaluate("Center", nodeList2, XPathConstants.NODESET);
for (int j = 0; j < o.getLength(); j++) {
Node node2 = o.item(j);

MNode mn = new MNode();
mn.n = new Integer(path.evaluate("l_to", node2));
mn.name = path.evaluate("name", node2);
mn.weight = new Double(path.evaluate("l_weight", node2));
mn.parent = parent;
parent.add(mn);
}

NodeList o2 = (NodeList)path.evaluate("*[local-name()!='Center']", nodeList2, XPathConstants.NODESET);
for (int j = 0; j < o2.getLength(); j++) {
Node node2 = o2.item(j);
MNode mn = new MNode();
int from = new Integer(path.evaluate("l_from", node2));
mn.n = new Integer(path.evaluate("l_to", node2));
mn.name = path.evaluate("name", node2);
mn.weight = new Double(path.evaluate("l_weight", node2));

MNode p = parent.child(from);
if(p != null){
mn.parent = p;
p.add(mn);
} else {
System.err.println("error parent[" + from + "] not exist.");
}
}

}

return parent;
}

static class Table {

int l_from;
int l_to;
double l_weight;
String name;

public String toString() {
return "l_from:[" + l_from + "] l_to:[" + l_to + "] l_weight:["
+ l_weight + "] name:[" + name + "]";
}
}

static class MNode {
String name;
int n;
double weight;
MNode parent;
Map<Integer, MNode> child = new HashMap<Integer, MNode>();

public MNode(){

}
public MNode(String name, int n){
this.name = name;
this.n = n;
}
public void add(MNode node){
child.put(node.n, node);
}
public MNode child(int n){
return child.get(n);
}

public boolean equals(Object o) {
if (o == null)
return false;
if (!(o instanceof MNode))
return false;
MNode node = (MNode) o;
if (node.n == node.n)
return true;
return false;
}

public String toString(){
return "name:[" + name + "] n:[" + n + "] parent:["
+ (parent != null ? parent.n : -1) + "]";
}

public String toString(int c){
StringBuilder sb = new StringBuilder();
for(int i=0;i<(c*2);i++){
sb.append(" ");
}
sb.append(toString()).append("\n");

Collection<MNode> collection = child.values();
for (MNode node : collection) {
sb.append(node.toString(c + 1));
}
return new String(sb);
}
}

}

: