Skip to content

Instantly share code, notes, and snippets.

@enjalot
Created May 17, 2014 05:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enjalot/4fb6f34fd7eaac6a1ae9 to your computer and use it in GitHub Desktop.
Save enjalot/4fb6f34fd7eaac6a1ae9 to your computer and use it in GitHub Desktop.
kijani horizon
{"description":"kijani horizon","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"horizon.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"style.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"style.css":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":false,"loop":false,"restart":false,"autoinit":true,"pause":true,"loop_type":"pingpong","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"ajax-caching":true,"controls":{"garden":"asprod3"},"thumbnail":"http://i.imgur.com/DU81wHV.png"}
(function() {
d3.horizon = function() {
var bands = 1, // between 1 and 5, typically
mode = "offset", // or mirror
interpolate = "linear", // or basis, monotone, step-before, etc.
x = d3_horizonX,
y = d3_horizonY,
width = 960,
height = 40;
var color = d3.scale.linear()
.domain([-1, 0, 1])
.range(["#d62728", "#fff", "#1f77b4"]);
// For each small multiple…
function horizon(g) {
g.each(function(d) {
var g = d3.select(this),
xMin = Infinity,
xMax = -Infinity,
yMax = -Infinity,
x0, // old x-scale
y0, // old y-scale
t0,
id; // unique id for paths
// Compute x- and y-values along with extents.
var data = d.map(function(d, i) {
var xv = x.call(this, d, i),
yv = y.call(this, d, i);
if (xv < xMin) xMin = xv;
if (xv > xMax) xMax = xv;
if (-yv > yMax) yMax = -yv;
if (yv > yMax) yMax = yv;
return [xv, yv];
});
// Compute the new x- and y-scales, and transform.
var x1 = d3.scale.linear().domain([xMin, xMax]).range([0, width]),
y1 = d3.scale.linear().domain([0, yMax]).range([0, height * bands]),
t1 = d3_horizonTransform(bands, height, mode);
// Retrieve the old scales, if this is an update.
if (this.__chart__) {
x0 = this.__chart__.x;
y0 = this.__chart__.y;
t0 = this.__chart__.t;
id = this.__chart__.id;
} else {
x0 = x1.copy();
y0 = y1.copy();
t0 = t1;
id = ++d3_horizonId;
}
// We'll use a defs to store the area path and the clip path.
var defs = g.selectAll("defs")
.data([null]);
// The clip path is a simple rect.
defs.enter().append("defs").append("clipPath")
.attr("id", "d3_horizon_clip" + id)
.append("rect")
.attr("width", width)
.attr("height", height);
d3.transition(defs.select("rect"))
.attr("width", width)
.attr("height", height);
// We'll use a container to clip all horizon layers at once.
g.selectAll("g")
.data([null])
.enter().append("g")
.attr("clip-path", "url(#d3_horizon_clip" + id + ")");
// Instantiate each copy of the path with different transforms.
var path = g.select("g").selectAll("path")
.data(d3.range(-1, -bands - 1, -1).concat(d3.range(1, bands + 1)), Number);
var d0 = d3_horizonArea
.interpolate(interpolate)
.x(function(d) { return x0(d[0]); })
.y0(height * bands)
.y1(function(d) { return height * bands - y0(d[1]); })
(data);
var d1 = d3_horizonArea
.x(function(d) { return x1(d[0]); })
.y1(function(d) { return height * bands - y1(d[1]); })
(data);
path.enter().append("path")
.style("fill", color)
.attr("transform", t0)
.attr("d", d0);
d3.transition(path)
.style("fill", color)
.attr("transform", t1)
.attr("d", d1);
d3.transition(path.exit())
.attr("transform", t1)
.attr("d", d1)
.remove();
// Stash the new scales.
this.__chart__ = {x: x1, y: y1, t: t1, id: id};
});
}
horizon.bands = function(_) {
if (!arguments.length) return bands;
bands = +_;
color.domain([-bands, 0, bands]);
return horizon;
};
horizon.mode = function(_) {
if (!arguments.length) return mode;
mode = _ + "";
return horizon;
};
horizon.colors = function(_) {
if (!arguments.length) return color.range();
color.range(_);
return horizon;
};
horizon.interpolate = function(_) {
if (!arguments.length) return interpolate;
interpolate = _ + "";
return horizon;
};
horizon.x = function(_) {
if (!arguments.length) return x;
x = _;
return horizon;
};
horizon.y = function(_) {
if (!arguments.length) return y;
y = _;
return horizon;
};
horizon.width = function(_) {
if (!arguments.length) return width;
width = +_;
return horizon;
};
horizon.height = function(_) {
if (!arguments.length) return height;
height = +_;
return horizon;
};
horizon.colors = function(_) {
if (!arguments.length) return color.range();
color.range(_);
return horizon;
};
return horizon;
};
var d3_horizonArea = d3.svg.area(),
d3_horizonId = 0;
function d3_horizonX(d) { return d[0]; }
function d3_horizonY(d) { return d[1]; }
function d3_horizonTransform(bands, h, mode) {
return mode == "offset"
? function(d) { return "translate(0," + (d + (d < 0) - bands) * h + ")"; }
: function(d) { return (d < 0 ? "scale(1,-1)" : "") + "translate(0," + (d - bands) * h + ")"; };
}
})();
var HOUR = 1000 * 60 * 60
var today = Math.floor(+new Date() / HOUR*60) * HOUR/60; //round now to the latest minute mark
var earlier = today - 2 * HOUR; //get data from two hours before that
d3.json("http://50.19.108.27/arduino/list", function(err, gardens) {
console.log("gardens", gardens);
var gnames = [];
gardens.forEach(function(d) {
if(d && +new Date(d.time) > earlier) {
gnames.push(d.report.garden.name)
}
})
gnames.sort(function(a,b) { return b < a ? 1 : -1 });
var garden = tributary.control({name:"garden", options:gnames});
//var start = "2014-05-15T02:03:07.000Z"
//var end = "2014-05-16T01:17:31.000Z"
var start = new Date(earlier).toString()
var end = new Date(today).toString()
var num = 500;
var url = "http://50.19.108.27/arduino/garden/range/" + garden + "?start_time=" + start + "&end_time=" + end + "&num=" + num;
console.log("url:",url);
d3.json(url, function(err, reports) {
//console.log(reports);
if(err) {
console.log(err);
return;
}
console.log("first report", reports[0])
var cx = 50;
var cy = 63;
//grow bed level
var gl = [];
reports.forEach(function(d) {
if(!d || d.report.gb_level_sensor.gbLevel === undefined) return;
gl.push([ d.timestamp, d.report.gb_level_sensor.gbLevel ]);
});
//flow rate
var fr = [];
reports.forEach(function(d) {
if(!d || d.report.flow_rate_sensor.flowRate === undefined) return;
fr.push([ d.timestamp, d.report.flow_rate_sensor.flowRate ]);
});
// flow switch
var fs = [];
reports.forEach(function(d) {
if(!d || d.report.flow_switch_sensor.flow === undefined) return;
fs.push([ d.timestamp, d.report.flow_switch_sensor.flow ]);
});
var width = tributary.sw - 100;//500;
var height = 200;
var svg = d3.select("svg");
var timeScale = d3.time.scale()
.domain(d3.extent(reports, function(d) { return new Date(d.time) }))
.range([0, width])
var axis = d3.svg.axis()
.scale(timeScale)
.orient("top")
var dateFormat = d3.time.format("%m-%d %I:%M");
var xAxis = svg.append("g")
.classed("axis", true)
.attr("transform", "translate(" + [ cx, cy - 5 ] + ")")
axis(xAxis);
//start date
xAxis.append("text")
.text(dateFormat(new Date(reports[0].time)))
.attr("transform", "translate(" + [ width - 28, -22 ] + ")")
.style("font-weight", "bold")
.style("font-size", 12)
//start date
xAxis.append("text")
.text(dateFormat(new Date(reports[reports.length-1].time)))
.attr("transform", "translate(" + [ -32, -22 ] + ")")
.style("font-weight", "bold")
.style("font-size", 12)
var chart = d3.horizon()
.width(width)
.height(height)
.bands(5)
.height(height)
.mode("mirror")
.interpolate("step-after")
.colors(["#ded04e", "#ffffff", "#1a859c"]);
var g = svg.append("g")
.attr("transform", "translate(" + [ cx, cy ] +")")
g.append("rect")
.attr({
x: -1,
y: -1,
width: width + 2,
height: height + 2
})
g.datum(gl);
chart(g);
g.append("text")
.classed("label", true)
.text("Growbed Level")
.attr({ x: 2, y: 16 })
var frchart = d3.horizon()
.width(width)
.height(height/2)
.bands(5)
.height(height/2)
.mode("mirror")
.interpolate("step-after")
.colors(["#ded04e", "#ffffff", "#1a9c36"]);
var frg = svg.append("g")
.attr("transform", "translate(" + [ cx, 5 + cy + height ] +")")
frg.append("rect")
.attr({
x: -1,
y: -1,
width: width + 2,
height: height/2 + 2,
fill: "#ffffff",
stroke: "#000"
})
frg.datum(fr);
frchart(frg);
frg.append("text")
.classed("label", true)
.text("Flow Rate")
.attr({ x: 2, y: 16 })
var fschart = d3.horizon()
.width(width)
.height(height/2)
.bands(5)
.height(height/2)
.mode("mirror")
.interpolate("step-after")
.colors(["#000000", "#168732", "#ffffff"]);
var fsg = svg.append("g")
.attr("transform", "translate(" + [ cx, 10 + cy + height + height / 2 ] +")")
fsg.append("rect")
.attr({
x: -1,
y: -1,
width: width + 2,
height: height/2 + 2,
fill: "#009e0a",
stroke: "#000"
})
fsg.datum(fs);
fschart(fsg);
fsg.append("text")
.classed("label", true)
.text("Flow Switch")
.attr({ x: 2, y: 16 })
});
});
.label {
font-size: 24;
font-family: Helvetica;
fill: #000000;
}
.axis text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
}
#display {
background-color: #fff
}
#gif {
display: none;
}
#controls {
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment