问题
I am using the prefuse visualization toolkit, The GraphView Demo in the toolkit is amazing providing a variety of controls to visualize the data.
I am able to generate GraphML for my dataset and visualize it using GraphView, One additional thing that i would love to have is to label the edges with weights or color coding to demonstrate the strength between two nodes.
Any input about the same are greatly appreciated..Thanks..
回答1:
Disclaimer: I haven't worked with the API just checked the documentation:) It seems that the API has an EdgeRenderer interface that you should implement to achieve the desired behaviour.
Ref: http://prefuse.org/doc/manual/introduction/example/, http://prefuse.org/doc/api/prefuse/render/DefaultRendererFactory.html
Update: First a correction: in fact EdgeRenderer is not an iterface but a class. I've made a simple demo to illustrate how to implement custom edge rendering.
Feature
Add label to edges containing the initials of the node labels
Method
I made a quick and dirty solution, that is copied LabelRenderer and modified in order to handle edges.
Code
I named the class as MyEdgeRenderer
:
public class MyEdgeRenderer extends AbstractShapeRenderer {
use the original EdgeRenderer
to draw edge lines (see render()
below for the renderer in action):
protected EdgeRenderer m_edgeRenderer = new EdgeRenderer();
modify getText()
to get the initials from nodes:
protected String getText(VisualItem item) {
EdgeItem edge = (EdgeItem)item;
VisualItem item1 = edge.getSourceItem();
VisualItem item2 = edge.getTargetItem();
String t1 = null, t2 = null;
if ( item1.canGetString(m_labelName) ) {
t1 = item1.getString(m_labelName).substring(0,1);
};
if ( item2.canGetString(m_labelName) ) {
t2 = item2.getString(m_labelName).substring(0,1);
};
if (t1 != null && t2 != null)
return t1 + "-" + t2;
else
return null;
}
modified getAlignedPoint()
to position the label half way on the edge:
protected void getAlignedPoint(Point2D p, VisualItem item,
double w, double h, int xAlign, int yAlign)
{
double x=0, y=0;
EdgeItem edge = (EdgeItem)item;
VisualItem item1 = edge.getSourceItem();
VisualItem item2 = edge.getTargetItem();
// label is positioned to the center of the edge
x = (item1.getX()+item2.getX())/2;
y = (item1.getY()+item2.getY())/2;
...
modify render()
to (I) first draw the line and (II) use black color:
public void render(Graphics2D g, VisualItem item) {
m_edgeRenderer.render(g, item);
...
// render text
int textColor = ColorLib.color(Color.BLACK); // item.getTextColor()
if ( text != null && ColorLib.alpha(textColor) > 0 ) {
...
For testing I modified the sample found on the Prefuse website (http://prefuse.org/doc/manual/introduction/example/Example.java):
// -- 3. the renderers and renderer factory ---------------------------
// draw the "name" label for NodeItems
LabelRenderer ir = new LabelRenderer("name");
ir.setRoundedCorner(8, 8); // round the corners
// draw the "name" initials for EdgeItems
MyEdgeRenderer er = new MyEdgeRenderer("name");
er.setRoundedCorner(8, 8); // round the corners
// create a new default renderer factory
// return our name label renderer as the default for all non-EdgeItems
// includes straight line edges for EdgeItems by default
vis.setRendererFactory(new DefaultRendererFactory(ir, er));
This is just a demo to illustrate custom rendering. In real you would probably retrieve label text and color from the graph model, ie: EdgeItem.getString(), getTextColor()
. I guess both attribute could come from the GraphML data. Also the example code shows how to set colors for nodes, it might be adapted for edges as well (though I haven't tried):
// -- 4. the processing actions ---------------------------------------
...
// use black for node text
ColorAction text = new ColorAction("graph.nodes",
VisualItem.TEXTCOLOR, ColorLib.gray(0));
来源:https://stackoverflow.com/questions/8010823/prefuse-adding-edge-weights-to-the-graphview-demo