pedvizapi


christian fuchsberger1, mario falchi2, lukas forer1, peter pramstaller1

1Institute of Genetic Medicine, European Academy, Bolzano, Italy
2Twin Research & Genetic Epidemiology Unit, Kings College London, London

Description Comparison In use Tutorials DemoApp Rpedviz Help Forum Download christian.fuchsberger@eurac.edu

Show me the pedigree!

public static void main(String[] args) {

	//Step 1
	Graph graph = new Graph();
		CsvGraphLoader loader = new CsvGraphLoader("tutorial_data.csv", ",");
		loader.setSettings("PID", "MOM", "DAD");
		loader.load(graph);

	//Step 2
	Sugiyama s = new Sugiyama(graph);
		s.run();

	//Creates a frame
	JFrame frame = new JFrame();
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	frame.setSize(800, 600);

	//Step 3
	GraphView2D view = new GraphView2D(s.getLayoutedGraph());
		frame.add(view.getComponent());

	frame.setVisible(true);

}

[complete source]
[tutorial_data.csv]

Import data from database

An example with HSQL:

	Database db = new HSQLDatabase();
	Graph graph = new Graph();
	if (db.connect("user", "pass", "connection-string")) {
	    DatabaseGraphLoader loader = new DatabaseGraphLoader(db,
		    "table");
	    loader.setSettings("pid-column", "mom-column", "dad-column");
	    loader.load(graph);
	    db.close();
	}
Complex custom symbols,
here a basic haplotype representation.

Extend the class Symbol2D and override the method drawSymbol(..). Its parameters are the Gaphics2D object, the position and size of the node, the fill and border-color and at least the currentNode object.

This source code draws a rectangle at the bottom of the sex symbol (it can be the border for the haplotype).

public class MyHaplotypeSymbol extends Symbol2D {

    private Rectangle2D rectangle = new Rectangle2D.Double();

    public void drawSymbol(Graphics2D g, Point2D.Float position, float size,
        Color border, Color fill, Node node) {

        float top = (float)(-position.getY() + (size / 2f)+0.5);
        float left =(float)(position.getX() - (size / 2f));

        //draws background
        g.setColor(fill);
        rectangle.setFrame(left+1.5, top, size-3, size*3);
        g.fill(rectangle);

        //draws the border
        g.setColor(border);
        rectangle.setFrame(left+1.5, top, size-3, size*3);
        g.draw(rectangle);
    }

    @Override
    public int getPriority() {
        return 0;
    }
}

Using the Node object you can read the traits with getUserData(..).

The method getPriority() returns the priority of the symbol. Symbols like SymbolSexMale and SymbolSexFemale have a low priority (0), however the SymbolDeceased has a higher priority (5). The priorities define the sequence for drawing the symbols.

You can use your symbol in combination with ShapeRule or you can define it as standard symbol:

graphView.getDefaultNodeView().addSymbol(new MyHaplotypeSymbol())
Workaround for bigger symbols

If you are working with large symbols then spacing is an issue.

In the current version of the pedvizapi you must adapt the spacing between the nodes by hand. Helpful methods are:

  • rubberBands.setVerticalSpacing(..)
  • rubberBands.setHorizontalGap(..)
  • graphView.getDefaultEdgeView().setGapTop(...)
  • graphView.getDefaultNodeView().setGap(...)

[complete source]
[tutorial_data.csv]

Node Styles

In the pedvizapi nodes are defined by rules. A lot of Rules are already implemented, such as for colors, symbols and hints. In this tutorial we define a new Rule.

Difference between Node and NodeView

An individual will be represented by the class Node. Every Node has his own NodeView object. It will be used for drawing the node on a GraphView. The NodeView object saves informations like the position, fill color, border color and symbols for a specific Node. You don’t have access directly to a NodeView, but across a Rule.

Class Rule

Every rule must extend the class Rule and must overwrite the method applyRule(..). This methode will be run for every individual with its NodeView as parameter. You get the specific Node from the given NodeView by the method getNode(). Now you are able to change the node by using setter-methods from NodeView.

class MyFantasticRule extends Rule {

    public void applyRule(NodeView nodeview) {

        // gets a reference to node
        Node node = nodeview.getNode();

        // now you have access to the traits
        Object value = node.getUserData("TRAIT");
        if (value != null) {
            Integer trait = Integer.parseInt(value.toString());
            if (trait > 107)
                nodeview.setColor(Color.red);
			else
                nodeview.setColor(Color.blue);

            // add a wonderful hint
            nodeview.setHintText("trait: " + trait);
    }
}

The new Rule must be added to the GraphView with addRule(...).

Hints
  • If you add more rules, they are applied one after another.
  • A rule can overwrite values changed by an earlier rule.

[complete source]
[tutorial_data.csv]

Customization

Some usefull hints to customize the visualization. It's only a small overview of the core features. To see pedvizapi in its full strength, check out the demo section and the documentation.

  • First of all, change the background color:
    	view.setBackground(Color.YELLOW);
  • The appearance for all nodes and edges you can set in the DefaultNodeView and the DefaultEdgeView object. This must happen before you runs the layout algorithm.
    	DefaultEdgeView e = new DefaultEdgeView();
    	e.setWidth(0.0005f);
    	e.setColor(new Color(100,100,100));
    	e.setAlphaForLongLines(0.2f);
    	e.setHighlightedColor(Color.black);
    
    	DefaultNodeView n = new DefaultNodeView();
    	n.setColor(Color.orange);
    	n.addHintAttribute("pid");
    	n.addHintAttribute("mom");
    	n.addHintAttribute("dad");
    
    	Sugiyama algorithm = new Sugiyama(graph, n, e);
    	algorithm.run();
  • Add a rule to your GraphView object (see: ColorRule, ShapeRule and HintRule), with it you can change the appearance of particular nodes (e.g: all sick individuals have a red color, symbols are dependent on sex).
    	ColorRule rule = new ColorRule("sick", 1", Color.red);
    	view.addRule(rule);
    
    	view.addRule(new ShapeRule("sex", "1", new SymbolSexFemale());
    	view.addRule(new ShapeRule("sex", "2", new SymbolSexMale());
    	view.addRule(new ShapeRule("sex", "-1", new SymbolSexUndesignated());

    [complete source]
    [tutorial_data.csv]

  • Enable the selection for nodes and register a NodeListener to react on it:
  • 	view.setSelectionEnabled(true);
    	view.addNodeListener(new NodeListener() {
    	    public void onNodeEvent(NodeEvent event) {
    		switch (event.getType()) {
    		case NodeEvent.MOUSE_ENTER:
    		    ...
    		    break;
    		case NodeEvent.MOUSE_LEAVE:
    		    ...
    		    break;
    		case NodeEvent.DESELECTED:
    			...
    		    break;
    		case NodeEvent.SELECTED:
    			...
    		    break;
    		case NodeEvent.ALL_DESELECTED:
    		    ...
    		    break;
    	    }
    	});
    Useful classes: NodeEvent, PathHighlighter and LODHighlighter.

    [complete source]
    [tutorial_data.csv]

  • Use the Filter and the Highlighter class to find important nodes and highlight them. Also it's possible to hide unimportant stuff.
    	Node node = graph.getNode(nodeId);
    	if (selectedNode != null) {
    	    ArrayList nodes = Highlighter.findParentsAndChilds(node, 1);
    	    graphView.highlight(nodes);
    	} else {
    	    graphView.unHighlightAll();
    	}