changeset 7:45dad9e38c82

first functional version of commentary visualisation.
author casties
date Thu, 01 Oct 2015 14:39:56 +0200
parents aeef1fedd899
children 18ef6948d689 0f4846255b20
files ismi-python-neo4jrestclient/ismi-vis.py ismi-python-neo4jrestclient/static/index.html
diffstat 2 files changed, 67 insertions(+), 58 deletions(-) [+]
line wrap: on
line diff
--- a/ismi-python-neo4jrestclient/ismi-vis.py	Mon Sep 28 18:15:35 2015 +0200
+++ b/ismi-python-neo4jrestclient/ismi-vis.py	Thu Oct 01 14:39:56 2015 +0200
@@ -3,7 +3,7 @@
 
 from flask import Flask, Response, request
 
-from neo4jrestclient.client import GraphDatabase, Node
+from neo4jrestclient.client import GraphDatabase, Node, Relationship
 
 app = Flask(__name__, static_url_path='/static/')
 gdb = GraphDatabase("http://localhost:7474", username="neo4j", password="neo5j")
@@ -16,27 +16,41 @@
 
 @app.route("/graph")
 def get_graph():
-    query = ("MATCH (m:Movie)<-[:ACTED_IN]-(a:Person) "
-             "RETURN m.title as movie, collect(a.name) as cast "
-             "LIMIT {limit}")
-    results = gdb.query(query,
-                        params={"limit": request.args.get("limit", 100)})
+    query = ("match (t1:TEXT)-[r:is_commentary_on]->(t2:TEXT) return t1,r,t2")
+    results = gdb.query(query, returns=(Node,Relationship,Node))
+    n4j_nodes = {}
+    node_idx = {}
     nodes = []
     rels = []
     i = 0
-    for movie, cast in results:
-        nodes.append({"title": movie, "label": "movie"})
-        target = i
-        i += 1
-        for name in cast:
-            actor = {"title": name, "label": "actor"}
-            try:
-                source = nodes.index(actor)
-            except ValueError:
-                nodes.append(actor)
-                source = i
-                i += 1
-            rels.append({"source": source, "target": target})
+    for node1, rel, node2 in results:
+        # source node
+        id1 = node1['ismi_id']
+        if id1 not in n4j_nodes:
+            n4j_nodes[id1] = node1
+            nodes.append({"title": node1['label'], "label": "TEXT"})
+            node_idx[id1] = i
+            source = i
+            i += 1
+
+        else:
+            source = node_idx[id1]
+
+        # target node
+        id2 = node2['ismi_id']
+        if id2 not in n4j_nodes:
+            n4j_nodes[id2] = node2
+            nodes.append({"title": node2['label'], "label": "TEXT"})
+            node_idx[id2] = i
+            target = i
+            i += 1
+
+        else:
+            target = node_idx[id2]
+
+        # relation
+        rels.append({"source": source, "target": target})
+
     return Response(dumps({"nodes": nodes, "links": rels}),
                     mimetype="application/json")
 
@@ -48,32 +62,27 @@
     except KeyError:
         return []
     else:
-        query = ("MATCH (movie:Movie) "
-                 "WHERE movie.title =~ {title} "
-                 "RETURN movie")
+        query = ("MATCH (text:TEXT) "
+                 "WHERE text.label =~ {title} "
+                 "RETURN text")
         results = gdb.query(
             query,
             returns=Node,
             params={"title": "(?i).*" + q + ".*"}
         )
