Is it possible to have a gnuplot plot in wxFrame window.

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
PaulUK
Knows some wx things
Knows some wx things
Posts: 43
Joined: Wed Nov 18, 2020 12:55 pm

Is it possible to have a gnuplot plot in wxFrame window.

Post by PaulUK »

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.
New Pagodi
Super wx Problem Solver
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.

Post by New Pagodi »

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:

Code: Select all

    
int i = gdk_x11_window_get_xid(gtk_widget_get_window(m_panel1->GetHandle()));
wxString s = wxString::Format("%0X",i);
Then in gnuplot, you would run the command

Code: Select all

set terminal x11 window "<contents of s>"
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.
New Pagodi
Super wx Problem Solver
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.

Post by New Pagodi »

Here's a small example using wxGTK3

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);
gnuplot.png
gnuplot.png (5.3 KiB) Viewed 3052 times
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.
PaulUK
Knows some wx things
Knows some wx things
Posts: 43
Joined: Wed Nov 18, 2020 12:55 pm

Re: Is it possible to have a gnuplot plot in wxFrame window.

Post by PaulUK »

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.
DavidHart
Site Admin
Site Admin
Posts: 4252
Joined: Thu Jan 12, 2006 6:23 pm
Location: IoW, UK

Re: Is it possible to have a gnuplot plot in wxFrame window.

Post by DavidHart »

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 Pagodi
Super wx Problem Solver
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.

Post by New Pagodi »

PaulUK wrote: Fri Nov 20, 2020 1:54 pm 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.
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.
PaulUK
Knows some wx things
Knows some wx things
Posts: 43
Joined: Wed Nov 18, 2020 12:55 pm

Re: Is it possible to have a gnuplot plot in wxFrame window.

Post by PaulUK »

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.
New Pagodi
Super wx Problem Solver
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.

Post by New Pagodi »

PaulUK wrote: Mon Nov 23, 2020 3:22 pm 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.
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);
Untitled.png
Untitled.png (22.8 KiB) Viewed 2924 times
Commands can be sent to gnuplot with the top text control. Any messages from gnuplot are displayed in the middle text control. You could use the png or any other format wxWidgets can display in a similar manner.

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.
PaulUK
Knows some wx things
Knows some wx things
Posts: 43
Joined: Wed Nov 18, 2020 12:55 pm

Re: Is it possible to have a gnuplot plot in wxFrame window.

Post by PaulUK »

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?
New Pagodi
Super wx Problem Solver
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.

Post by New Pagodi »

PaulUK wrote: Wed Nov 25, 2020 11:12 am Is it possible to print and save plot images doing it this way?
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.
lr83
Knows some wx things
Knows some wx things
Posts: 34
Joined: Sat Nov 28, 2020 2:15 pm
Location: France

Re: Is it possible to have a gnuplot plot in wxFrame window.

Post by lr83 »

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 :

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);
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,
Attachments
gnu.png
gnu.png (60.45 KiB) Viewed 2643 times
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Is it possible to have a gnuplot plot in wxFrame window.

Post by doublemax »

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!
lr83
Knows some wx things
Knows some wx things
Posts: 34
Joined: Sat Nov 28, 2020 2:15 pm
Location: France

Re: Is it possible to have a gnuplot plot in wxFrame window.

Post by lr83 »

That's obviously the first thing I do. No error.
User avatar
doublemax@work
Super wx Problem Solver
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.

Post by doublemax@work »

Can you upload the SVG here?
lr83
Knows some wx things
Knows some wx things
Posts: 34
Joined: Sat Nov 28, 2020 2:15 pm
Location: France

Re: Is it possible to have a gnuplot plot in wxFrame window.

Post by lr83 »

Yes I can :

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>

And I can say that if I save the svg in a file and then load it into the WebView, it works.
Post Reply