I am developing a graphical view of data using PREFUSE library.
I have 3 kinds of nodes in my graph:
- APPLICATION
- DATABASE
- INTERFACE
Below are some excerpts from my .xml file containing graph
<node id="AP-1">
<data key="name">Application1</data>
<data key="type">APPLICATION</data>
</node>
<node id="DB-1">
<data key="name">Database1</data>
<data key="type">DATABASE</data>
</node>
<node id="IT-1">
<data key="name">Interface1</data>
<data key="type">INTERFACE</data>
</node>
I want to show the above 3 diff. kinds of nodes with 3 diff. kinds of shapes as follows:
- APPLICATION by Rectangle
- DATABASE by custom shape (shape of a cylinder, usually used to denote a database)
- INTERFACE by circle
I have first read the .xml file in a
Graph g
Q1. Now how can I distinguish these 3 kinds of nodes in a datagroup. I think I should write predicates. I have read the whole predicates and expressions manuals for prefuse but couldn't write a predicate to distinguish them. So what will be the predicate for that?
Q2. How to specify my custom shape and how to set a renderer that can render the custom shape developed by me?
You don't need predicates to assign shapes. In fact, in order to draw custom shapes you have to subclass the shape drawing renderer
ShapeRenderer
. ShapeRenderer distinguishes between shapes using id number (int
). These ints are in structureConstants
for all the standard shapes - like bcr wrote, for exampleConstants.SHAPE_RECTANGLE
.Internally prefuse calls ShapeRenderer's
protected Shape getRawShape(VisualItem item)
function. In turn, this function calls other internals fromShapeRenderer
in order to get the shape to draw. For example:getRawShape
callsint stype = item.getShape()
(set by shape actionDataShapeAction
)then, hawing the shape id at hand, there is
switch
statement selecting proper shape to drawIn order to draw some other shapes (custom ones) you subclass
ShapeRenderer
and provide your own implementation of shape to draw and overridegetRawShape
.If you recognize the shape id as your own you return your shape otherwise you call super(item) in your implementation of
getRawShape
in order to call the standard one.The paradigm for assigning different shapes to nodes is with a DataShapeAction
E.g. in the "Congress" demo (the same applies to Nodes as Tables):
This assigns different shapes to data points based on the value in the "Senate" data field, i.e. senators are one shape, and congressmen are another shape, in some order (there are various controls for this in the API, see Constants.ORDINAL for an example).
So, in other words, you would probably use your "type" data field to indicate what kind of node the node was, and then use a DataShapeAction to assign different shapes.
Defining a new shape is certainly possible, but will require some more tinkering. I'll try to get back to you with a better answer, but I'm guessing the most straightforward way would be to write your own subclass of the noderenderer that was capable of drawing your desired shape, and then perhaps extending DataShapeAction to handle some flag for your new data type. More on that later, though, hopefully.