Edit file File name : gnuplot_svg_2018.js Content :// Javascript routines for mouse and keyboard interaction with // SVG documents produced by gnuplot 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 = "04 March 2018"; gnuplot_svg.SVGDoc = null; gnuplot_svg.SVGRoot = null; gnuplot_svg.Init = function (e) { gnuplot_svg.SVGDoc = e.target.ownerDocument; // unused gnuplot_svg.SVGRoot = gnuplot_svg.SVGDoc.documentElement; gnuplot_svg.axisdate = new Date(); // zoom and pan with mouse gnuplot_svg.interactive = gnuplot_svg.interactiveInit(e.target); }; 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 = svg.getScreenCTM(); var p = svg.createSVGPoint(); var loc = cursorPoint(evt); p.x = loc.x; p.y = loc.y; var label_x, label_y; t.setAttribute("x", p.x); t.setAttribute("y", p.y); var plotcoord = gnuplot_svg.mouse2plot(p.x, p.y); if (isNaN(plotcoord.x) || isNaN(plotcoord.y)) { // nonlinear axis or custom function mapping [x,y] to plot coordinates label_x = "not "; label_y = "supported"; } else 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 = gnuplot_svg.SVGDoc.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]); var tspan_element; if (lines.length <= 1) { hypertext.appendChild(textNode); } else { xmlns = "http://www.w3.org/2000/svg"; 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++) { 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 tspan_element = hypertext.firstChild; while (tspan_element) { if (tspan_element.setAttributeNS) { 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; 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 = {}; var plotx = mousex - gnuplot_svg.plot_xmin; var ploty = mousey - gnuplot_svg.plot_ybot; var x, y; if (gnuplot_svg.plot_logaxis_x < 0) { // nonlinear axis or custom mapping function x = NaN; } else 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 = NaN; } else 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 = {}; 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; }; gnuplot_svg.interactiveInit = function (svgElement) { var dragOffset = {'x' : 0, 'y' : 0}; var dragChange = svgElement.createSVGPoint(); var dragTimeout = null; var dragEnabled = false; var getViewBox = function () { var viewBoxValues = svgElement.getAttribute('viewBox').split(' '); viewBoxValues[0] = parseFloat(viewBoxValues[0]); viewBoxValues[1] = parseFloat(viewBoxValues[1]); viewBoxValues[2] = parseFloat(viewBoxValues[2]); viewBoxValues[3] = parseFloat(viewBoxValues[3]); return viewBoxValues; }; var setViewBox = function (viewBoxValues) { svgElement.setAttribute('viewBox', viewBoxValues.join(' ')); }; var zoom = function (direction) { var zoomRate = 1.1; var viewBoxValues = getViewBox(); var widthBefore = viewBoxValues[2]; var heightBefore = viewBoxValues[3]; if (direction == 'in') { viewBoxValues[2] /= zoomRate; viewBoxValues[3] /= zoomRate; // Pan to center viewBoxValues[0] -= (viewBoxValues[2] - widthBefore) / 2; viewBoxValues[1] -= (viewBoxValues[3] - heightBefore) / 2; } else if (direction == 'out') { viewBoxValues[2] *= zoomRate; viewBoxValues[3] *= zoomRate; // Pan to center viewBoxValues[0] += (widthBefore - viewBoxValues[2]) / 2; viewBoxValues[1] += (heightBefore - viewBoxValues[3]) / 2; } return viewBoxValues; }; var pan = function (direction) { var panRate = 10; var viewBoxValues = getViewBox(); switch (direction) { case 'left': viewBoxValues[0] += panRate; break; case 'right': viewBoxValues[0] -= panRate; break; case 'up': viewBoxValues[1] += panRate; break; case 'down': viewBoxValues[1] -= panRate; break; } return viewBoxValues; }; // viewBox initial position and size var resetValue = getViewBox(); // Keyboard actions, old svg version not support key events so must listen window window.addEventListener('keydown', function (evt) { // Not capture event from inputs // body = svg inline in page, svg = plain svg file, window = delegated events to object if (evt.target.nodeName != 'BODY' && evt.target.nodeName != 'svg' && evt.target != window) { return true; } var viewBoxValues = []; switch (evt.key) { // Move, Edge sends without Arrow word case 'ArrowLeft': case 'Left': case 'ArrowRight': case 'Right': case 'ArrowUp': case 'Up': case 'ArrowDown': case 'Down': viewBoxValues = pan(evt.key.replace('Arrow', '').toLowerCase()); break; // Zoom in case '+': case 'Add': viewBoxValues = zoom('in'); break; // Zoom out case '-': case 'Subtract': viewBoxValues = zoom('out'); break; // Reset case 'Home': viewBoxValues = resetValue; break; // Toggle grid case '#': gnuplot_svg.toggleGrid(); break; } if (viewBoxValues.length) { setViewBox(viewBoxValues); } }); // Set focusable for event focusing, not work on old svg version svgElement.setAttribute('focusable', true); // Disable native draggable svgElement.setAttribute('draggable', false); // Save move relative start position svgElement.addEventListener('mousedown', function (evt) { dragOffset = {'x' : evt.clientX, 'y' : evt.clientY}; // Delay for moving, so not move accidentally if only click dragTimeout = setTimeout(function () { dragEnabled = true; }, 250); // Cancel draggable evt.stopPropagation(); evt.preventDefault(); return false; }); svgElement.addEventListener('mouseup', function (evt) { dragEnabled = false; clearTimeout(dragTimeout); }); // Mouse move svgElement.addEventListener('mousemove', function (evt) { if (evt.buttons == 1 && dragEnabled) { // Position change dragChange.x = evt.clientX - dragOffset.x; dragChange.y = evt.clientY - dragOffset.y; // Set current mouse position dragOffset.x = evt.clientX; dragOffset.y = evt.clientY; dragChange.matrixTransform(svgElement.getScreenCTM().inverse()); var viewBoxValues = getViewBox(); viewBoxValues[0] -= dragChange.x; viewBoxValues[1] -= dragChange.y; setViewBox(viewBoxValues); } }); // Zoom with wheel svgElement.addEventListener('wheel', function (evt) { // x or y scroll zoom both axels var delta = Math.max(-1, Math.min(1, (evt.deltaY || evt.deltaX))); if (delta > 0) { setViewBox(zoom('in')); } else { setViewBox(zoom('out')); } // Disable scroll the entire webpage evt.stopPropagation(); evt.preventDefault(); return false; }); // Reset on right click or hold tap svgElement.addEventListener('contextmenu', function (evt) { setViewBox(resetValue); // Disable native context menu evt.stopPropagation(); evt.preventDefault(); return false; }); // Return functions to outside use return { zoom: function (direction) { setViewBox(zoom(direction)); return this; }, pan: function (direction) { setViewBox(pan(direction)); return this; }, reset: function () { setViewBox(resetValue); return this; } }; }; Save