Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7f5ee1d
Showing
6 changed files
with
5,111 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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> |
Oops, something went wrong.