(function() { var Plot, bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; $.event.special.removed = { remove: function(o) { if (o.handler) { return o.handler(); } } }; $.extend(WSClient.prototype.actions, { plot: function(data) { var target; target = this.__parent.check_target(data); this.__plots || (this.__plots = {}); if (this.__plots[data.id]) { return this.__plots[data.id].update(data); } else { return this.__plots[data.id] = new Plot(target, this.__parent, data); } } }); $(document).ready(function() { return Plot.prototype.default_options = { color: $('#plot-style').css("color"), replace: true, size: 1.0, orientation: 'vertical', xscale: 1.0, yscale: 1.0, tick_height: 15, number_of_ticks: 10, tick_color: $("#plot-style > .tickmarks").css("color"), tick_precision: 2, id: "spec0", draw_zero: true, fill_color: null, draw_line: true, draw_marker: false, marker_color: $("#plot-style > .markers").css("color"), ystart: 'min', fill: false, fill_color: $('#plot-style').css("background-color"), zero_color: $('#plot-style > .zero').css("color") }; }); Plot = (function() { Plot.prototype.parse_property = function(prop) { return parseInt(prop.slice(0, -1)); }; Plot.prototype.move_zoom = function(event) { this.zoom_box.width = event.pageX - this.zoom_box.left; this.zoom_box.height = event.pageY - this.zoom_box.top; this.zoom_element.css("width", "" + (Math.abs(this.zoom_box.width))); this.zoom_element.css("height", "" + (Math.abs(this.zoom_box.height))); if (this.zoom_box.width < 0) { this.zoom_element.css("left", event.pageX); } if (this.zoom_box.height < 0) { return this.zoom_element.css("top", event.pageY); } }; Plot.prototype.mousemove = function(event) { var mouse_x_value, mouse_y_value, relative_x_pos, relative_y_pos; this.mouse_element.removeClass("hidden"); this.canvas.focus(); relative_x_pos = (event.pageX - this.canvas.offset().left) / this.plot_width; relative_y_pos = 1.0 - ((event.pageY - this.canvas.offset().top) / this.plot_height); this.mouse_element.css("left", (event.pageX + 15) + "px"); this.mouse_element.css("top", (event.pageY + 15) + "px"); mouse_x_value = relative_x_pos * this.xscaled_end_value + (1.0 - relative_x_pos) * this.xscaled_start_value; mouse_x_value = mouse_x_value * this.xvalue_scale; mouse_y_value = relative_y_pos * this.yscaled_end_value + (1.0 - relative_y_pos) * this.yscaled_start_value; this.mouse_element.text((mouse_x_value.toFixed(2)) + ", " + (mouse_y_value.toFixed(2))); if (this.mouse_is_down) { return this.move_zoom(event); } }; Plot.prototype.mousedown = function(event) { if (!this.mouse_is_down) { this.zoom_box || (this.zoom_box = {}); this.zoom_box.left = event.pageX; this.zoom_box.top = event.pageY; this.zoom_element.css("left", event.pageX); this.zoom_element.css("top", event.pageY); this.zoom_element.css("width", 0); this.zoom_element.css("height", 0); this.zoom_element.removeClass("hidden"); return this.mouse_is_down = true; } }; Plot.prototype.mouseup = function(event) { var relative_xend_pos, relative_xstart_pos, relative_yend_pos, relative_ystart_pos, zoom_height, zoom_width, zoom_xend_pixel, zoom_xend_value, zoom_xstart_pixel, zoom_xstart_value, zoom_yend_pixel, zoom_yend_value, zoom_ystart_pixel, zoom_ystart_value; this.mouse_is_down = false; this.zoom_element.addClass("hidden"); zoom_width = this.parse_property(this.zoom_element.css("width")); zoom_xstart_pixel = this.parse_property(this.zoom_element.css("left")) - this.canvas.offset().left; zoom_xend_pixel = zoom_xstart_pixel + zoom_width; relative_xstart_pos = zoom_xstart_pixel / this.plot_width; relative_xend_pos = zoom_xend_pixel / this.plot_width; zoom_xstart_value = relative_xstart_pos * this.xscaled_end_value + (1.0 - relative_xstart_pos) * this.xscaled_start_value; zoom_xend_value = relative_xend_pos * this.xscaled_end_value + (1.0 - relative_xend_pos) * this.xscaled_start_value; zoom_height = this.parse_property(this.zoom_element.css("height")); zoom_yend_pixel = this.parse_property(this.zoom_element.css("top")) - this.canvas.offset().top; zoom_ystart_pixel = zoom_yend_pixel + zoom_height; relative_ystart_pos = 1.0 - (zoom_ystart_pixel / this.plot_height); relative_yend_pos = 1.0 - (zoom_yend_pixel / this.plot_height); zoom_ystart_value = relative_ystart_pos * this.yscaled_end_value + (1.0 - relative_ystart_pos) * this.yscaled_start_value; zoom_yend_value = relative_yend_pos * this.yscaled_end_value + (1.0 - relative_yend_pos) * this.yscaled_start_value; return this.zoom_to(zoom_xstart_value, zoom_xend_value, zoom_ystart_value, zoom_yend_value); }; Plot.prototype.keypress = function(event) { switch (event.which) { case 114: case 97: this.zoom_to(this.xstart_value, this.xend_value, this.ystart_value, this.yend_value); return this.draw(this.data); } }; Plot.prototype.setup_hover = function() { this.zoom_element = $('#plot-zoombox'); if (this.zoom_element.size() === 0) { this.zoom_element = $('
'); $('body').append(this.zoom_element); } this.mouse_element = $('#plot-mouseover'); if (this.mouse_element.size() === 0) { this.mouse_element = $(''); $('body').append(this.mouse_element); } this.canvas.mousemove(this.mousemove); this.canvas.mouseout((function(_this) { return function(event) { return _this.mouse_element.addClass("hidden"); }; })(this)); this.canvas.mousedown(this.mousedown); this.canvas.mouseup(this.mouseup); this.canvas.keypress(this.keypress); return this.canvas.on('removed', (function(_this) { return function() { return _this.canvas.off(); }; })(this)); }; Plot.prototype.create_container = function() { this.container = $(""); return this.__parent.add(this.container, this.target, this.options); }; Plot.prototype.set_canvas_size = function() { this.container_width = this.container.width(); this.container_height = this.container.height(); this.canvas[0].width = this.canvas_width = this.container_width; this.canvas[0].height = this.canvas_height = this.container_height; return this.set_scale_values(); }; Plot.prototype.zoom_to = function(xscaled_start_value, xscaled_end_value, yscaled_start_value, yscaled_end_value) { this.xscaled_start_value = xscaled_start_value; this.xscaled_end_value = xscaled_end_value; this.yscaled_start_value = yscaled_start_value; this.yscaled_end_value = yscaled_end_value; return this.draw(this.data); }; Plot.prototype.set_scale_values = function() { this.xvalue_scale = this.options.xscale; this.xend_value = this.options.xend || (this.data.length - 1); this.xstart_value = this.options.xstart || 0; this.yvalue_scale = this.options.yscale; this.ystart_value = this.options.ystart || 0; if (this.ystart_value === 'min') { this.ystart_value = Math.min.apply(Math, this.data); } this.yend_value = this.options.yend || Math.max.apply(Math, this.data); this.plot_height = this.canvas_height - this.options.tick_height; this.plot_width = this.canvas_width; this.xscaled_start_value = this.xstart_value; this.xscaled_end_value = this.xend_value; this.yscaled_start_value = this.ystart_value; return this.yscaled_end_value = this.yend_value; }; Plot.prototype.y_value_to_pixel = function(y) { return this.plot_height - (y - this.yscaled_start_value) / (this.yscaled_end_value - this.yscaled_start_value) * this.plot_height; }; Plot.prototype.x_value_to_pixel = function(i) { return (i - this.xscaled_start_value) / (this.xscaled_end_value - this.xscaled_start_value) * this.plot_width; }; Plot.prototype.draw = function(data) { var i, j, ref; this.ctx.clearRect(0, 0, this.canvas_width, this.canvas_height); this.ctx.fillStyle = this.options.marker_color; this.ctx.strokeStyle = this.options.color; this.ctx.font = "8px Monospace"; this.ctx.textAlign = "center"; this.ctx.beginPath(); this.ctx.moveTo(this.x_value_to_pixel(0), this.y_value_to_pixel(data[0])); for (i = j = 1, ref = data.length - 1; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) { if (this.options.draw_line) { this.ctx.lineTo(this.x_value_to_pixel(i), this.y_value_to_pixel(data[i])); } if (this.options.draw_marker) { this.ctx.fillText("x", this.x_value_to_pixel(i), this.y_value_to_pixel(data[i])); } } this.ctx.moveTo(this.x_value_to_pixel(0), this.y_value_to_pixel(data[0])); this.ctx.closePath(); this.ctx.fillStyle = this.options.fill_color; if (this.options.fill_color && this.options.fill) { this.ctx.fill(); } this.ctx.stroke(); this.draw_ticks(); if (this.options.draw_zero) { return this.draw_zero(); } }; Plot.prototype.draw_ticks = function() { var i, j, number_of_ticks, pos, ref, tickEnd, tickStart, tickValue, tick_height; this.ctx.font = (this.options.tick_height - 3) + "px Monospace"; this.ctx.fillStyle = this.options.tick_color; this.ctx.strokeStyle = this.options.tick_color; this.ctx.textAlign = "center"; this.ctx.textBaseline = 'middle'; number_of_ticks = this.options.number_of_ticks + 1; tick_height = this.options.tick_height; for (i = j = 1, ref = number_of_ticks - 1; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) { this.ctx.beginPath(); pos = i * this.plot_width / number_of_ticks; this.ctx.moveTo(pos, this.plot_height + tick_height / 2); this.ctx.lineTo(pos, this.plot_height - tick_height); this.ctx.stroke(); tickStart = this.xscaled_start_value; tickEnd = this.xscaled_end_value; tickValue = i * 1.0 / number_of_ticks; tickValue = tickValue * tickEnd + (1.0 - tickValue) * tickStart; tickValue = tickValue * this.xvalue_scale; this.ctx.textAlign = 'start'; this.ctx.fillText("" + (tickValue.toFixed(this.options.tick_precision)), pos + 3, this.canvas_height - 3); } this.ctx.beginPath(); this.ctx.moveTo(0, this.plot_height); this.ctx.lineTo(this.canvas_width, this.plot_height); return this.ctx.stroke(); }; Plot.prototype.draw_zero = function() { this.ctx.strokeStyle = this.options.zero_color; this.ctx.beginPath(); this.ctx.moveTo(0, this.y_value_to_pixel(0)); this.ctx.lineTo(this.canvas_width, this.y_value_to_pixel(0)); return this.ctx.stroke(); }; Plot.prototype.update = function(data) { this.data = data.data; $.extend(this.options, data); return this.draw(data.data); }; function Plot(target1, __parent, input_options) { this.target = target1; this.__parent = __parent; this.input_options = input_options; this.keypress = bind(this.keypress, this); this.mouseup = bind(this.mouseup, this); this.mousedown = bind(this.mousedown, this); this.mousemove = bind(this.mousemove, this); this.move_zoom = bind(this.move_zoom, this); this.options = $.extend({}, this.default_options, this.input_options); this.id = this.options.id; this.data = this.options.data; this.container = this.target.find("#" + this.id); if (this.container.size() === 0) { this.create_container(); } this.canvas = this.container.find("canvas"); this.ctx = this.canvas[0].getContext("2d"); this.set_canvas_size(); this.setup_hover(); this.draw(this.data); } return Plot; })(); }).call(this);