Dance.js is dancing based on data. It's much like Backbone.js, but with a foundation for building interactive visualizations in the spirit of D3.js. It comes with Data.js, a uniform interface for handling your domain data.
Created
April 22, 2012 05:49
-
-
Save michael/2458819 to your computer and use it in GitHub Desktop.
The Scatterplot Dance
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
window.countries_data = { | |
"type": { | |
"_id": "/type/country", | |
"name": "Countries", | |
"properties": { | |
"name": {"name": "Country Name", "type": "string" }, | |
"languages": {"name": "Languages spoken", "type": "string" }, | |
"population": { "name": "Population", "type": "number" }, | |
"gdp": { "name": "GDP per capita", "type": "number" } | |
}, | |
"indexes": { | |
"by_name": ["name"] | |
} | |
}, | |
"objects": [ | |
{ | |
"_id": "at", | |
"name": "Austria", | |
"languages": ["German", "Austrian"], | |
"population": 8.3, | |
"gdp": 41.805 | |
}, | |
{ | |
"_id": "de", | |
"name": "Germany", | |
"languages": ["German"], | |
"population": 82, | |
"gdp": 46.860 | |
}, | |
{ | |
"_id": "us", | |
"name": "United States of America", | |
"languages": ["German", "English", "Spanish", "Chinese", "French"], | |
"population": 311, | |
"gdp": 36.081 | |
}, | |
{ | |
"_id": "uk", | |
"name": "United Kingdom", | |
"languages": ["English", "Irish", "Scottish Gaelic"], | |
"population": 62.3, | |
"gdp": 36.081 | |
}, | |
{ | |
"_id": "es", | |
"name": "Spain", | |
"languages": ["Spanish"], | |
"population": 30.6, | |
"gdp": 36.081 | |
}, | |
{ | |
"_id": "gr", | |
"name": "Greece", | |
"languages": ["Greek"], | |
"population": 11.0, | |
"gdp": 36.081 | |
}, | |
{ | |
"_id": "ca", | |
"name": "Canada", | |
"languages": ["English", "French", "Spanish"], | |
"population": 40.1, | |
"gdp": 40.457 | |
} | |
] | |
}; |
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset='UTF-8'/> | |
<title>Dance.js - The Scatterplot Dance</title> | |
<link rel='stylesheet' href='scatterplot.css'> | |
<script src='https://raw.github.com/documentcloud/underscore/87cac5bd057ceafd6f779b1df33de61ca21b5e1d/underscore.js'></script> | |
<script src='https://raw.github.com/michael/data/fe65cb9ab32fbee59f14f44e17e186cf69ff16a7/data.js'></script> | |
<script src='http://code.jquery.com/jquery-1.7.2.min.js'></script> | |
<script src='https://raw.github.com/michael/dance/96cb9a6384acce19202275c6dce9b7fbdac87763/dance.js'></script> | |
<!-- Countries data --> | |
<script src='countries.js'></script> | |
<!-- Dance Performers --> | |
<script src="scatterplot.js"></script> | |
<script> | |
$(function() { | |
window.countries = new Data.Collection(countries_data); | |
window.scatterplot = new Scatterplot({}); | |
scatterplot.update(countries, ["gdp", "population"]); | |
// Update | |
function update() { | |
var language = $('#language').val(); | |
var query = {}; | |
if (language) query["languages"] = [ language ]; | |
var items = countries.find(query); | |
scatterplot.update(items, [$('#property_x').val(), $('#property_y').val()]); | |
} | |
$('#property_x').change(update); | |
$('#property_y').change(update); | |
$('#language').change(update); | |
}); | |
</script> | |
</head> | |
<body> | |
<div id='container'> | |
X | |
<select id="property_x"> | |
<option value="gdp">GDP (thousands)</option> | |
<option value="population">Population (millions)</option> | |
</select> | |
Y | |
<select id="property_y"> | |
<option value="gdp">GDP (thousands)</option> | |
<option selected="selected" value="population">Population (millions)</option> | |
</select> | |
<select id="language"> | |
<option value="">All</option> | |
<option value="English">English</option> | |
<option value="French">French</option> | |
<option value="German">German</option> | |
<option value="Greek">Greek</option> | |
<option value="Spanish">Spanish</option> | |
<option value="Scottish Gaelic">Scottish Gaelic</option> | |
</select> | |
<div id='canvas'></div> | |
</div> | |
</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
body { | |
font: 15px 'Helvetica Neue' Arial | |
} | |
#canvas { | |
margin-top: 20px; | |
border: 30px solid #eee; | |
width: 550px; | |
height: 350px; | |
background: #eee; | |
position: relative; | |
} | |
.dot { | |
-moz-transition-duration: 0.8s; | |
-webkit-transition-duration: 0.8s; | |
transition-duration: 0.8s; | |
position: absolute; | |
bottom: 0px; | |
background: steelblue; | |
opacity: 0.7; | |
border-radius: 5px; | |
} | |
.bar:hover { opacity: 1.0; } | |
.dot .label { | |
display: none; | |
text-transform: uppercase; | |
position: absolute; | |
bottom: -25px; | |
left: 10px; | |
right: 0; | |
width: 40px; | |
text-align: center; | |
background: #ccc; | |
padding: 10px; | |
} | |
.dot:hover .label { | |
display: block; | |
} | |
.dot .value { | |
font-weight: bold; | |
text-transform: uppercase; | |
position: absolute; | |
top: -25px; | |
left: 0; | |
right: 0; | |
text-align: center; | |
} |
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
(function(exports) { | |
// Helpers | |
// ------------ | |
function htmlId(obj) { | |
return obj._id.split('/').join('_'); | |
} | |
// Collections you wanna dance with | |
// ------------ | |
var collections = { | |
"items": { | |
enter: function(items) { | |
items.each(function(item) { | |
var dot = $('<div class="dot" id="'+htmlId(item)+'"><div class="label">'+item._id+'</div></div>') | |
.css('left', Math.random()*$('#canvas').width()) | |
.css('bottom', Math.random()*$('#canvas').height()) | |
.css('width', 1) | |
.css('height', 1); | |
$('#canvas').append(dot); | |
}); | |
// Delegate to update (motion tweening fun) | |
_.delay(this.collections["items"].update, 200, items); | |
}, | |
update: function(items) { | |
items.each(function(item) { | |
var cell = $('#'+htmlId(item)) | |
.css('left', item.pos.x) | |
.css('bottom', item.pos.y) | |
.css('width', 10) | |
.css('height', 10); | |
}); | |
}, | |
exit: function(items) { | |
items.each(function(i) { $('#'+htmlId(i)).remove() }); | |
} | |
} | |
}; | |
// Scatterplot Visualization | |
// ------------ | |
var Scatterplot = Dance.Performer.extend({ | |
collections: collections, | |
initialize: function(options) { | |
this.data["items"] = options.items; | |
}, | |
layout: function(properties) { | |
var that = this; | |
// Prepare scales | |
function aggregate(p, fn) { | |
var values = _.map(that.data["items"].objects, function(i) { return i.get(p); }); | |
return fn.apply(this, values); | |
} | |
var minX = aggregate(properties[0], Math.min); | |
var maxX = aggregate(properties[0], Math.max); | |
var minY = aggregate(properties[1], Math.min); | |
var maxY = aggregate(properties[1], Math.max); | |
function x(val) { | |
return (((val-minX) * $('#canvas').width()) / (maxX-minX)); | |
} | |
function y(val) { | |
return (((val-minY) * $('#canvas').height()) / (maxY-minY)); | |
} | |
// Apply layout | |
this.data["items"].each(function(item, key, index) { | |
item.pos = { | |
x: x(item.get(properties[0])), | |
y: y(item.get(properties[1])) | |
}; | |
}); | |
}, | |
update: function(items, properties) { | |
this.data["items"] = items; | |
this.layout(properties); | |
this.refresh(); | |
} | |
}); | |
exports.Scatterplot = Scatterplot; | |
})(window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment