Node dragging works, no saving yet

master
James Gao 2014-11-01 13:15:19 -07:00
rodzic c678d10e56
commit fae13053ee
5 zmienionych plików z 114 dodań i 39 usunięć

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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++) {

Wyświetl plik

@ -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;

Wyświetl plik

@ -23,7 +23,6 @@
<![endif]-->
</head>
<body>
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
@ -61,8 +60,9 @@
<div class="row">
<div class="col-sm-8 col-md-8 row-space">
<svg id="graph" class="row-space"></svg>
<svg id="graph" class="row-space"></svg>
<div class="btn-group btn-group-justified row-space">
<div class="btn-group">
<button id="stop_button" type="button" class="btn btn-primary disabled"><span class="glyphicon glyphicon-stop"></span> Off</button>
@ -109,6 +109,22 @@
</div>
</div>
<div id='profile-node-info' class='panel panel-info'>
<div class='panel-heading name'>
Set point
</div>
<div class='panel-body'>
<div class="input-group input-group-sm row-space">
<span class="input-group-addon">Time</span>
<input type="text" class="form-control time">
</div>
<div class="input-group input-group-sm">
<span class="input-group-addon">Temp</span>
<input type="text" class="form-control temp">
</div>
</div>
</div>
</div> <!-- /container -->
<script src="js/jquery.min.js"></script>