Is it possible to have a gnuplot plot in wxFrame window.
Is it possible to have a gnuplot plot in wxFrame window.
Hello All,
I'm currently learning how to use wxWidgets and GUI programming in general with Code:Blocks and have some programs in mind that would need to display 2D and 3D plots in a window. Does anyone know how to embed a gnuplot plot/graph within a frame window in a similar way to how I've seen openGL windows displayed in wxWidgets? If so, is there any sample code so that I can use learn how to do this? I'd be grateful for any advice. Thank you.
I'm currently learning how to use wxWidgets and GUI programming in general with Code:Blocks and have some programs in mind that would need to display 2D and 3D plots in a window. Does anyone know how to embed a gnuplot plot/graph within a frame window in a similar way to how I've seen openGL windows displayed in wxWidgets? If so, is there any sample code so that I can use learn how to do this? I'd be grateful for any advice. Thank you.
-
- Super wx Problem Solver
- Posts: 466
- Joined: Tue Jun 20, 2006 6:47 pm
- Contact:
Re: Is it possible to have a gnuplot plot in wxFrame window.
I posted some wrong information before. If anyone saw this post before this edit, please disregard what I write earlier. I don't think there is a way to embed an interactive terminal.
However, on X11 you can redirect to plot output to a window So for example, with wxGTK3 if you have a panel named m_panel1 in your form, you could get a hex string with its xid like so:
Then in gnuplot, you would run the command
To draw into that panel. I think with wxGTK2, m_panel1->GetHandle() will be the xid, but I don't have any systems with wxGTK2 anymore to test that with.
It looks like it's also possible to do the same thing with a qtwidget if you use the qt framework, but I don't have any experience there.
You can also simply draw to a png and then draw that png.
None of this will be like the interactive terminals though.
However, on X11 you can redirect to plot output to a window So for example, with wxGTK3 if you have a panel named m_panel1 in your form, you could get a hex string with its xid like so:
Code: Select all
int i = gdk_x11_window_get_xid(gtk_widget_get_window(m_panel1->GetHandle()));
wxString s = wxString::Format("%0X",i);
Code: Select all
set terminal x11 window "<contents of s>"
It looks like it's also possible to do the same thing with a qtwidget if you use the qt framework, but I don't have any experience there.
You can also simply draw to a png and then draw that png.
None of this will be like the interactive terminals though.
-
- Super wx Problem Solver
- Posts: 466
- Joined: Tue Jun 20, 2006 6:47 pm
- Contact:
Re: Is it possible to have a gnuplot plot in wxFrame window.
Here's a small example using wxGTK3
There actually is a little interactivity, but not as much as the other terminals. You could add a text box to use for sending additional commands to gnuplot if you want.
This would be slightly different with wxGTK2 but I don't know what all needs to be changed. Sadly, I don't see any way to do something similar on Windows or MacOS using wxWidgets. So I guess the only way to do something similar on those platforms is to use qt.
Code: Select all
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/process.h>
#include <wx/sstream.h>
#ifdef __WXGTK__
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#endif
class MainWindow : public wxFrame
{
public:
MainWindow(wxWindow* parent, int id = wxID_ANY,
wxString title = "demo",
wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize,
int style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL);
~MainWindow();
private:
void OnPlotWinCreated(wxWindowCreateEvent& event);
wxPanel* m_panel;
wxProcess m_process;
};
MainWindow::MainWindow(wxWindow* parent, int id, wxString title, wxPoint pos,
wxSize size, int style)
:wxFrame(parent, id, title, pos, size, style),
m_process(wxPROCESS_REDIRECT)
{
wxExecute("gnuplot",wxEXEC_ASYNC,&m_process);
m_process.Redirect();
m_panel = new wxPanel(this,wxID_ANY);
m_panel->Bind(wxEVT_CREATE, &MainWindow::OnPlotWinCreated, this);
}
MainWindow::~MainWindow()
{
wxStringInputStream sis("set term x11\n");
m_process.GetOutputStream()->Write(sis);
wxStringInputStream sis2("quit\n");
m_process.GetOutputStream()->Write(sis2);
}
void MainWindow::OnPlotWinCreated(wxWindowCreateEvent& event)
{
// We need to wait until the window is fully created to get all the
// info that is needed.
m_panel->Unbind(wxEVT_CREATE, &MainWindow::OnPlotWinCreated, this);
int i = gdk_x11_window_get_xid(gtk_widget_get_window(m_panel->GetHandle()));
wxString s = wxString::Format("set term x11 window \"%0X\"\n",i);
s << "plot sin(x)\n";
wxStringInputStream sis(s);
m_process.GetOutputStream()->Write(sis);
}
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
MainWindow* frame = new MainWindow(NULL);
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
This would be slightly different with wxGTK2 but I don't know what all needs to be changed. Sadly, I don't see any way to do something similar on Windows or MacOS using wxWidgets. So I guess the only way to do something similar on those platforms is to use qt.
Re: Is it possible to have a gnuplot plot in wxFrame window.
Thanks for explaining that. It's a shame if it doesn't work in Windows because that's what I use the most. I will study what you did here anyway. Ideally I'd like to write a program that would work in Windows with the option to compile for Linux if requested.
Re: Is it possible to have a gnuplot plot in wxFrame window.
Hi,
New in wx3.1 is wxNativeWindow. I've no experience of using it, but it might help you do what you want...
Regards,
David
New in wx3.1 is wxNativeWindow. I've no experience of using it, but it might help you do what you want...
Regards,
David
-
- Super wx Problem Solver
- Posts: 466
- Joined: Tue Jun 20, 2006 6:47 pm
- Contact:
Re: Is it possible to have a gnuplot plot in wxFrame window.
It definitely should be possible to redirect output with the windows terminal to a HWND in a similar manner that the x11 terminal can redirect it with an xid. But I guess none of the gnuplot developers have implemented it yet. Maybe you could put in a feature request.
Re: Is it possible to have a gnuplot plot in wxFrame window.
As a compromise, am I right in assuming I can open gnuplot from within my app, and send commands to plot and read the data to plot from a file? This might be a possibility. In a way, controlling gnuplot from within my wxWidgets app.
-
- Super wx Problem Solver
- Posts: 466
- Joined: Tue Jun 20, 2006 6:47 pm
- Contact:
Re: Is it possible to have a gnuplot plot in wxFrame window.
Yes.
Actually, you don't need to save to an intermediate file. If you don't specify an output file, gnuplot will output to stdout and you can read the plot contents from there. Here's an example using the svg terminal using wxWebview to display the svg:
Code: Select all
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/webview.h>
#include <wx/process.h>
#include <wx/timer.h>
#include <wx/mstream.h>
#include <wx/sstream.h>
#include <wx/app.h>
#include <wx/txtstrm.h>
#include <wx/webviewfshandler.h>
#include <wx/fs_mem.h>
class MainWindow : public wxFrame
{
public:
MainWindow(wxWindow* parent, int id = wxID_ANY,
wxString title = "demo",
wxPoint pos = wxDefaultPosition, wxSize size = wxDefaultSize,
int style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL);
~MainWindow();
void SendCommand(const wxString&);
private:
void OnCommandEntered(wxCommandEvent& event);
void OnIdleTimer(wxTimerEvent& event);
void OnIdle(wxIdleEvent& event);
void OnProcessTerminated(wxProcessEvent& event);
bool HasInput();
wxWebView* m_plotWindow;
wxTextCtrl* m_log;
wxTimer m_timerIdleWakeUp;
wxProcess m_process;
bool m_isRunning;
bool m_svgLoaded;
};
MainWindow::MainWindow(wxWindow* parent, int id, wxString title, wxPoint pos,
wxSize size, int style)
:wxFrame(parent, id, title, pos, size, style),
m_process(this)
{
wxPanel* panel = new wxPanel(this,wxID_ANY);
m_plotWindow = wxWebView::New(panel, wxID_ANY, wxWebViewDefaultURLStr);
m_log = new wxTextCtrl(panel, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE|wxTE_DONTWRAP|wxTE_READONLY);
wxTextCtrl* commandWindow =
new wxTextCtrl(panel, wxID_ANY, wxEmptyString,
wxDefaultPosition,wxDefaultSize,
wxTE_MULTILINE|wxTE_DONTWRAP|wxTE_PROCESS_ENTER);
wxBoxSizer* szr = new wxBoxSizer(wxVERTICAL);
szr->Add(commandWindow,wxSizerFlags(1).Expand().Border(wxALL));
szr->Add(m_log,wxSizerFlags(1).Expand().Border(wxALL));
szr->Add(m_plotWindow,wxSizerFlags(4).Expand().Border(wxALL));
panel->SetSizer(szr);
panel->Layout();
Bind(wxEVT_IDLE, &MainWindow::OnIdle, this);
Bind(wxEVT_TIMER, &MainWindow::OnIdleTimer, this);
Bind(wxEVT_END_PROCESS, &MainWindow::OnProcessTerminated, this);
commandWindow->Bind(wxEVT_TEXT_ENTER,&MainWindow::OnCommandEntered, this);
m_process.Redirect();
if ( !wxExecute("gnuplot", wxEXEC_ASYNC, &m_process) )
{
m_log->AppendText("Unable to gnuplot.\n");
m_isRunning = false;
}
else
{
m_isRunning = true;
int pid = m_process.GetPid();
m_log->AppendText(
wxString::Format("Process spawned with PID %d.\n", pid));
SendCommand("set terminal svg mouse standalone");
commandWindow->SetFocus();
}
m_svgLoaded = false;
wxFileSystem::AddHandler(new wxMemoryFSHandler);
m_plotWindow->RegisterHandler(
wxSharedPtr<wxWebViewHandler>(new wxWebViewFSHandler("memory")));
}
MainWindow::~MainWindow()
{
SendCommand("quit");
}
void MainWindow::OnCommandEntered(wxCommandEvent& event)
{
wxTextCtrl* = wxDynamicCast(event.GetEventObject(), wxTextCtrl);
if ( commandWin )
{
wxString s = commandWin->GetValue();
commandWin->Clear();
SendCommand(s);
}
}
void MainWindow::OnIdleTimer(wxTimerEvent& event)
{
wxWakeUpIdle();
}
void MainWindow::OnIdle(wxIdleEvent& event)
{
if ( HasInput() )
{
event.RequestMore();
}
}
void MainWindow::OnProcessTerminated(wxProcessEvent& event)
{
if ( event.GetPid() == m_process.GetPid() )
{
while ( HasInput() )
;
m_timerIdleWakeUp.Stop();
m_isRunning = false;
m_log->AppendText("gnuplot has terminated.\n");
}
}
bool MainWindow::HasInput()
{
bool readMore = false;
int sz = 10*1024*1024;
unsigned char* buffer = new unsigned char[sz];
if ( m_process.IsErrorAvailable() )
{
wxTextInputStream tis(*(m_process.GetErrorStream()));
wxString msg = tis.ReadLine();
msg << "\n";
m_log->AppendText(msg);
readMore = true;
}
if ( m_process.IsInputAvailable() )
{
wxMemoryOutputStream mos;
int lastRead = -1;
bool tryAgain = true;
while ( tryAgain )
{
m_process.GetInputStream()->Read(buffer,sz);
lastRead = m_process.GetInputStream()->LastRead();
mos.Write(buffer,lastRead);
tryAgain = ( lastRead == sz );
}
int fullSize = mos.GetOutputStreamBuffer()->GetBufferSize();
void* fullBuffer = mos.GetOutputStreamBuffer()->GetBufferStart();
if ( m_svgLoaded )
{
wxMemoryFSHandler::RemoveFile("a.svg");
}
wxMemoryFSHandler::AddFile("a.svg", fullBuffer, fullSize);
m_plotWindow->LoadURL("memory:a.svg");
m_svgLoaded = true;
readMore = true;
}
delete[] buffer;
return readMore;
}
void MainWindow::SendCommand(const wxString& s)
{
if ( m_isRunning )
{
wxString copyS = s;
copyS << "\n";
wxStringInputStream sis(copyS);
m_process.GetOutputStream()->Write(sis);
}
}
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
MainWindow* frame = new MainWindow(NULL);
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
One advantage of the svg output though is that if you know java script, you can intercept the svg before displaying it and inject extra functions to provide more interactivity if you want.
Re: Is it possible to have a gnuplot plot in wxFrame window.
Thank you, this seems like a nice solution, or at least a possible way to do it. I'm very new to wxWidgets so still learning the basics before I start to build my app. I'll first try to recreate your example. Is it possible to print and save plot images doing it this way?
-
- Super wx Problem Solver
- Posts: 466
- Joined: Tue Jun 20, 2006 6:47 pm
- Contact:
Re: Is it possible to have a gnuplot plot in wxFrame window.
Using wxWebview like above, you should be able to call wxWebview::Print to print the plot and wxWebview::GetPageSource to get a string that can be saved to a file. It will be an SVG file though and some image applications may not be able to open the file.
Re: Is it possible to have a gnuplot plot in wxFrame window.
Hi,
I try the code of New Pagodi but it does not work for me. After lot of search I found that the stream is not received in one piece but in separate pieces. So we must collect all the pieces before rendering.
I have adapted the code like that :
Now the svg is complete but it is not rendering on the WebView. In place, I have the source of the svg
Any idea why this problem ?
Thanks,
I try the code of New Pagodi but it does not work for me. After lot of search I found that the stream is not received in one piece but in separate pieces. So we must collect all the pieces before rendering.
I have adapted the code like that :
Code: Select all
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWidgets headers)
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/webview.h>
#include <wx/process.h>
#include <wx/timer.h>
#include <wx/wfstream.h>
#include <wx/mstream.h>
#include <wx/sstream.h>
#include <wx/app.h>
#include <wx/txtstrm.h>
#include <wx/webviewfshandler.h>
#include <wx/fs_mem.h>
class MainWindow : public wxFrame
{
public:
MainWindow(wxWindow* parent, int id = wxID_ANY,
wxString title = "demo",
wxPoint pos = wxDefaultPosition, wxSize size = wxSize(700,600),
int style = wxDEFAULT_FRAME_STYLE|wxTAB_TRAVERSAL);
~MainWindow();
void SendCommand(const wxString&);
void GnuDraw();
private:
void OnCommandEntered(wxCommandEvent& event);
void OnIdleTimer(wxTimerEvent& event);
void OnIdle(wxIdleEvent& event);
void OnProcessTerminated(wxProcessEvent& event);
bool HasInput();
wxWebView* m_plotWindow;
wxTextCtrl* m_log;
wxTimer m_timerIdleWakeUp;
wxProcess m_process;
bool m_isRunning;
bool m_svgLoaded;
wxMemoryOutputStream* mos;
bool HasGnuDraw = false;
int count = 0;
};
MainWindow::MainWindow(wxWindow* parent, int id, wxString title, wxPoint pos,
wxSize size, int style)
:wxFrame(parent, id, title, pos, size, style),
m_process(this)
{
wxPanel* panel = new wxPanel(this,wxID_ANY);
m_plotWindow = wxWebView::New(panel, wxID_ANY, wxWebViewDefaultURLStr);
m_log = new wxTextCtrl(panel, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE|wxTE_DONTWRAP|wxTE_READONLY);
wxTextCtrl* commandWindow =
new wxTextCtrl(panel, wxID_ANY, "plot sin(x)",
wxDefaultPosition,wxDefaultSize,
wxTE_MULTILINE|wxTE_DONTWRAP|wxTE_PROCESS_ENTER);
wxBoxSizer* szr = new wxBoxSizer(wxVERTICAL);
szr->Add(commandWindow,wxSizerFlags(1).Expand().Border(wxALL));
szr->Add(m_log,wxSizerFlags(1).Expand().Border(wxALL));
szr->Add(m_plotWindow,wxSizerFlags(4).Expand().Border(wxALL));
panel->SetSizer(szr);
panel->Layout();
Bind(wxEVT_IDLE, &MainWindow::OnIdle, this);
Bind(wxEVT_TIMER, &MainWindow::OnIdleTimer, this);
Bind(wxEVT_END_PROCESS, &MainWindow::OnProcessTerminated, this);
commandWindow->Bind(wxEVT_TEXT_ENTER,&MainWindow::OnCommandEntered, this);
m_process.Redirect();
if ( !wxExecute("gnuplot", wxEXEC_ASYNC, &m_process) )
{
m_log->AppendText("Unable to gnuplot.\n");
m_isRunning = false;
}
else
{
m_isRunning = true;
int pid = m_process.GetPid();
m_log->AppendText(
wxString::Format("Process spawned with PID %d.\n", pid));
SendCommand("set terminal svg mouse standalone"); //
commandWindow->SetFocus();
}
m_svgLoaded = false;
wxFileSystem::AddHandler(new wxMemoryFSHandler);
m_plotWindow->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewFSHandler("memory")));
mos = new wxMemoryOutputStream();
}
MainWindow::~MainWindow()
{
SendCommand("quit");
}
void MainWindow::OnCommandEntered(wxCommandEvent& event)
{
wxTextCtrl* commandWin = wxDynamicCast(event.GetEventObject(), wxTextCtrl);
if ( commandWin )
{
wxString s = commandWin->GetValue();
commandWin->Clear();
count = 0;
// Delete and recreate a Memory Output Stream
// because a don't know how to clear the existing
delete mos;
mos = new wxMemoryOutputStream();
HasGnuDraw = false;
SendCommand(s);
}
}
void MainWindow::OnIdleTimer(wxTimerEvent& WXUNUSED(event))
{
wxWakeUpIdle();
}
void MainWindow::OnIdle(wxIdleEvent& event)
{
if ( HasInput() )
{
event.RequestMore();
}
else
{
if (HasGnuDraw)
{
HasGnuDraw = false;
// std::cout << "DRAW: " << count << std::endl;
GnuDraw();
}
}
}
void MainWindow::OnProcessTerminated(wxProcessEvent& event)
{
if ( event.GetPid() == m_process.GetPid() )
{
while ( HasInput() )
;
m_timerIdleWakeUp.Stop();
m_isRunning = false;
m_log->AppendText("gnuplot has terminated.\n");
}
}
bool MainWindow::HasInput()
{
bool readMore = false;
int sz = 10*1024*1024;
unsigned char* buffer = new unsigned char[sz];
if ( m_process.IsErrorAvailable() )
{
wxTextInputStream tis(*(m_process.GetErrorStream()));
wxString msg = tis.ReadLine();
msg << "\n";
m_log->AppendText(msg);
readMore = true;
}
if ( m_process.IsInputAvailable() )
{
// wxFile css_file("output.svg", wxFile::write_append);
int lastRead = -1;
bool tryAgain = true;
while ( tryAgain )
{
m_process.GetInputStream()->Read(buffer,sz);
lastRead = m_process.GetInputStream()->LastRead();
mos->Write(buffer,lastRead);
// css_file.Write(buffer,lastRead);
tryAgain = ( lastRead == sz );
}
// css_file.Close();
count++;
// std::cout << "Receive: " << count << std::endl;
readMore = true;
HasGnuDraw = true;
}
delete[] buffer;
return readMore;
}
void MainWindow::GnuDraw()
{
int fullSize = mos->GetOutputStreamBuffer()->GetBufferSize();
void* fullBuffer = mos->GetOutputStreamBuffer()->GetBufferStart();
if ( m_svgLoaded )
{
wxMemoryFSHandler::RemoveFile("a.svg");
}
wxMemoryFSHandler::AddFile("a.svg", fullBuffer, fullSize);
m_plotWindow->LoadURL("memory:a.svg");
m_svgLoaded = true;
}
void MainWindow::SendCommand(const wxString& s)
{
if ( m_isRunning )
{
wxString copyS = s;
copyS << "\n";
wxStringInputStream sis(copyS);
m_process.GetOutputStream()->Write(sis);
}
m_log->AppendText(s+"\n");
}
class MyApp : public wxApp
{
public:
virtual bool OnInit()
{
MainWindow* frame = new MainWindow(NULL);
frame->Show();
return true;
}
};
wxIMPLEMENT_APP(MyApp);
Any idea why this problem ?
Thanks,
- Attachments
-
- gnu.png (60.45 KiB) Viewed 2643 times
Re: Is it possible to have a gnuplot plot in wxFrame window.
There quite of lot of JS code in that SVG. Try saving it as a file, load in a browser and check the error console. Maybe it has some error messages that give a hint.
Use the source, Luke!
Re: Is it possible to have a gnuplot plot in wxFrame window.
That's obviously the first thing I do. No error.
- doublemax@work
- Super wx Problem Solver
- Posts: 474
- Joined: Wed Jul 29, 2020 6:06 pm
- Location: NRW, Germany
Re: Is it possible to have a gnuplot plot in wxFrame window.
Can you upload the SVG here?
Re: Is it possible to have a gnuplot plot in wxFrame window.
Yes I can :
And I can say that if I save the svg in a file and then load it into the WebView, it works.
Code: Select all
<?xml version="1.0" encoding="windows-1252" standalone="no"?>
<svg onload="if (typeof(gnuplot_svg)!='undefined') gnuplot_svg.Init(evt)"
width="600" height="480"
viewBox="0 0 600 480"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
>
<title>Gnuplot</title>
<desc>Produced by GNUPLOT 5.2 patchlevel 8 </desc>
<script type="text/javascript" > <![CDATA[
// 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;
}
]]>
</script>
<!-- Tie mousing to entire bounding box of the plot -->
<rect x="0" y="0" width="600" height="480" fill="#ffffff" stroke="black" stroke-width="1"
onclick="gnuplot_svg.toggleCoordBox(evt)" onmousemove="gnuplot_svg.moveCoordBox(evt)"/>
<!-- Also track mouse when it is on a plot element -->
<g id="gnuplot_canvas" onclick="gnuplot_svg.toggleCoordBox(evt)" onmousemove="gnuplot_svg.moveCoordBox(evt)">
<defs>
<circle id='gpDot' r='0.5' stroke-width='0.5' stroke='currentColor'/>
<path id='gpPt0' stroke-width='0.222' stroke='currentColor' d='M-1,0 h2 M0,-1 v2'/>
<path id='gpPt1' stroke-width='0.222' stroke='currentColor' d='M-1,-1 L1,1 M1,-1 L-1,1'/>
<path id='gpPt2' stroke-width='0.222' stroke='currentColor' d='M-1,0 L1,0 M0,-1 L0,1 M-1,-1 L1,1 M-1,1 L1,-1'/>
<rect id='gpPt3' stroke-width='0.222' stroke='currentColor' x='-1' y='-1' width='2' height='2'/>
<rect id='gpPt4' stroke-width='0.222' stroke='currentColor' fill='currentColor' x='-1' y='-1' width='2' height='2'/>
<circle id='gpPt5' stroke-width='0.222' stroke='currentColor' cx='0' cy='0' r='1'/>
<use xlink:href='#gpPt5' id='gpPt6' fill='currentColor' stroke='none'/>
<path id='gpPt7' stroke-width='0.222' stroke='currentColor' d='M0,-1.33 L-1.33,0.67 L1.33,0.67 z'/>
<use xlink:href='#gpPt7' id='gpPt8' fill='currentColor' stroke='none'/>
<use xlink:href='#gpPt7' id='gpPt9' stroke='currentColor' transform='rotate(180)'/>
<use xlink:href='#gpPt9' id='gpPt10' fill='currentColor' stroke='none'/>
<use xlink:href='#gpPt3' id='gpPt11' stroke='currentColor' transform='rotate(45)'/>
<use xlink:href='#gpPt11' id='gpPt12' fill='currentColor' stroke='none'/>
<path id='gpPt13' stroke-width='0.222' stroke='currentColor' d='M0,1.330 L1.265,0.411 L0.782,-1.067 L-0.782,-1.076 L-1.265,0.411 z'/>
<use xlink:href='#gpPt13' id='gpPt14' fill='currentColor' stroke='none'/>
<filter id='textbox' filterUnits='objectBoundingBox' x='0' y='0' height='1' width='1'>
<feFlood flood-color='white' flood-opacity='1' result='bgnd'/>
<feComposite in='SourceGraphic' in2='bgnd' operator='atop'/>
</filter>
<filter id='greybox' filterUnits='objectBoundingBox' x='0' y='0' height='1' width='1'>
<feFlood flood-color='lightgrey' flood-opacity='1' result='grey'/>
<feComposite in='SourceGraphic' in2='grey' operator='atop'/>
</filter>
</defs>
<g fill="none" color="white" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,444.0 L62.9,444.0 M575.0,444.0 L566.0,444.0 '/> <g transform="translate(45.6,447.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text><tspan font-family="Arial" >-1</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,401.4 L62.9,401.4 M575.0,401.4 L566.0,401.4 '/> <g transform="translate(45.6,405.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text><tspan font-family="Arial" >-0.8</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,358.8 L62.9,358.8 M575.0,358.8 L566.0,358.8 '/> <g transform="translate(45.6,362.7)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text><tspan font-family="Arial" >-0.6</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,316.2 L62.9,316.2 M575.0,316.2 L566.0,316.2 '/> <g transform="translate(45.6,320.1)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text><tspan font-family="Arial" >-0.4</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,273.6 L62.9,273.6 M575.0,273.6 L566.0,273.6 '/> <g transform="translate(45.6,277.5)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text><tspan font-family="Arial" >-0.2</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,231.0 L62.9,231.0 M575.0,231.0 L566.0,231.0 '/> <g transform="translate(45.6,234.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text><tspan font-family="Arial" > 0</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,188.5 L62.9,188.5 M575.0,188.5 L566.0,188.5 '/> <g transform="translate(45.6,192.4)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text><tspan font-family="Arial" > 0.2</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,145.9 L62.9,145.9 M575.0,145.9 L566.0,145.9 '/> <g transform="translate(45.6,149.8)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text><tspan font-family="Arial" > 0.4</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,103.3 L62.9,103.3 M575.0,103.3 L566.0,103.3 '/> <g transform="translate(45.6,107.2)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text><tspan font-family="Arial" > 0.6</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,60.7 L62.9,60.7 M575.0,60.7 L566.0,60.7 '/> <g transform="translate(45.6,64.6)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text><tspan font-family="Arial" > 0.8</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,18.1 L62.9,18.1 M575.0,18.1 L566.0,18.1 '/> <g transform="translate(45.6,22.0)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text><tspan font-family="Arial" > 1</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,444.0 L53.9,435.0 M53.9,18.1 L53.9,27.1 '/> <g transform="translate(53.9,465.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
<text><tspan font-family="Arial" >-10</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M184.2,444.0 L184.2,435.0 M184.2,18.1 L184.2,27.1 '/> <g transform="translate(184.2,465.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
<text><tspan font-family="Arial" >-5</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M314.5,444.0 L314.5,435.0 M314.5,18.1 L314.5,27.1 '/> <g transform="translate(314.5,465.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
<text><tspan font-family="Arial" > 0</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M444.7,444.0 L444.7,435.0 M444.7,18.1 L444.7,27.1 '/> <g transform="translate(444.7,465.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
<text><tspan font-family="Arial" > 5</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M575.0,444.0 L575.0,435.0 M575.0,18.1 L575.0,27.1 '/> <g transform="translate(575.0,465.9)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="middle">
<text><tspan font-family="Arial" > 10</tspan></text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,18.1 L53.9,444.0 L575.0,444.0 L575.0,18.1 L53.9,18.1 Z '/></g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g id="gnuplot_plot_1" ><title>sin(x)</title>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<g id="gnuplot_plot_1_keyentry" visibility="visible" onclick="gnuplot_svg.toggleVisibility(evt,'gnuplot_plot_1')">
<g transform="translate(507.9,40.0)" stroke="none" fill="black" font-family="Arial" font-size="12.00" text-anchor="end">
<text>sin(x)</text>
</g>
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='rgb(148, 0, 211)' d='M516.2,36.1 L558.4,36.1 '/> </g>
<path stroke='rgb(148, 0, 211)' d='M53.9,115.2 L59.2,153.4 L64.4,194.8 L69.7,237.6 L75.0,280.2 L80.2,320.8 L85.5,357.7 L90.7,389.5
L96.0,414.8 L101.3,432.7 L106.5,442.3 L111.8,443.4 L117.1,435.8 L122.3,419.9 L127.6,396.3 L132.9,366.0
L138.1,330.2 L143.4,290.4 L148.6,248.2 L153.9,205.2 L159.2,163.3 L164.4,124.2 L169.7,89.4 L175.0,60.4
L180.2,38.3 L185.5,24.1 L190.8,18.2 L196.0,21.1 L201.3,32.4 L206.5,51.9 L211.8,78.6 L217.1,111.6
L222.3,149.3 L227.6,190.5 L232.9,233.2 L238.1,275.9 L243.4,316.8 L248.7,354.1 L253.9,386.5 L259.2,412.5
L264.4,431.2 L269.7,441.7 L275.0,443.7 L280.2,437.0 L285.5,421.9 L290.8,399.1 L296.0,369.4 L301.3,334.1
L306.6,294.6 L311.8,252.5 L317.1,209.6 L322.3,167.5 L327.6,128.0 L332.9,92.7 L338.1,63.0 L343.4,40.2
L348.7,25.1 L353.9,18.4 L359.2,20.4 L364.5,30.9 L369.7,49.6 L375.0,75.6 L380.2,108.0 L385.5,145.3
L390.8,186.2 L396.0,228.9 L401.3,271.6 L406.6,312.8 L411.8,350.5 L417.1,383.5 L422.4,410.2 L427.6,429.7
L432.9,441.0 L438.1,443.9 L443.4,438.0 L448.7,423.8 L453.9,401.7 L459.2,372.7 L464.5,337.9 L469.7,298.8
L475.0,256.9 L480.3,213.9 L485.5,171.7 L490.8,131.9 L496.0,96.1 L501.3,65.8 L506.6,42.2 L511.8,26.3
L517.1,18.7 L522.4,19.8 L527.6,29.4 L532.9,47.3 L538.2,72.6 L543.4,104.4 L548.7,141.3 L553.9,181.9
L559.2,224.5 L564.5,267.3 L569.7,308.7 L575.0,346.9 '/></g>
</g>
<g fill="none" color="white" stroke="rgb(148, 0, 211)" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="black" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
<path stroke='black' d='M53.9,18.1 L53.9,444.0 L575.0,444.0 L575.0,18.1 L53.9,18.1 Z '/></g>
<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
</g>
<script type="text/javascript"><![CDATA[
// plot boundaries and axis scaling information for mousing
gnuplot_svg.plot_term_xmax = 600;
gnuplot_svg.plot_term_ymax = 480;
gnuplot_svg.plot_xmin = 53.9;
gnuplot_svg.plot_xmax = 575.0;
gnuplot_svg.plot_ybot = 444.0;
gnuplot_svg.plot_ytop = 18.1;
gnuplot_svg.plot_width = 521.1;
gnuplot_svg.plot_height = 425.9;
gnuplot_svg.plot_axis_xmin = -10;
gnuplot_svg.plot_axis_xmax = 10;
gnuplot_svg.plot_axis_ymin = -1;
gnuplot_svg.plot_axis_ymax = 1;
gnuplot_svg.polar_mode = false;
gnuplot_svg.plot_axis_x2min = "none"
gnuplot_svg.plot_axis_y2min = "none"
gnuplot_svg.plot_logaxis_x = 0;
gnuplot_svg.plot_logaxis_y = 0;
gnuplot_svg.plot_timeaxis_x = "";
gnuplot_svg.plot_timeaxis_y = "";
]]>
</script>
</g>
<text id="coord_text" text-anchor="start" pointer-events="none"
font-size="12" font-family="Arial"
visibility="hidden"> </text>
<rect id="hypertextbox" class="hypertextbox" pointer-events="none"
fill="white" stroke="black" opacity="0.8"
height="16" visibility="hidden" />
<text id="hypertext" class="hypertext" pointer-events="none"
font-size="12" font-family="Arial"
visibility="hidden"> </text>
<image id="hyperimage" class="hyperimage" pointer-events="none"
fill="white" stroke="black" opacity="0.8"
height="200" width="300" visibility="hidden" />
</svg>