-        return Response(dumps([{"movie": row.properties}
-                               for [row] in results]),
+        return Response(dumps([{"text": row.properties} for [row] in results]),
                         mimetype="application/json")
 
 
-@app.route("/movie/<title>")
-def get_movie(title):
-    query = ("MATCH (movie:Movie {title:{title}}) "
-             "OPTIONAL MATCH (movie)<-[r]-(person:Person) "
-             "RETURN movie.title as title,"
-             "collect([person.name, "
-             "         head(split(lower(type(r)), '_')), r.roles]) as cast "
-             "LIMIT 1")
-    results = gdb.query(query, params={"title": title})
-    title, cast = results[0]
-    return Response(dumps({"title": title,
-                           "cast": [dict(zip(("name", "job", "role"), member))
-                                    for member in cast]}),
+@app.route("/text/<text_id>")
+def get_text(text_id):
+    query = ("MATCH (text:TEXT {ismi_id:{text_id}}) "
+             " RETURN text"
+             " LIMIT 1")
+    results = gdb.query(query, returns=Node, params={"text_id": int(text_id)})
+    node = results[0][0]
+    print("node:%s"%repr(node))
+    return Response(dumps({"title": node['label'], "attrs": node.properties}),
                     mimetype="application/json")
 
 
--- a/ismi-python-neo4jrestclient/static/index.html	Mon Sep 28 18:15:35 2015 +0200
+++ b/ismi-python-neo4jrestclient/static/index.html	Thu Oct 01 14:39:56 2015 +0200
@@ -16,7 +16,7 @@
                     <li>
                         <form role="search" class="navbar-form" id="search">
                             <div class="form-group">
-                                <input type="text" value="Matrix" placeholder="Search for Movie Title" class="form-control" name="search">
+                                <input type="text" value="Qushji" placeholder="Search for Title" class="form-control" name="search">
                             </div>
                             <button class="btn btn-default" type="submit">Search</button>
                         </form>
@@ -30,7 +30,7 @@
                     </a>
                 </div>
                 <div class="navbar-brand">
-                    <div class="brand">ISMI Texts</div>
+                    <div class="brand">ISMI Commentary relations between Texts</div>
                 </div>
             </div>
         </div>
@@ -44,9 +44,9 @@
             <table id="results" class="table table-striped table-hover">
                 <thead>
                 <tr>
-                    <th>Movie</th>
-                    <th>Released</th>
-                    <th>Tagline</th>
+                    <th>Title (translit)</th>
+                    <th>ismi_id</th>
+                    <th>Title (arabic)</th>
                 </tr>
                 </thead>
                 <tbody>
@@ -58,12 +58,12 @@
         <div class="panel panel-default">
             <div class="panel-heading" id="title">Details</div>
             <div class="row">
-                <div class="col-sm-4 col-md-4">
+                <!-- <div class="col-sm-4 col-md-4">
                     <img src="" class="well" id="poster"/>
-                </div>
+                </div> -->
                 <div class="col-md-8 col-sm-8">
-                    <h4>Crew</h4>
-                    <ul id="crew">
+                    <h4>Details</h4>
+                    <ul id="info">
                     </ul>
                 </div>
             </div>
@@ -72,7 +72,7 @@
 </div>
 <style type="text/css">
     .node { stroke: #222; stroke-width: 1.5px; }
-    .node.actor { fill: #888; }
+    .node.TEXT { fill: #888; }
     .node.movie { fill: #BBB; }
     .link { stroke: #999; stroke-opacity: .6; stroke-width: 1px; }
 </style>
@@ -81,16 +81,16 @@
 <script src="http://d3js.org/d3.v3.min.js" type="text/javascript"></script>
 <script type="text/javascript">
     $(function () {
-        function showMovie(title) {
-            $.get("/movie/" + encodeURIComponent(title),
+        function showMovie(text_id) {
+            $.get("/text/" + encodeURIComponent(text_id),
                     function (data) {
                         if (!data) return;
                         $("#title").text(data.title);
-                        $("#poster").attr("src","http://neo4j-contrib.github.io/developer-resources/language-guides/assets/posters/"+encodeURIComponent(data.title)+".jpg");
-                        var $list = $("#crew").empty();
-                        data.cast.forEach(function (cast) {
-                            $list.append($("<li>" + cast.name + " " +cast.job + (cast.job == "acted"?" as " + cast.role : "") + "</li>"));
-                        });
+                        // $("#poster").attr("src","http://neo4j-contrib.github.io/developer-resources/language-guides/assets/posters/"+encodeURIComponent(data.title)+".jpg");
+                        var $list = $("#info").empty();
+                        for (key in data.attrs) {
+                            $list.append($("<li>" + key + ": " + data.attrs[key] + "</li>"));
+                        };
                     }, "json");
             return false;
         }
@@ -101,11 +101,11 @@
                         var t = $("table#results tbody").empty();
                         if (!data || data.length == 0) return;
                         data.forEach(function (row) {
-                            var movie = row.movie;
-                            $("<tr><td class='movie'>" + movie.title + "</td><td>" + movie.released + "</td><td>" + movie.tagline + "</td></tr>").appendTo(t)
-                                    .click(function() { showMovie($(this).find("td.movie").text());})
+                            var text = row.text;
+                            $("<tr><td>" + text.label + "</td><td>" + text.full_title + "</td><td class='text_id'>" + text.ismi_id + "</td></tr>").appendTo(t)
+                                    .click(function() { showMovie($(this).find("td.text_id").text());})
                         });
-                        showMovie(data[0].movie.title);
+                        showMovie(data[0].text.ismi_id);
                     }, "json");
             return false;
         }