1   /****************************************************************************
2    **
3    ** This file is part of yFiles-2.9. 
4    ** 
5    ** yWorks proprietary/confidential. Use is subject to license terms.
6    **
7    ** Redistribution of this file or of an unauthorized byte-code version
8    ** of this file is strictly forbidden.
9    **
10   ** Copyright (c) 2000-2011 by yWorks GmbH, Vor dem Kreuzberg 28, 
11   ** 72070 Tuebingen, Germany. All rights reserved.
12   **
13   ***************************************************************************/
14  
15  package demo.base;
16  
17  import y.base.EdgeMap;
18  import y.base.Graph;
19  import y.base.Edge;
20  import y.base.NodeMap;
21  import y.base.Node;
22  import y.util.YRandom;
23  import y.base.EdgeCursor;
24  import y.base.NodeCursor;
25  import y.util.D;
26  
27  /**
28   * This class represents an extended Graph object whose nodes
29   * and edges carry additional data. The yFiles way of adding additional 
30   * features to nodes and edges is not to extend the node and edge
31   * objects themselves but to extend the graph that contains the
32   * nodes and edges. The graph stores the extra data in internal Node-
33   * and/or EdgeMaps. Access to the additional node and edge data is provided
34   * by setter and getter methods of the extended graph.
35   * <br>
36   * There is a main method in this class that serves as a test driver for 
37   * the implementation.
38   *
39   * @see <a href="http://docs.yworks.com/yfiles/doc/developers-guide/custom_data.html#custom_data">Section Binding Data to Graph Elements</a> in the yFiles for Java Developer's Guide
40   */
41  public class ExtendedGraph extends Graph
42  {
43    /**
44     * internal NodeMap that stores additional node data
45     */
46    private NodeMap extraNodeData;
47    
48    /**
49     * internal EdgeMap that stores additional edge data
50     */
51    private EdgeMap extraEdgeData;
52   
53    /////////////////////////////////////////////////////////////////////////////
54    // CONSTRUCTION /////////////////////////////////////////////////////////////
55    /////////////////////////////////////////////////////////////////////////////
56    
57    /** Creates a new instance of ExtendedGraph */
58    public ExtendedGraph()
59    {
60      extraNodeData = createNodeMap();
61      extraEdgeData = createEdgeMap();
62    }
63    
64    /** Creates a graph of type ExtendedGraph */
65    public Graph createGraph()
66    {
67      return new ExtendedGraph();
68    }
69    
70    /////////////////////////////////////////////////////////////////////////////
71    // SETTER AND GETTER ////////////////////////////////////////////////////////
72    /////////////////////////////////////////////////////////////////////////////
73    
74    /**
75     * Returns the edge weight associated with the given edge.
76     * By default 0 will be returned.
77     */
78    public double getEdgeWeight(Edge e)
79    {
80      return extraEdgeData.getDouble(e);
81    }
82    
83    /**
84     * Sets the edge weight associated with the given edge.
85     */
86    public void setEdgeWeight(Edge e, double weight)
87    { 
88      extraEdgeData.setDouble(e, weight);
89    }
90    
91    /**
92     * Returns the node info associated with the given node.
93     *
94     * By default 0 will be returned.
95     */
96    public NodeInfo getNodeInfo(Node v)
97    {
98      NodeInfo info = (NodeInfo)extraNodeData.get(v);
99      
100 //lazy default initialisation could be performed here 
101 //    if(info == null)
102 //    {
103 //      info = new NodeInfo();
104 //      setNodeInfo(v, info);
105 //    }
106 
107     return info;
108 
109   }
110   
111   public void setNodeInfo(Node v, NodeInfo info)
112   {
113     extraNodeData.set(v, info);
114   }
115 
116   public static class NodeInfo
117   {
118     public String name;
119     public String type;
120     public int    version;
121   
122     public NodeInfo()
123     {
124       this("unknown","unknown",0);
125     }
126     
127     public NodeInfo(String name, String type, int version)
128     {
129       this.name = name;
130       this.type = type;
131       this.version = version;
132     }
133     
134     public String toString()
135     {
136       return "Name=" + name + "  Type=" + type + "  Version=" + version;
137     }
138   }
139   
140   
141   public static void main(String[] args)
142   {
143      ExtendedGraph graph = new ExtendedGraph();
144      RandomGraphGenerator rg = new RandomGraphGenerator(0);
145      rg.setNodeCount(10);
146      rg.setEdgeCount(10);
147      rg.generate(graph);
148      YRandom random = new YRandom(0);
149      for(EdgeCursor ec = graph.edges(); ec.ok(); ec.next())
150      {
151        graph.setEdgeWeight(ec.edge(), random.nextDouble(0.0,10.0));
152      }
153      for(NodeCursor nc = graph.nodes(); nc.ok(); nc.next())
154      {
155        Node v = nc.node();
156        NodeInfo info = new NodeInfo("Node #" + v.index(),"Extra Node",1);
157        graph.setNodeInfo(v, info);
158      }
159      
160      for(NodeCursor nc = graph.nodes(); nc.ok(); nc.next())
161      {
162        D.bug(graph.getNodeInfo(nc.node()));
163      }
164      for(EdgeCursor ec = graph.edges(); ec.ok(); ec.next())
165      {
166        D.bug("Edge " + ec.edge().index() + " weight= " + graph.getEdgeWeight(ec.edge()));
167      }
168      
169   }
170 }
171