From fae13053ee5e193194052e4ee6a29587590e2c85 Mon Sep 17 00:00:00 2001 From: James Gao Date: Sat, 1 Nov 2014 13:15:19 -0700 Subject: [PATCH] Node dragging works, no saving yet --- kiln/static/css/temp_monitor.css | 9 +++++- kiln/static/js/temp_graph.js | 21 ++++++++---- kiln/static/js/temp_monitor.js | 48 +++++++++++++--------------- kiln/static/js/temp_profile.js | 55 +++++++++++++++++++++++++++++--- kiln/templates/main.html | 20 ++++++++++-- 5 files changed, 114 insertions(+), 39 deletions(-) diff --git a/kiln/static/css/temp_monitor.css b/kiln/static/css/temp_monitor.css index 17bbc92..64ce86c 100644 --- a/kiln/static/css/temp_monitor.css +++ b/kiln/static/css/temp_monitor.css @@ -52,5 +52,12 @@ body { stroke-width:1px; } .profile-line.dot:hover { - stroke-width:5px; + stroke-width:3px; +} + +#profile-node-info { + float:left; + position:absolute; + display:none; + width:200px; } \ No newline at end of file diff --git a/kiln/static/js/temp_graph.js b/kiln/static/js/temp_graph.js index 987d176..5caa048 100644 --- a/kiln/static/js/temp_graph.js +++ b/kiln/static/js/temp_graph.js @@ -34,8 +34,8 @@ var tempgraph = (function(module) { this.x = d3.time.scale().range([0, this.width]); this.y = d3.scale.linear().range([this.height, 0]); - this.zoom = d3.behavior.zoom().on("zoom", this.draw.bind(this)) - .on("zoomend", this.recenter.bind(this)); + this.zoom = d3.behavior.zoom(this.obj).on("zoom", this.draw.bind(this)) + .on("zoomend", this.recenter.bind(this, .2)); if (options.show_axes === undefined || options.show_axes) { this.x_axis = d3.svg.axis().scale(this.x).orient("bottom") @@ -71,7 +71,6 @@ var tempgraph = (function(module) { }; module.Graph.prototype.plot = function(data, className, marker) { this.x.domain(d3.extent(data, function(d) { return d.x; })); - this.y.domain(d3.extent(data, function(d) { return d.y; })); this.zoom.x(this.x); var line = d3.svg.line() @@ -97,7 +96,8 @@ var tempgraph = (function(module) { this.lines[className] = {line:line, data:data, marker:marker}; this.svg.call(this.zoom); this.draw(); - return line; + this.recenter(.2); + return this.lines[className]; } module.Graph.prototype.draw = function() { this.svg.select("g.x.axis").call(this.x_axis); @@ -130,15 +130,24 @@ var tempgraph = (function(module) { this.height = height; this.draw(); } - module.Graph.prototype.recenter = function() { + module.Graph.prototype.recenter = function(margin) { + //Argument margin gives the fraction of (max - min) to add to the margin + //Defaults to 0 var extent = [], data, valid, low = this.x.domain()[0], high=this.x.domain()[1]; + for (var name in this.lines) { data = this.lines[name].data; valid = data.filter(function(d) { return low <= d.x && d.x <= high; }) extent = extent.concat(valid); } - this.y.domain(d3.extent(extent, function(d) {return d.y;})); + extent = d3.extent(extent, function(d){return d.y}); + if (margin > 0) { + var range = extent[1]-extent[0]; + extent[0] -= margin*range; + extent[1] += margin*range; + } + this.y.domain(extent); this.draw(); } module.Graph.prototype.update = function(className, data) { diff --git a/kiln/static/js/temp_monitor.js b/kiln/static/js/temp_monitor.js index 73a693d..b89f64c 100644 --- a/kiln/static/js/temp_monitor.js +++ b/kiln/static/js/temp_monitor.js @@ -3,9 +3,7 @@ var tempgraph = (function(module) { this.temperature = initial; this.profile = null; //default to F - this.scalefunc = module.temp_to_F; - this.temp_suffix = "°F" - this.temp_prefix = "" + this.scalefunc = new module.TempScale("F"); this.graph = new module.Graph(); this._mapped = this.temperature.map(this._map_temp.bind(this)); @@ -16,13 +14,11 @@ var tempgraph = (function(module) { } module.Monitor.prototype.updateTemp = function(data) { var now = new Date(data.time*1000.); - var temp = this.scalefunc(data.temp); + var temp = this.scalefunc.scale(data.temp); var nowstr = module.format_time(now); - - var tempstr = Math.round(temp*100) / 100; $("#current_time").text(nowstr); - $("#current_temp").text(this.temp_prefix+tempstr+this.temp_suffix); + $("#current_temp").text(this.scalefunc.print(Math.round(temp*100) / 100)); if (this.profile) { var finish = module.format_time(this.profile.time_finish(now)); @@ -42,11 +38,9 @@ var tempgraph = (function(module) { } //If incoming sample is higher or lower than the ylims, expand that as well - var ylims = this.graph.y.domain(), range = 2*(ylims[1] - ylims[0]); - if (temp >= ylims[1]) { - this.graph.y.domain([ylims[0], ylims[0]+range]); - } else if (temp <= ylims[0]) { - this.graph.y.domain([ylims[1]-range, ylims[1]]); + var ylims = this.graph.y.domain(); + if (temp >= ylims[1] || temp <= ylims[0]) { + this.graph.recenter(.2); } this.graph.update("temperature", this._mapped); } @@ -86,22 +80,16 @@ var tempgraph = (function(module) { $("a#temp_scale_cone").parent().removeClass("active"); if (scale == "C") { $("li a#temp_scale_C").parent().addClass("active"); - this.scalefunc = module.temp_to_C; + this.scalefunc = new module.TempScale("C"); this.graph.ylabel("Temperature (°C)") - this.temp_suffix = "°C"; - this.temp_prefix = ""; } else if (scale == "F") { $("li a#temp_scale_F").parent().addClass("active"); - this.scalefunc = module.temp_to_F; + this.scalefunc = new module.TempScale("F"); this.graph.ylabel("Temperature (°F)") - this.temp_suffix = "°F"; - this.temp_prefix = ""; } else if (scale == "cone") { $("li a#temp_scale_cone").parent().addClass("active"); - this.scalefunc = module.temp_to_cone; + this.scalefunc = new module.TempScale("cone"); this.graph.ylabel("Temperature (Δ)"); - this.temp_prefix = "Δ"; - this.temp_suffix = ""; } this._mapped = this.temperature.map(this._map_temp.bind(this)); this.graph.y.domain(d3.extent(this._mapped, function(d) { return d.y; })); @@ -113,7 +101,7 @@ var tempgraph = (function(module) { } module.Monitor.prototype._map_temp = function(d) { - return {x:new Date(d.time*1000), y:this.scalefunc(d.temp)}; + return {x:new Date(d.time*1000), y:this.scalefunc.scale(d.temp)}; } module.Monitor.prototype.setState = function(name) { @@ -193,11 +181,19 @@ var tempgraph = (function(module) { $("input").attr("disabled", "disabled"); } - module.temp_to_C = function(temp) { return temp; } - module.temp_to_F = function(temp) { - return temp * 9 / 5 + 32; + + module.TempScale = function(name) { + if (name == "C") { + this.scale = function(t) { return t;}; + this.inverse = function(t) { return t;}; + this.print = function(t) { return t+"°C"} + } else if (name == "F") { + this.scale = function(temp) { return temp * 9 / 5 + 32; } + this.inverse = function(temp) { return (temp - 32) * 5 / 9;} + this.print = function(t) { return t+"°F"} + } } - module.temp_to_cone = function(temp) { + module.TempScale.C_to_cone = function(temp) { var cones = [600,614,635,683,717,747,792,804,838,852,884,894,900,923,955,984,999,1046,1060,1101,1120,1137,1154,1162,1168,1186,1196,1222,1240,1263,1280,1305,1315,1326,1346] var names = []; for (var i = -22; i < 0; i++) { diff --git a/kiln/static/js/temp_profile.js b/kiln/static/js/temp_profile.js index 1b23d06..f06c73c 100644 --- a/kiln/static/js/temp_profile.js +++ b/kiln/static/js/temp_profile.js @@ -25,6 +25,7 @@ var tempgraph = (function(module) { module.Profile.prototype.setScale = function(scale) { this.scalefunc = scale; + this.update(); } module.Profile.prototype.setupGraph = function() { //immediately view range from 10 min before to end time of profile @@ -37,16 +38,35 @@ var tempgraph = (function(module) { .attr("class", "profile-pane") .attr("height", this.graph.height) - this.graph.zoom.on("zoom.profile", this.update.bind(this)); this.line = this.graph.plot(this._schedule(), "profile-line", true); this.update(); + + //events + this.drag = d3.behavior.drag().origin(function(d) { + return {x:this.graph.x(d.x), y:this.graph.y(d.y)}; + }.bind(this)).on("dragstart", function(d) { + d3.event.sourceEvent.stopPropagation(); + this._node = this._findNode(d); + }.bind(this)).on("drag", this.dragNode.bind(this)); + this.line.marker.call(this.drag); + + var hide_info = function() { + this.hide_timeout = setTimeout(function() { $("#profile-node-info").hide(); }, 250); + }; + this.graph.zoom.on("zoom.profile", this.update.bind(this)); + this.line.marker.on("mouseover", this.hoverNode.bind(this)); + this.line.marker.on("mouseout", hide_info.bind(this)); + $("#profile-node-info").on("mouseout.profile", hide_info.bind(this)); + $("#profile-node-info").on("mouseover.profile", function() { + clearTimeout(this.hide_timeout); + }.bind(this)); } module.Profile.prototype._schedule = function() { var start_time = this.time_start instanceof Date ? this.time_start : new Date(); var schedule = []; for (var i = 0; i < this.schedule.length; i++) { var time = new Date(start_time.getTime() + this.schedule[i][0]*1000); - var temp = this.scalefunc(this.schedule[i][1]); + var temp = this.scalefunc.scale(this.schedule[i][1]); schedule.push({x:time, y:temp}); } return schedule; @@ -64,15 +84,42 @@ var tempgraph = (function(module) { this.scalefunc = scale; this.update(); } - + module.Profile.prototype._findNode = function(d) { + var time, temp, + start_time = this.time_start instanceof Date ? this.time_start : new Date(); + for (var i = 0; i < this.schedule.length; i++) { + time = new Date((start_time.getTime() + this.schedule[i][0]*1000)); + temp = this.schedule[i][1]; + //if time is within 10 seconds and temperature matches exactly + if ((time - d.x) < 10000 && d.y == this.scalefunc.scale(temp)) + return i; + } + } module.Profile.prototype.addNode = function() { } module.Profile.prototype.delNode = function() { } - module.Profile.prototype.dragNode = function() { + module.Profile.prototype.dragNode = function(d) { + var time = this.graph.x.invert(d3.event.x); + var temp = this.graph.y.invert(d3.event.y); + var start_time = this.time_start instanceof Date ? this.time_start : new Date(); + this.schedule[this._node][0] = (time - start_time) / 1000; + this.schedule[this._node][1] = this.scalefunc.inverse(temp); + this.update(); + } + module.Profile.prototype.hoverNode = function(d) { + clearTimeout(this.hide_timeout); + var node = this._findNode(d); + $("#profile-node-info") + .css('left', this.graph.x(d.x)+80) + .css('top', this.graph.y(d.y)+50) + .show(); + $("#profile-node-info div.name").text("Set point "+(node+1)); + $("#profile-node-info input.temp").val(this.scalefunc.scale(this.schedule[node][1])); + $("#profile-node-info input.time"); } return module; diff --git a/kiln/templates/main.html b/kiln/templates/main.html index b03996d..1b94660 100644 --- a/kiln/templates/main.html +++ b/kiln/templates/main.html @@ -23,7 +23,6 @@ -