Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
edsu committed Sep 23, 2010
0 parents commit 7f5ee1d
Show file tree
Hide file tree
Showing 6 changed files with 5,111 additions and 0 deletions.
15 changes: 15 additions & 0 deletions README
@@ -0,0 +1,15 @@
This is a visualization of the Linked Open Data cloud using the ProtoVis
JavaScript library. The underlying data is generated by talking to the
Comprehensive Knowledge Archive Network (CKAN) API.

To generate the lod.js data file you should be able to run ckan.py:

./ckan.py > lod.js

It can take a few minutes to run, so go make yourself a cup of tea while
it's running. After that you should be able to load index.html in
your browser.

Ed Summers
ehs@pobox.com

98 changes: 98 additions & 0 deletions ckan.py
@@ -0,0 +1,98 @@
#!/usr/bin/env python

"""
This is a little script that will pull down all the package information
for packages in the lodcloud group on CKAN, and write out JSON dataset
for ProtoVis.
"""

import sys
import json
import urllib
import logging


LOG_FILE = "ckan.log"
LOG_LEVEL = logging.INFO


def main(argv):
logging.basicConfig(filename=LOG_FILE, level=LOG_LEVEL)
packages = lod_packages()
protovis = protovis_json(packages)
print "var lod = " + json.dumps(protovis, indent=2)


def lod_packages():
log = logging.getLogger()
packages = []
count = 0
for package in ckan('group/lodcloud')['packages']:
package_info = ckan('package/%s' % package)
package_info['internal_id'] = count
packages.append(package_info)
log.info("got info for %s" % package_info['name'])
count += 1
return packages


def protovis_json(packages):
protovis = {'nodes': get_nodes(packages),
'links': get_links(packages)}
return protovis


def get_nodes(packages):
nodes = []
for package in packages:
if package['ratings_average'] == None:
rating = 0
else:
rating = int(round(float(package['ratings_average'])))
nodes.append({
'rating': rating,
'nodeName': package['title']})
return nodes


def get_links(packages):
log = logging.getLogger()

# first get a dictionary lookup for all the packages by name
package_map = {}
for package in packages:
package_map[package['name']] = package

# now generate links based on the numeric id of the package
links = []
for from_package in packages:
for key in from_package['extras']:
if key.startswith('links:'):
to_package_name = key.split(':')[1]
if not package_map.has_key(to_package_name):
log.error("%s has link to %s which doesn't exist" % \
(from_package['name'], to_package_name))
continue
links.append({
'source': from_package['internal_id'],
'target': package_map[to_package_name]['internal_id']})
return links


def ckan(path):
j = urllib.urlopen('http://ckan.net/api/rest/' + path).read()
return json.loads(j)


def configure_logging():
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
handler = logging.FileHandler(log_file)
formatter = logging.Formatter("""[%(asctime)s %(levelname)s %(name)s] %(message)s""")
handler.setFormatter(formatter)
logger.addHandler(handler)


if __name__ == "__main__":
main(sys.argv)
67 changes: 67 additions & 0 deletions index.html
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html>
<head>
<title>Linked Open Data Touchgraph</title>
<link href='http://fonts.googleapis.com/css?family=Inconsolata' rel='stylesheet' type='text/css'>
<style type="text/css">
body {
margin-left: 10%;
margin-right: 10%;
font-family: "Inconsolata";
}
h1 {
font-size: 26pt;
text-align: center;
margin-bottom: 40px;
}
#content {
width: 100%;
}
#graph_console {
width: 100%;
}
#graph {
height: 650px;
width: 100%;
border-color: ltgray;
}
#about {
}
</style>
</head>
<body>
<h1>Linked Open Data Touchgraph</h1>
<div id="content">
<div id="about">
<p>
This is a touchgraph version of the
<a href="http://lod-cloud.net/">Linked Open Data Cloud</a>.
It is based on the same underlying data using the
Comprehensive Knowledge Archive Network (CKAN)
<a href="http://knowledgeforge.net/ckan/doc/ckan/api.html">API</a>
to pull all the packages in the the
<a href="http://ckan.net/group/lodcloud">lodcloud</a> group.
If your screen <b>goes crazy</b> cross your fingers and try to
reload the page a couple times. The colors reflect the
CKAN rating: (<span style="color: black">0</span>,
<span style="color: red;">1</span>,
<span style="color: pink;">2</span>,
<span style="color: orange;">3</span>,
<span style="color: lightgreen;">4</span>,
<span style="color: green;">5</span>)
More about how this graph was
generated can be found on
<a href="http://github.com/edsu/lod-cloud">Github</a>.
Comments/questions welcome at
<a href="mailto:ehs@pobox.com">ehs@pobox.com</a>.
</p>
</div>
<div id="graph_console">
<iframe id="graph" src="lod.html"></iframe>
</div>
</div>
<br />
<br />
<br />
</body>
</html>
64 changes: 64 additions & 0 deletions lod.html
@@ -0,0 +1,64 @@
<html>
<head>
<title>Force-Directed Layout</title>
<script type="text/javascript" src="protovis-r3.2.js"></script>
<script type="text/javascript" src="lod.js"></script>
<style type="text/css">
body {
margin: 0;
}
</style>
</head>
<body>
<script type="text/javascript+protovis">

function nodeColor(node) {
if (node.rating == 5)
return "green";
else if (node.rating == 4)
return "lightgreen";
else if (node.rating == 3)
return "orange";
else if (node.rating = 2)
return "pink"
else if (node.rating = 1)
return "red";
else
return "white";
}

var w = document.body.clientWidth,
h = document.body.clientHeight,
colors = pv.Colors.category19();

var vis = new pv.Panel()
.width(w)
.height(h)
.fillStyle("white")
.event("mousedown", pv.Behavior.pan())
.event("mousewheel", pv.Behavior.zoom());

var force = vis.add(pv.Layout.Force)
.nodes(lod.nodes)
.links(lod.links)
.bound(true)
.springDamping(0.1)
.springLength(10)
.springConstant(0.000001);

force.link.add(pv.Line);

force.node.add(pv.Dot)
.size(function(d) (d.linkDegree + 4) * Math.pow(this.scale, -1.5))
.fillStyle(function(d) nodeColor(d))
.strokeStyle(function() this.fillStyle().darker())
.lineWidth(1)
.title(function(d) d.nodeName)
.event("mousedown", pv.Behavior.drag())
.event("drag", force);

vis.render();

</script>
</body>
</html>

0 comments on commit 7f5ee1d

Please sign in to comment.