/*
* $Id: gnuplot_mouse.js,v 1.7 2009/05/30 17:55:42 sfeam Exp $
*/
// Mousing code for use with gnuplot's 'canvas' terminal driver.
// The functions defined here assume that the javascript plot produced by
// gnuplot initializes the plot boundary and scaling parameters.
var mousex = 0;
var mousey = 0;
var plotx = 0;
var ploty = 0;
var scaled_x = 0;
var scaled_y = 0;
// These will be initialized by the gnuplot canvas-drawing function
var plot_xmin = 0;
var plot_xmax = 0;
var plot_ybot = 0;
var plot_ytop = 0;
var plot_width = 0
var plot_height = 0
var plot_term_ymax = 0;
var plot_axis_xmin = 0;
var plot_axis_xmax = 0;
var plot_axis_width = 0;
var plot_axis_height = 0;
var plot_axis_ymin = 0;
var plot_axis_ymax = 0;
var plot_axis_x2min = "none";
var plot_axis_y2min = "none";
var plot_logaxis_x = 0;
var plot_logaxis_y = 0;
var grid_lines = true;
var zoom_text = false;
// These are the equivalent parameters while zooming
var zoom_axis_xmin = 0;
var zoom_axis_xmax = 0;
var zoom_axis_ymin = 0;
var zoom_axis_ymax = 0;
var zoom_axis_x2min = 0;
var zoom_axis_x2max = 0;
var zoom_axis_y2min = 0;
var zoom_axis_y2max = 0;
var zoom_axis_width = 0;
var zoom_axis_height = 0;
var zoom_temp_xmin = 0;
var zoom_temp_ymin = 0;
var zoom_temp_x2min = 0;
var zoom_temp_y2min = 0;
var zoom_in_progress = false;
function gnuplot_init()
{
if (document.getElementById("gnuplot_canvas"))
document.getElementById("gnuplot_canvas").onmousemove = mouse_update;
if (document.getElementById("gnuplot_canvas"))
document.getElementById("gnuplot_canvas").onmouseup = zoom_in;
if (document.getElementById("gnuplot_canvas"))
document.getElementById("gnuplot_canvas").onmousedown = saveclick;
if (document.getElementById("gnuplot_canvas"))
document.getElementById("gnuplot_canvas").onkeypress = do_hotkey;
if (document.getElementById("gnuplot_grid_icon"))
document.getElementById("gnuplot_grid_icon").onmouseup = toggle_grid;
if (document.getElementById("gnuplot_textzoom_icon"))
document.getElementById("gnuplot_textzoom_icon").onmouseup = toggle_zoom_text;
if (document.getElementById("gnuplot_rezoom_icon"))
document.getElementById("gnuplot_rezoom_icon").onmouseup = rezoom;
if (document.getElementById("gnuplot_unzoom_icon"))
document.getElementById("gnuplot_unzoom_icon").onmouseup = unzoom;
mouse_update();
}
function getMouseCoordsWithinTarget(event)
{
var coords = { x: 0, y: 0};
if(!event) // then we're in a non-DOM (probably IE) browser
{
event = window.event;
if (event) {
coords.x = event.offsetX;
coords.y = event.offsetY;
}
}
else // we assume DOM modeled javascript
{
var Element = event.target ;
var CalculatedTotalOffsetLeft = 0;
var CalculatedTotalOffsetTop = 0 ;
while (Element.offsetParent)
{
CalculatedTotalOffsetLeft += Element.offsetLeft ;
CalculatedTotalOffsetTop += Element.offsetTop ;
Element = Element.offsetParent ;
}
coords.x = event.pageX - CalculatedTotalOffsetLeft ;
coords.y = event.pageY - CalculatedTotalOffsetTop ;
}
mousex = coords.x;
mousey = coords.y;
}
function mouse_update(e)
{
getMouseCoordsWithinTarget(e);
plotx = mousex - plot_xmin;
ploty = -(mousey - plot_ybot);
// Limit tracking to the interior of the plot
if (plotx < 0 || ploty < 0) return;
if (mousex > plot_xmax || mousey < plot_ytop) return;
var axis_xmin = (zoomed) ? zoom_axis_xmin : plot_axis_xmin;
var axis_xmax = (zoomed) ? zoom_axis_xmax : plot_axis_xmax;
var axis_ymin = (zoomed) ? zoom_axis_ymin : plot_axis_ymin;
var axis_ymax = (zoomed) ? zoom_axis_ymax : plot_axis_ymax;
if (plot_logaxis_x != 0) {
x = Math.log(axis_xmax) - Math.log(axis_xmin);
x = x * (plotx / (plot_xmax-plot_xmin)) + Math.log(axis_xmin);
x = Math.exp(x);
} else {
x = axis_xmin + (plotx / (plot_xmax-plot_xmin)) * (axis_xmax - axis_xmin);
}
if (plot_logaxis_y != 0) {
y = Math.log(axis_ymax) - Math.log(axis_ymin);
y = y * (-ploty / (plot_ytop-plot_ybot)) + Math.log(axis_ymin);
y = Math.exp(y);
} else {
y = axis_ymin - (ploty / (plot_ytop-plot_ybot)) * (axis_ymax - axis_ymin);
}
if (plot_axis_x2min != "none") {
axis_x2min = (zoomed) ? zoom_axis_x2min : plot_axis_x2min;
axis_x2max = (zoomed) ? zoom_axis_x2max : plot_axis_x2max;
x2 = axis_x2min + (plotx / (plot_xmax-plot_xmin)) * (axis_x2max - axis_x2min);
if (document.getElementById(active_plot_name + "_x2"))
document.getElementById(active_plot_name + "_x2").innerHTML = x2.toPrecision(4);
}
if (plot_axis_y2min != "none") {
axis_y2min = (zoomed) ? zoom_axis_y2min : plot_axis_y2min;
axis_y2max = (zoomed) ? zoom_axis_y2max : plot_axis_y2max;
y2 = axis_y2min - (ploty / (plot_ytop-plot_ybot)) * (axis_y2max - axis_y2min);
if (document.getElementById(active_plot_name + "_y2"))
document.getElementById(active_plot_name + "_y2").innerHTML = y2.toPrecision(4);
}
if (document.getElementById(active_plot_name + "_x"))
document.getElementById(active_plot_name + "_x").innerHTML = x.toPrecision(4);
if (document.getElementById(active_plot_name + "_y"))
document.getElementById(active_plot_name + "_y").innerHTML = y.toPrecision(4);
// Echo the zoom box interactively
if (zoom_in_progress) {
ctx.strokeStyle="rgba(128,128,128,0.20)";
ctx.strokeRect(
plot_xmin + zoom_temp_plotx, plot_ybot - zoom_temp_ploty,
plotx - zoom_temp_plotx, -(ploty - zoom_temp_ploty));
}
}
function saveclick(event)
{
mouse_update(event);
// Limit tracking to the interior of the plot
if (plotx < 0 || ploty < 0) return;
if (mousex > plot_xmax || mousey < plot_ytop) return;
if (event.which == null) /* IE case */
button= (event.button < 2) ? "LEFT" : ((event.button == 4) ? "MIDDLE" : "RIGHT");
else /* All others */
button= (event.which < 2) ? "LEFT" : ((event.which == 2) ? "MIDDLE" : "RIGHT");
if (button == "LEFT") {
ctx.strokeStyle="black";
ctx.strokeRect(mousex, mousey, 1, 1);
click = " " + x.toPrecision(4) + ", " + y.toPrecision(4);
ctx.drawText("sans", 9, mousex, mousey, click);
}
// Save starting corner of zoom box
else {
zoom_temp_xmin = x;
zoom_temp_ymin = y;
if (plot_axis_x2min != "none") zoom_temp_x2min = x2;
if (plot_axis_y2min != "none") zoom_temp_y2min = y2;
// Only used to echo the zoom box interactively
zoom_temp_plotx = plotx;
zoom_temp_ploty = ploty;
zoom_in_progress = true;
}
return false; // Nobody else should respond to this event
}
function zoom_in(event)
{
if (!zoom_in_progress)
return false;
mouse_update(event);
if (event.which == null) /* IE case */
button= (event.button < 2) ? "LEFT" : ((event.button == 4) ? "MIDDLE" : "RIGHT");
else /* All others */
button= (event.which < 2) ? "LEFT" : ((event.which == 2) ? "MIDDLE" : "RIGHT");
// Save ending corner of zoom box
if (button != "LEFT") {
if (x > zoom_temp_xmin) {
zoom_axis_xmin = zoom_temp_xmin;
zoom_axis_xmax = x;
if (plot_axis_x2min != "none") {
zoom_axis_x2min = zoom_temp_x2min;
zoom_axis_x2max = x2;
}
} else {
zoom_axis_xmin = x;
zoom_axis_xmax = zoom_temp_xmin;
if (plot_axis_x2min != "none") {
zoom_axis_x2min = x2;
zoom_axis_x2max = zoom_temp_x2min;
}
}
if (y > zoom_temp_ymin) {
zoom_axis_ymin = zoom_temp_ymin;
zoom_axis_ymax = y;
if (plot_axis_y2min != "none") {
zoom_axis_y2min = zoom_temp_y2min;
zoom_axis_y2max = y2;
}
} else {
zoom_axis_ymin = y;
zoom_axis_ymax = zoom_temp_ymin;
if (plot_axis_y2min != "none") {
zoom_axis_y2min = y2;
zoom_axis_y2max = zoom_temp_y2min;
}
}
zoom_axis_width = zoom_axis_xmax - zoom_axis_xmin;
zoom_axis_height = zoom_axis_ymax - zoom_axis_ymin;
zoom_in_progress = false;
rezoom(event);
}
return false; // Nobody else should respond to this event
}
function toggle_grid(e)
{
if (!grid_lines) grid_lines = true;
else grid_lines = false;
ctx.clearRect(0,0,plot_term_xmax,plot_term_ymax);
gnuplot_canvas();
}
function toggle_zoom_text(e)
{
if (!zoom_text) zoom_text = true;
else zoom_text = false;
ctx.clearRect(0,0,plot_term_xmax,plot_term_ymax);
gnuplot_canvas();
}
function rezoom(e)
{
if (zoom_axis_width > 0)
zoomed = true;
ctx.clearRect(0,0,plot_term_xmax,plot_term_ymax);
gnuplot_canvas();
}
function unzoom(e)
{
zoomed = false;
ctx.clearRect(0,0,plot_term_xmax,plot_term_ymax);
gnuplot_canvas();
}
function zoomXY(x,y)
{
zoom = new Object;
var xreal, yreal;
zoom.x = x; zoom.y = y; zoom.clip = false;
if (plot_logaxis_x != 0) {
xreal = Math.log(plot_axis_xmax) - Math.log(plot_axis_xmin);
xreal = Math.log(plot_axis_xmin) + (x - plot_xmin) * xreal/plot_width;
zoom.x = Math.log(zoom_axis_xmax) - Math.log(zoom_axis_xmin);
zoom.x = plot_xmin + (xreal - Math.log(zoom_axis_xmin)) * plot_width/zoom.x;
} else {
xreal = plot_axis_xmin + (x - plot_xmin) * (plot_axis_width/plot_width);
zoom.x = plot_xmin + (xreal - zoom_axis_xmin) * (plot_width/zoom_axis_width);
}
if (plot_logaxis_y != 0) {
yreal = Math.log(plot_axis_ymax) - Math.log(plot_axis_ymin);
yreal = Math.log(plot_axis_ymin) + (plot_ybot - y) * yreal/plot_height;
zoom.y = Math.log(zoom_axis_ymax) - Math.log(zoom_axis_ymin);
zoom.y = plot_ybot - (yreal - Math.log(zoom_axis_ymin)) * plot_height/zoom.y;
} else {
yreal = plot_axis_ymin + (plot_ybot - y) * (plot_axis_height/plot_height);
zoom.y = plot_ybot - (yreal - zoom_axis_ymin) * (plot_height/zoom_axis_height);
}
// Limit the zoomed plot to the original plot area
if (x > plot_xmax) {
zoom.x = x;
if (plot_axis_y2min == "none") {
zoom.y = y;
return zoom;
}
if (plot_ybot plot_ybot)
zoom.y = y;
else if (zoom.y > plot_ybot)
{ zoom.y = plot_ybot; zoom.clip = true; }
else if (zoom.y < plot_ytop)
{ zoom.y = plot_ytop; zoom.clip = true; }
return zoom;
}
function zoomW(w) { return (w*plot_axis_width/zoom_axis_width); }
function zoomH(h) { return (h*plot_axis_height/zoom_axis_height); }
function do_hotkey(event) {
keychar = String.fromCharCode(event.charCode ? event.charCode : event.keyCode);
switch (keychar) {
case 'e': ctx.clearRect(0,0,plot_term_xmax,plot_term_ymax);
gnuplot_canvas();
break;
case 'g': toggle_grid();
break;
case 'n': rezoom();
break;
case 'r':
ctx.lineWidth = 0.5;
ctx.strokeStyle="rgba(128,128,128,0.50)";
ctx.moveTo(plot_xmin, mousey); ctx.lineTo(plot_xmax, mousey);
ctx.moveTo(mousex, plot_ybot); ctx.lineTo(mousex, plot_ytop);
ctx.stroke();
break;
case 'p':
case 'u': unzoom();
break;
case '': zoom_in_progress = false;
break;
// Arrow keys
case '%': // ctx.drawText("sans", 10, mousex, mousey, "");
break;
case '&': // ctx.drawText("sans", 10, mousex, mousey, "^");
break;
case '(': // ctx.drawText("sans", 10, mousex, mousey, "v");
break;
default: // ctx.drawText("sans", 10, mousex, mousey, keychar);
return true; // Let someone else handle it
break;
}
return false; // Nobody else should respond to this keypress
}