SimpleGraph-MapSystem


Maria Fahl, Wolfgang Fahl

SimpleGraphModule

Map.png

SimpleGraph MapSystem module

The SimpleGraph MapSystem module supplies a simple wrapper for a graph with nodes that have key/value pairs in form of HashMaps. We would not really need this since Apache Tinkerpop/Gremlin already supplies us with properties per node/vertex. Still this system is useful as a helper system and to illustrate the wrapping concepts and possibilities of SimpleGraph see java.api.Map.

Sources

SimpleGraphModule[edit]

Map.png

SimpleGraph MapSystem module

The SimpleGraph MapSystem module supplies a simple wrapper for a graph with nodes that have key/value pairs in form of HashMaps. We would not really need this since Apache Tinkerpop/Gremlin already supplies us with properties per node/vertex. Still this system is useful as a helper system and to illustrate the wrapping concepts and possibilities of SimpleGraph see java.api.Map.

Sources

Example[edit]

Goal[edit]

We'd like to create a tree of carbrands with corresponding car makes.

Result[edit]

CarGraph[edit]

The nodes of this graph are clickable and will lead you to the wikidata pages of the carmakes and carbrands.

Explanation[edit]

The following JUnit Test source code is commented with the explanation on how the MapSystem works.

  @Test
  public void testMapSystem() throws Exception {
    // create a map system and connect to init
    MapSystem ms=new MapSystem();
    ms.connect();
    // init some maps of carbrands and cars each map shall later represent a
    // vertex in the graph with it's properties
    Map[] carbrandmaps= {
        initMap("name","Ferrari","country","Italy","wikidataid","Q27586"),
        initMap("name","Porsche","country","Germany","wikidataid","Q40993"),
        initMap("name","Ford","country","United States","wikidataid","Q44294")
    };
    Map[] carmakemaps= {
        initMap("name","308","year",1984,"wikidataid","Q1407659","brand","Ferrari"),
        initMap("name","328","year",1989,"wikidataid","Q1407669","brand","Ferrari"),
        initMap("name","901","year",1964,"wikidataid","Q2104537","brand","Porsche"),
        initMap("name","2017 GT","year",2017,"wikidataid","Q23856323","brand","Ford")
    };
    // create MapNodes with the given kind "carbrand" or "car" based on the maps
    MapNode startNode=null;
    for (Map map:carbrandmaps) {
      startNode=new MapNode(ms,"carbrand",map);
    }
    for (Map map:carmakemaps) {
      MapNode mapNode=new MapNode(ms,"car",map);
      // link the node of this car to it's carbrand node using the Gremlin graph traversal
      // language - this is the key action for this example
      ms.g().V().hasLabel("carbrand").has("name",map.get("brand")).forEachRemaining(brandNode->{
        brandNode.addEdge("brand", mapNode.getVertex());
      });
    }
    // set a start node for the system
    // any node will do and for this example it is not really necessary - each node
    // has the full graph accesible
    ms.setStartNode(startNode);
    // uncomment if you'd like to see all the node details
    // debug=true;
    if (debug)
      ms.g().V().forEachRemaining(SimpleNode.printDebug);
    // generate a graphviz graph based on this start node
    // show the "brand" edges
    // show the "name" for each node
    // use wikidataid as the identifier
    // and extend to a full url using the WIKIDATA_URL_PREFIX
    // use the rankDir RL = right left
    // and name the graph "CarGraph"
    String graphViz = TestRythm.generateGraphViz(ms.getStartNode(), "brand", "name", "wikidataid",
        WIKIDATA_URL_PREFIX,"RL","CarGraph");
    // uncomment if you'd like to see the graph source code
    // the rendered graph is available at http://www.bitplan.com/index.php?title=SimpleGraph#CarGraph
    // debug = true;
    if (debug)
      System.out.println(graphViz.trim());
    // check that the graph contains one of the expected graphviz code lines
    assertTrue(graphViz.contains("\"Q27586\" [ label=\"Ferrari\" URL=\"https://www.wikidata.org/wiki/Q27586\"]"));
  }

Example[edit]

Goal[edit]

We'd like to create a tree of carbrands with corresponding car makes.

Result[edit]

CarGraph[edit]

The nodes of this graph are clickable and will lead you to the wikidata pages of the carmakes and carbrands.

The file "mwstore://local-backend/local-public/diagrams/archive/20241121190902!Diagrams_f20059dafb79583e108a4b13876f599f.png" already exists.

Explanation[edit]

The following JUnit Test source code is commented with the explanation on how the MapSystem works.

  @Test
  public void testMapSystem() throws Exception {
    // create a map system and connect to init
    MapSystem ms=new MapSystem();
    ms.connect();
    // init some maps of carbrands and cars each map shall later represent a
    // vertex in the graph with it's properties
    Map[] carbrandmaps= {
        initMap("name","Ferrari","country","Italy","wikidataid","Q27586"),
        initMap("name","Porsche","country","Germany","wikidataid","Q40993"),
        initMap("name","Ford","country","United States","wikidataid","Q44294")
    };
    Map[] carmakemaps= {
        initMap("name","308","year",1984,"wikidataid","Q1407659","brand","Ferrari"),
        initMap("name","328","year",1989,"wikidataid","Q1407669","brand","Ferrari"),
        initMap("name","901","year",1964,"wikidataid","Q2104537","brand","Porsche"),
        initMap("name","2017 GT","year",2017,"wikidataid","Q23856323","brand","Ford")
    };
    // create MapNodes with the given kind "carbrand" or "car" based on the maps
    MapNode startNode=null;
    for (Map map:carbrandmaps) {
      startNode=new MapNode(ms,"carbrand",map);
    }
    for (Map map:carmakemaps) {
      MapNode mapNode=new MapNode(ms,"car",map);
      // link the node of this car to it's carbrand node using the Gremlin graph traversal
      // language - this is the key action for this example
      ms.g().V().hasLabel("carbrand").has("name",map.get("brand")).forEachRemaining(brandNode->{
        brandNode.addEdge("brand", mapNode.getVertex());
      });
    }
    // set a start node for the system
    // any node will do and for this example it is not really necessary - each node
    // has the full graph accesible
    ms.setStartNode(startNode);
    // uncomment if you'd like to see all the node details
    // debug=true;
    if (debug)
      ms.g().V().forEachRemaining(SimpleNode.printDebug);
    // generate a graphviz graph based on this start node
    // show the "brand" edges
    // show the "name" for each node
    // use wikidataid as the identifier
    // and extend to a full url using the WIKIDATA_URL_PREFIX
    // use the rankDir RL = right left
    // and name the graph "CarGraph"
    String graphViz = TestRythm.generateGraphViz(ms.getStartNode(), "brand", "name", "wikidataid",
        WIKIDATA_URL_PREFIX,"RL","CarGraph");
    // uncomment if you'd like to see the graph source code
    // the rendered graph is available at http://www.bitplan.com/index.php?title=SimpleGraph#CarGraph
    // debug = true;
    if (debug)
      System.out.println(graphViz.trim());
    // check that the graph contains one of the expected graphviz code lines
    assertTrue(graphViz.contains("\"Q27586\" [ label=\"Ferrari\" URL=\"https://www.wikidata.org/wiki/Q27586\"]"));
  }
🖨 🚪