![](/img/trans.png)
[英]How to load my data into a GraphML file for easy use in Prefuse?
[英]GraphML Node Coloring Prefuse
我有一个 prefuse 应用程序,它加载节点具有“Color”字符串属性的 GraphML 文件。 IE。
<node id="1">
<data key="Color">Green</data>
<node>
我想允许指定一系列预定义的 colors,我不想强制创建 GraphML 的程序使用所有 colors。
我认为这将是一项简单的任务(也许它是?),但预示似乎无时无刻不在与我作对。 我提出了两个部分解决方案,但它们都有各自的问题。 我的第一种方法是手动添加一个与“颜色”字符串相关的新属性 Integer,如下所示:
// Add new property to Graph g
g.addColumn("ColorNumber", int.class);
// Add property to each node
Iterator<Node> it = g.nodes();
while(it.hasNext()) {
Node n = it.next();
String type = n.getString("Color");
// Compare to an array of accepted types
for(int i=0; i < colorMap.length; i++) {
if(type.equalsIgnoreCase(colorMap[i])) {
n.setInt("ColorNumber", i);
break;
}
}
}
然后,您可以使用 prefuse 的默认颜色管理器将这些整数链接到数组索引。
draw.add(new DataColorAction("graph.nodes", "ColorNumber", Constants.NUMERICAL, VisualItem.FILLCOLOR, fillArray));
这种方法的最大问题(最重要的是它不够优雅)是当用户指定的唯一 colors 少于三个时它会失败。 如果指定了两个 colors,则 prefuse 使用颜色数组的第一个和最后一个元素。 如果一个,第一个。 嗯。
我的另一个解决方案是手动设置每个节点的颜色。
// Iterate over VisualItems in Visualization vis
Iterator<VisualItem> v_it = vis.items("graph.nodes");
while(v_it.hasNext()) {
VisualItem item = v_it.next();
String type = item.getString("Color");
for(int i=0; i < typeMap.length; i++) {
if(type.equalsIgnoreCase(typeMap[i])) {
item.setFillColor(fill[i]);
item.setEndFillColor(fill[i]);
break;
}
}
}
vis.repaint();
这适用于任意数量的 colors,但会随机出现混乱。 我认为 prefuse 在它们自己的线程上处理这些方法,由于某种原因,它运行缓慢。 对于 smaller.networks,我可以设置一个固定的等待时间(我还没有找到可以使用的 Thread.join() 方法)。 但是,这对于 large.networks 来说非常失败(阅读:让我的电脑崩溃)。
所以你有它。 为本应是微不足道的任务付出不必要的大量时间。 有人设法做到这一点吗? 有简单的方法吗? 请告诉我我想多了。
我非常了解这种关于 prefuse 的经历:-/
第一种方法是正确的方法,但指定了错误的数据类型。 颜色是NOMINAL
变量。
DataColorAction color = new DataColorAction("graph.nodes", "Color",
Constants.NOMINAL, VisualItem.FILLCOLOR, fillArray);
ColorNumber
字段不是必需的。
您对第二种方法的结论是正确的。 prefuse 在一个单独的线程中运行它的ActionList
。 因此,不应手动设置视觉属性。
如果需要更细粒度的代码,您可以扩展DataColorAction
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.