// Javascript routines for interaction with SVG documents produced by
// gnuplot's SVG terminal driver.
// Find your root SVG element
var svg = document.querySelector('svg');
// Create an SVGPoint for future math
var pt = svg.createSVGPoint();
// Get point in global SVG space
function cursorPoint(evt){
pt.x = evt.clientX; pt.y = evt.clientY;
return pt.matrixTransform(svg.getScreenCTM().inverse());
}
var gnuplot_svg = { };
gnuplot_svg.version = "17 February 2017";
gnuplot_svg.SVGDoc = null;
gnuplot_svg.SVGRoot = null;
gnuplot_svg.Init = function(e)
{
gnuplot_svg.SVGDoc = e.target.ownerDocument;
gnuplot_svg.SVGRoot = gnuplot_svg.SVGDoc.documentElement;
gnuplot_svg.axisdate = new Date();
}
gnuplot_svg.toggleVisibility = function(evt, targetId)
{
var newTarget = evt.target;
if (targetId)
newTarget = gnuplot_svg.SVGDoc.getElementById(targetId);
var newValue = newTarget.getAttributeNS(null, 'visibility')
if ('hidden' != newValue)
newValue = 'hidden';
else
newValue = 'visible';
newTarget.setAttributeNS(null, 'visibility', newValue);
if (targetId) {
newTarget = gnuplot_svg.SVGDoc.getElementById(targetId.concat("_keyentry"));
if (newTarget)
newTarget.setAttributeNS(null, 'style',
newValue == 'hidden' ? 'filter:url(#greybox)' : 'none');
}
evt.preventDefault();
evt.stopPropagation();
}
// Mouse tracking echos coordinates to a floating text box
gnuplot_svg.getText = function() {
return(document.getElementById("coord_text"));
}
gnuplot_svg.updateCoordBox = function(t, evt) {
/*
* Apply screen CTM transformation to the evt screenX and screenY to get
* coordinates in SVG coordinate space. Use scaling parameters stored in
* the plot document by gnuplot to convert further into plot coordinates.
* Then position the floating text box using the SVG coordinates.
*/
var m = document.documentElement.getScreenCTM();
var p = document.documentElement.createSVGPoint();
var loc = cursorPoint(evt);
p.x = loc.x;
p.y = loc.y;
var label_x, label_y;
// Allow for scrollbar position (Firefox, others?)
if (typeof evt.pageX != 'undefined') {
p.x = evt.pageX; p.y = evt.pageY;
}
t.setAttribute("x", p.x);
t.setAttribute("y", p.y);
var plotcoord = gnuplot_svg.mouse2plot(p.x,p.y);
if (gnuplot_svg.plot_timeaxis_x == "DMS" || gnuplot_svg.plot_timeaxis_y == "DMS") {
if (gnuplot_svg.plot_timeaxis_x == "DMS")
label_x = gnuplot_svg.convert_to_DMS(x);
else
label_x = plotcoord.x.toFixed(2);
if (gnuplot_svg.plot_timeaxis_y == "DMS")
label_y = gnuplot_svg.convert_to_DMS(y);
else
label_y = plotcoord.y.toFixed(2);
} else if (gnuplot_svg.polar_mode) {
polar = gnuplot_svg.convert_to_polar(plotcoord.x,plotcoord.y);
label_x = "ang= " + polar.ang.toPrecision(4);
label_y = "R= " + polar.r.toPrecision(4);
} else if (gnuplot_svg.plot_timeaxis_x == "Date") {
gnuplot_svg.axisdate.setTime(1000. * plotcoord.x);
var year = gnuplot_svg.axisdate.getUTCFullYear();
var month = gnuplot_svg.axisdate.getUTCMonth();
var date = gnuplot_svg.axisdate.getUTCDate();
label_x = (" " + date).slice (-2) + "/"
+ ("0" + (month+1)).slice (-2) + "/"
+ year;
label_y = plotcoord.y.toFixed(2);
} else if (gnuplot_svg.plot_timeaxis_x == "Time") {
gnuplot_svg.axisdate.setTime(1000. * plotcoord.x);
var hour = gnuplot_svg.axisdate.getUTCHours();
var minute = gnuplot_svg.axisdate.getUTCMinutes();
var second = gnuplot_svg.axisdate.getUTCSeconds();
label_x = ("0" + hour).slice (-2) + ":"
+ ("0" + minute).slice (-2) + ":"
+ ("0" + second).slice (-2);
label_y = plotcoord.y.toFixed(2);
} else if (gnuplot_svg.plot_timeaxis_x == "DateTime") {
gnuplot_svg.axisdate.setTime(1000. * plotcoord.x);
label_x = gnuplot_svg.axisdate.toUTCString();
label_y = plotcoord.y.toFixed(2);
} else {
label_x = plotcoord.x.toFixed(2);
label_y = plotcoord.y.toFixed(2);
}
while (null != t.firstChild) {
t.removeChild(t.firstChild);
}
var textNode = document.createTextNode(". "+label_x+" "+label_y);
t.appendChild(textNode);
}
gnuplot_svg.showCoordBox = function(evt) {
var t = gnuplot_svg.getText();
if (null != t) {
t.setAttribute("visibility", "visible");
gnuplot_svg.updateCoordBox(t, evt);
}
}
gnuplot_svg.moveCoordBox = function(evt) {
var t = gnuplot_svg.getText();
if (null != t)
gnuplot_svg.updateCoordBox(t, evt);
}
gnuplot_svg.hideCoordBox = function(evt) {
var t = gnuplot_svg.getText();
if (null != t)
t.setAttribute("visibility", "hidden");
}
gnuplot_svg.toggleCoordBox = function(evt) {
var t = gnuplot_svg.getText();
if (null != t) {
var state = t.getAttribute('visibility');
if ('hidden' != state)
state = 'hidden';
else
state = 'visible';
t.setAttribute('visibility', state);
}
}
gnuplot_svg.toggleGrid = function() {
if (!gnuplot_svg.SVGDoc.getElementsByClassName) // Old browsers
return;
var grid = gnuplot_svg.SVGDoc.getElementsByClassName('gridline');
for (var i=0; i<grid.length; i++) {
var state = grid[i].getAttribute('visibility');
grid[i].setAttribute('visibility', (state == 'hidden') ? 'visible' : 'hidden');
}
}
gnuplot_svg.showHypertext = function(evt, mouseovertext)
{
var lines = mouseovertext.split('\n');
// If text starts with "image:" process it as an xlinked bitmap
if (lines[0].substring(0,5) == "image") {
var nameindex = lines[0].indexOf(":");
if (nameindex > 0) {
gnuplot_svg.showHyperimage(evt, lines[0]);
lines[0] = lines[0].slice(nameindex+1);
}
}
var loc = cursorPoint(evt);
var anchor_x = loc.x;
var anchor_y = loc.y;
var hypertextbox = document.getElementById("hypertextbox")
hypertextbox.setAttributeNS(null,"x",anchor_x+10);
hypertextbox.setAttributeNS(null,"y",anchor_y+4);
hypertextbox.setAttributeNS(null,"visibility","visible");
var hypertext = document.getElementById("hypertext")
hypertext.setAttributeNS(null,"x",anchor_x+14);
hypertext.setAttributeNS(null,"y",anchor_y+18);
hypertext.setAttributeNS(null,"visibility","visible");
var height = 2+16*lines.length;
hypertextbox.setAttributeNS(null,"height",height);
var length = hypertext.getComputedTextLength();
hypertextbox.setAttributeNS(null,"width",length+8);
// bounce off frame bottom
if (anchor_y > gnuplot_svg.plot_ybot + 16 - height) {
anchor_y -= height;
hypertextbox.setAttributeNS(null,"y",anchor_y+4);
hypertext.setAttributeNS(null,"y",anchor_y+18);
}
while (null != hypertext.firstChild) {
hypertext.removeChild(hypertext.firstChild);
}
var textNode = document.createTextNode(lines[0]);
if (lines.length <= 1) {
hypertext.appendChild(textNode);
} else {
xmlns="http://www.w3.org/2000/svg";
var tspan_element = document.createElementNS(xmlns, "tspan");
tspan_element.appendChild(textNode);
hypertext.appendChild(tspan_element);
length = tspan_element.getComputedTextLength();
var ll = length;
for (var l=1; l<lines.length; l++) {
var tspan_element = document.createElementNS(xmlns, "tspan");
tspan_element.setAttributeNS(null,"dy", 16);
textNode = document.createTextNode(lines[l]);
tspan_element.appendChild(textNode);
hypertext.appendChild(tspan_element);
ll = tspan_element.getComputedTextLength();
if (length < ll) length = ll;
}
hypertextbox.setAttributeNS(null,"width",length+8);
}
// bounce off right edge
if (anchor_x > gnuplot_svg.plot_xmax + 14 - length) {
anchor_x -= length;
hypertextbox.setAttributeNS(null,"x",anchor_x+10);
hypertext.setAttributeNS(null,"x",anchor_x+14);
}
// left-justify multiline text
var tspan_element = hypertext.firstChild;
while (tspan_element) {
tspan_element.setAttributeNS(null,"x",anchor_x+14);
tspan_element = tspan_element.nextElementSibling;
}
}
gnuplot_svg.hideHypertext = function ()
{
var hypertextbox = document.getElementById("hypertextbox")
var hypertext = document.getElementById("hypertext")
var hyperimage = document.getElementById("hyperimage")
hypertextbox.setAttributeNS(null,"visibility","hidden");
hypertext.setAttributeNS(null,"visibility","hidden");
hyperimage.setAttributeNS(null,"visibility","hidden");
}
gnuplot_svg.showHyperimage = function(evt, linktext)
{
var loc = cursorPoint(evt);
var anchor_x = loc.x;
var anchor_y = loc.y;
// Allow for scrollbar position (Firefox, others?)
if (typeof evt.pageX != 'undefined') {
anchor_x = evt.pageX; anchor_y = evt.pageY;
}
var hyperimage = document.getElementById("hyperimage")
hyperimage.setAttributeNS(null,"x",anchor_x);
hyperimage.setAttributeNS(null,"y",anchor_y);
hyperimage.setAttributeNS(null,"visibility","visible");
// Pick up height and width from "image(width,height):name"
var width = hyperimage.getAttributeNS(null,"width");
var height = hyperimage.getAttributeNS(null,"height");
if (linktext.charAt(5) == "(") {
width = parseInt(linktext.slice(6));
height = parseInt(linktext.slice(linktext.indexOf(",") + 1));
hyperimage.setAttributeNS(null,"width",width);
hyperimage.setAttributeNS(null,"height",height);
hyperimage.setAttributeNS(null,"preserveAspectRatio","none");
}
// bounce off frame bottom and right
if (anchor_y > gnuplot_svg.plot_ybot + 50 - height)
hyperimage.setAttributeNS(null,"y",20 + anchor_y-height);
if (anchor_x > gnuplot_svg.plot_xmax + 150 - width)
hyperimage.setAttributeNS(null,"x",10 + anchor_x-width);
// attach image URL as a link
linktext = linktext.slice(linktext.indexOf(":") + 1);
var xlinkns = "http://www.w3.org/1999/xlink";
hyperimage.setAttributeNS(xlinkns,"xlink:href",linktext);
}
// Convert from svg panel mouse coordinates to the coordinate
// system of the gnuplot figure
gnuplot_svg.mouse2plot = function(mousex,mousey) {
var plotcoord = new Object;
var plotx = mousex - gnuplot_svg.plot_xmin;
var ploty = mousey - gnuplot_svg.plot_ybot;
var x,y;
if (gnuplot_svg.plot_logaxis_x != 0) {
x = Math.log(gnuplot_svg.plot_axis_xmax)
- Math.log(gnuplot_svg.plot_axis_xmin);
x = x * (plotx / (gnuplot_svg.plot_xmax - gnuplot_svg.plot_xmin))
+ Math.log(gnuplot_svg.plot_axis_xmin);
x = Math.exp(x);
} else {
x = gnuplot_svg.plot_axis_xmin + (plotx / (gnuplot_svg.plot_xmax-gnuplot_svg.plot_xmin)) * (gnuplot_svg.plot_axis_xmax - gnuplot_svg.plot_axis_xmin);
}
if (gnuplot_svg.plot_logaxis_y != 0) {
y = Math.log(gnuplot_svg.plot_axis_ymax)
- Math.log(gnuplot_svg.plot_axis_ymin);
y = y * (ploty / (gnuplot_svg.plot_ytop - gnuplot_svg.plot_ybot))
+ Math.log(gnuplot_svg.plot_axis_ymin);
y = Math.exp(y);
} else {
y = gnuplot_svg.plot_axis_ymin + (ploty / (gnuplot_svg.plot_ytop-gnuplot_svg.plot_ybot)) * (gnuplot_svg.plot_axis_ymax - gnuplot_svg.plot_axis_ymin);
}
plotcoord.x = x;
plotcoord.y = y;
return plotcoord;
}
gnuplot_svg.convert_to_polar = function (x,y)
{
polar = new Object;
var phi, r;
phi = Math.atan2(y,x);
if (gnuplot_svg.plot_logaxis_r)
r = Math.exp( (x/Math.cos(phi) + Math.log(gnuplot_svg.plot_axis_rmin)/Math.LN10) * Math.LN10);
else if (gnuplot_svg.plot_axis_rmin > gnuplot_svg.plot_axis_rmax)
r = gnuplot_svg.plot_axis_rmin - x/Math.cos(phi);
else
r = gnuplot_svg.plot_axis_rmin + x/Math.cos(phi);
phi = phi * (180./Math.PI);
if (gnuplot_svg.polar_sense < 0)
phi = -phi;
if (gnuplot_svg.polar_theta0 != undefined)
phi = phi + gnuplot_svg.polar_theta0;
if (phi > 180.)
phi = phi - 360.;
polar.r = r;
polar.ang = phi;
return polar;
}
gnuplot_svg.convert_to_DMS = function (x)
{
var dms = {d:0, m:0, s:0};
var deg = Math.abs(x);
dms.d = Math.floor(deg);
dms.m = Math.floor((deg - dms.d) * 60.);
dms.s = Math.floor((deg - dms.d) * 3600. - dms.m * 60.);
fmt = ((x<0)?"-":" ")
+ dms.d.toFixed(0) + "°"
+ dms.m.toFixed(0) + "\""
+ dms.s.toFixed(0) + "'";
return fmt;
}