Skip to content

Instantly share code, notes, and snippets.

@darthmall
Last active December 17, 2015 00:39
Show Gist options
  • Save darthmall/5522747 to your computer and use it in GitHub Desktop.
Save darthmall/5522747 to your computer and use it in GitHub Desktop.
AppJS data explorer.
var app = module.exports = require('appjs');
var sqlite3 = require('sqlite3').verbose();
// Store a reference to the objects generated from the SQLite database in bins.
// This seems to prevent the application from crashing, probably by ensuring
// these objects aren't deallocated.
var bins, db;
function density(cutoff, unoccupied, callback) {
function tallyBin(err, results) {
function tally(bin) {
return function (err, results) {
if (err) {
console.log(err);
callback(err);
return;
}
var total = 0, area = 0,
percentiles = [];
for (var i = 0; i <= 100; i += 5) {
percentiles.push({
'percentile': i / 100,
'delta': Infinity,
'density': 0
});
}
results = results.map(function (row) {
total += row.area;
return {
'area' : row.area,
'density' : row.density > cutoff ? 0 : row.density
};
}).sort(function (a, b) { return a.density - b.density; });
results.forEach(function (row) {
area += row.area;
var p = area / total;
percentiles.forEach(function (d) {
var delta = Math.abs(d.percentile - p);
if (delta <= d.delta) {
d.delta = delta;
d.density = row.density;
}
});
});
console.log(bin + ': done');
// Store a reference to the calculated values to ensure they won't be
// dereferenced later.
bins[bin] = percentiles;
// Callback into the front-end JavaScript running in Chromium to pass
// the calculated percentiles for this bin.
callback(err, bin, percentiles);
};
}
if (err) {
console.log(err);
callback(err);
return;
}
results.forEach(function (row) {
if (unoccupied) {
db.all('SELECT area, density FROM livestock WHERE bin = ? AND density > 0 AND density <= ?',
[row.bin, cutoff], tally(row.bin));
} else {
db.all('SELECT area, density FROM livestock WHERE bin = ?', [row.bin],
tally(row.bin));
}
});
}
bins = {};
if (!db) {
db = new sqlite3.Database('livestock.db', function (err) {
console.log(err || 'Database opened');
if (!err) {
db.all('SELECT DISTINCT bin FROM livestock', tallyBin);
} else {
callback(err);
}
});
} else {
db.all('SELECT DISTINCT bin FROM livestock', tallyBin);
}
}
app.serveFilesFrom(__dirname + '/content');
var menubar = app.createMenu([{
label:'&File',
submenu:[
{
label:'E&xit',
action: function(){
window.close();
}
}
]
},{
label:'&Window',
submenu:[
{
label:'Fullscreen',
action:function(item) {
window.frame.fullscreen();
console.log(item.label+" called.");
}
},
{
label:'Minimize',
action:function(){
window.frame.minimize();
}
},
{
label:'Maximize',
action:function(){
window.frame.maximize();
}
},{
label:''//separator
},{
label:'Restore',
action:function(){
window.frame.restore();
}
}
]
}]);
menubar.on('select',function(item){
console.log("menu item "+item.label+" clicked");
});
var window = app.createWindow({
width : 640,
height : 460,
icons : __dirname + '/content/icons',
name : 'Biomass Densities'
});
window.on('create', function(){
console.log("Window Created");
window.frame.show();
window.frame.center();
window.frame.setMenuBar(menubar);
});
window.on('ready', function(){
console.log("Window Ready");
window.process = process;
window.module = module;
window.density = density;
window.stdout = console.log;
function F12(e){ return e.keyIdentifier === 'F12' }
function Command_Option_J(e){ return e.keyCode === 74 && e.metaKey && e.altKey }
window.addEventListener('keydown', function(e){
if (F12(e) || Command_Option_J(e)) {
window.frame.openDevTools();
}
});
});
window.on('close', function(){
console.log("Window Closed");
});
<!doctype html>
<html>
<head>
<title>Biomass Density</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<form class="controls">
<label for="cutoff">Cutoff density</label>
<div class="slider">
<input id="cutoff-slider" name="cutoff" type="range" min="0" max="10" value="3" step="0.01" />
<input id="cutoff-value" name="cutoff" type="text" value="3.0" size="4" maxlength="4" />
</div>
<input id="unoccupied" name="unoccupied" type="checkbox" />
<label for="unoccupied">Include unoccuped pasture</label>
<button id="export">Export</button>
</form>
<script src="d3.v3.min.js"></script>
<script src="main.js"></script>
</body>
</html>
addEventListener('app-ready', function () {
function update(err, bin, percentiles) {
if (err) {
window.alert(err);
return;
}
console.log(bin);
// bins[bin] = JSON.parse(percentiles);
// var lines = svg.selectAll('.bin')
// .data(bins, function (d) { return d.bin; });
// lines.enter().append('path')
// .attr('class', 'bin')
// .attr('d', function (d) { return line(d.density); });
}
var cutoff = document.getElementById('cutoff-value');
var margin = {top: 20, right: 10, bottom: 20, left: 10};
var width = 640 - margin.left - margin.right,
height = 460 - margin.top - margin.bottom;
var svg = d3.select('body').append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
var x = d3.scale.linear().range([0, width]).domain([0, 1]),
y = d3.scale.linear().range([height, 0]).domain([0, cutoff.value]);
var line = d3.svg.line()
.x(function (d) { return x(d.percentile); })
.y(function (d) { return y(d.density); });
var bins = {};
slider(document.getElementsByClassName('slider'));
density(cutoff.value, false, update);
function slider(selection) {
function onSliderChange(input) {
return function (e) {
input.value = e.target.value = precision(e.target.value, 2);
y.domain([0, input.value]);
density(input.value, false, update);
};
}
var i = selection.length;
while (--i >= 0) {
var range = selection[i].children[0],
input = selection[i].children[1];
range.addEventListener('change', onSliderChange(input));
input.addEventListener('change', onSliderChange(range));
}
return selection;
}
function precision(value, decimals) {
return Math.round(value * Math.pow(10, decimals)) / Math.pow(10, decimals);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment