Thread: Saving explain output graphically

Saving explain output graphically

From
Magnus Hagander
Date:
There was some talk a while back about being able to save the explain
output graphically, and I've taken a stab at it. Attached patch appears
to be working for me, but I had a lot of trouble getting things to work
properly before I found the right track. Specifically, I got the wrong
size of the image all the time.

So if some people could test the patch with a bunch of different queries
and strange explain outputs, to see if you get proper size images out of
it, that would be great :-)

Thanks!


//Magnus
Index: ctl/explainCanvas.cpp
===================================================================
--- ctl/explainCanvas.cpp    (revision 6992)
+++ ctl/explainCanvas.cpp    (working copy)
@@ -163,6 +163,9 @@
     int h=(rootShape->totalShapes * yoffs + y0*2 + PIXPERUNIT - 1) / PIXPERUNIT;

     SetScrollbars(PIXPERUNIT, PIXPERUNIT, w, h);
+
+    graphWidth = maxLevel * xoffs + x0;
+    graphHeight = rootShape->totalShapes * yoffs + y0;
 }


@@ -182,7 +185,34 @@
     popup->Move(ClientToScreen(wxPoint(sx, sy)));
 }

+bool ExplainCanvas::CanSave()
+{
+    return (GetDiagram()->GetCount() > 0);
+}

+bool ExplainCanvas::SaveToFile(const wxString& filename)
+{
+    wxBitmap bmp(graphWidth, graphHeight);
+    wxMemoryDC *mem = new wxMemoryDC();
+
+    mem->SelectObject(bmp);
+    mem->Clear();
+
+    GetDiagram()->Redraw(*mem);
+
+    if (!bmp.SaveFile(filename, wxBITMAP_TYPE_PNG))
+    {
+        wxLogError(__("Could not write the file %s."), filename.c_str());
+        delete mem;
+        return false;
+    }
+
+    delete mem;
+
+    return true;
+}
+
+
 class ExplainText : public wxWindow
 {
 public:
Index: pgAdmin3.cpp
===================================================================
--- pgAdmin3.cpp    (revision 6992)
+++ pgAdmin3.cpp    (working copy)
@@ -183,6 +183,9 @@
     // Force logging off until we're ready
     wxLog *seLog=new wxLogStderr();
     wxLog::SetActiveTarget(seLog);
+
+    // Initialize image formats
+    ::wxInitAllImageHandlers();

     static const wxCmdLineEntryDesc cmdLineDesc[] =
     {
Index: include/ctl/explainCanvas.h
===================================================================
--- include/ctl/explainCanvas.h    (revision 6992)
+++ include/ctl/explainCanvas.h    (working copy)
@@ -33,11 +33,14 @@
     void ShowPopup(ExplainShape *s);
     void SetExplainString(const wxString &str);
     void Clear();
+    bool CanSave();
+    bool SaveToFile(const wxString &filename);

 private:

     ExplainShape *rootShape, *lastShape;
     ExplainPopup *popup;
+    int graphHeight, graphWidth;
 };


Index: include/frm/menu.h
===================================================================
--- include/frm/menu.h    (revision 6992)
+++ include/frm/menu.h    (working copy)
@@ -62,6 +62,7 @@
     MNU_ANALYZE,
     MNU_CLEARHISTORY,
     MNU_SAVEHISTORY,
+    MNU_SAVEEXPLAIN,
     MNU_CHECKALIVE,
     MNU_SELECTALL,

Index: include/frm/frmQuery.h
===================================================================
--- include/frm/frmQuery.h    (revision 6992)
+++ include/frm/frmQuery.h    (working copy)
@@ -105,6 +105,7 @@
     void OnSaveHistory(wxCommandEvent& event);
     void OnChangeConnection(wxCommandEvent &ev);
     void OnClearHistory(wxCommandEvent& event);
+    void OnSaveExplain(wxCommandEvent& event);
     void OnActivate(wxActivateEvent& event);
     void OnFocus(wxFocusEvent& event);
     void OnSelectAll(wxCommandEvent& event);
Index: frm/frmQuery.cpp
===================================================================
--- frm/frmQuery.cpp    (revision 6992)
+++ frm/frmQuery.cpp    (working copy)
@@ -92,6 +92,7 @@
     EVT_MENU(MNU_HELP,              frmQuery::OnHelp)
     EVT_MENU(MNU_CLEARHISTORY,      frmQuery::OnClearHistory)
     EVT_MENU(MNU_SAVEHISTORY,       frmQuery::OnSaveHistory)
+    EVT_MENU(MNU_SAVEEXPLAIN,       frmQuery::OnSaveExplain)
     EVT_MENU(MNU_SELECTALL,         frmQuery::OnSelectAll)
     EVT_MENU(MNU_QUICKREPORT,       frmQuery::OnQuickReport)
     EVT_MENU(MNU_AUTOINDENT,        frmQuery::OnAutoIndent)
@@ -195,6 +196,7 @@
     queryMenu->AppendSeparator();
     queryMenu->Append(MNU_SAVEHISTORY, _("Save history"), _("Save history of executed commands."));
     queryMenu->Append(MNU_CLEARHISTORY, _("Clear history"), _("Clear history window."));
+    queryMenu->Append(MNU_SAVEEXPLAIN, _("Save explain"), _("Save explain output image."));
     queryMenu->AppendSeparator();
     queryMenu->Append(MNU_CANCEL, _("&Cancel\tAlt-Break"), _("Cancel query"));
     menuBar->Append(queryMenu, _("&Query"));
@@ -856,7 +858,17 @@

 }

+void frmQuery::OnSaveExplain(wxCommandEvent& event)
+{
+    wxFileDialog *dlg = new wxFileDialog(this, _("Save explain"), lastDir, wxEmptyString,
+        _("Image files (*.png)|*.png|All files (*.*)|*.*)"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
+    if (dlg->ShowModal() == wxID_OK)
+    {
+        explainCanvas->SaveToFile(dlg->GetPath());
+    }
+}

+
 void frmQuery::OnSetFocus(wxFocusEvent& event)
 {
     sqlQuery->SetFocus();
@@ -1548,6 +1560,7 @@
         return;

     explainCanvas->SetExplainString(str);
+    setTools(false);
     outputPane->SetSelection(1);
     sqlQuery->SetFocus();
 }
@@ -1632,6 +1645,7 @@
     queryMenu->Enable(MNU_EXECFILE, !running);
     queryMenu->Enable(MNU_EXPLAIN, !running);
     queryMenu->Enable(MNU_CANCEL, running);
+    queryMenu->Enable(MNU_SAVEEXPLAIN, explainCanvas->CanSave());
     fileMenu->Enable(MNU_EXPORT, sqlResult->CanExport());
     fileMenu->Enable(MNU_QUICKREPORT, sqlResult->CanExport());
     fileMenu->Enable(MNU_RECENT, (recentFileMenu->GetMenuItemCount() > 0));
@@ -1653,12 +1667,12 @@

 void frmQuery::execQuery(const wxString &query, int resultToRetrieve, bool singleResult, const int queryOffset, bool
toFile,bool explain, bool verbose) 
 {
+    explainCanvas->Clear();
+
     setTools(true);
     queryMenu->Enable(MNU_SAVEHISTORY, true);
     queryMenu->Enable(MNU_CLEARHISTORY, true);

-    explainCanvas->Clear();
-
     // Clear markers and indicators
     sqlQuery->MarkerDeleteAll(0);
     sqlQuery->StartStyling(0, wxSTC_INDICS_MASK);
@@ -1933,6 +1947,7 @@
                 }
             }
             explainCanvas->SetExplainString(str);
+            setTools(false);
             outputPane->SetSelection(1);
         }
     }

Re: Saving explain output graphically

From
"Dave Page"
Date:
On 14/01/2008, Magnus Hagander <magnus@hagander.net> wrote:
> There was some talk a while back about being able to save the explain
> output graphically, and I've taken a stab at it. Attached patch appears
> to be working for me, but I had a lot of trouble getting things to work
> properly before I found the right track. Specifically, I got the wrong
> size of the image all the time.
>
> So if some people could test the patch with a bunch of different queries
> and strange explain outputs, to see if you get proper size images out of
> it, that would be great :-)

I consistently get no border along the right hand side - see the
attached example. It looks pretty good though :-)

Now you just need to add options to include the data for each node and
the query text :-p

/D

Attachment

Re: Saving explain output graphically

From
Magnus Hagander
Date:
Dave Page wrote:
> On 14/01/2008, Magnus Hagander <magnus@hagander.net> wrote:
>> There was some talk a while back about being able to save the explain
>> output graphically, and I've taken a stab at it. Attached patch appears
>> to be working for me, but I had a lot of trouble getting things to work
>> properly before I found the right track. Specifically, I got the wrong
>> size of the image all the time.
>>
>> So if some people could test the patch with a bunch of different queries
>> and strange explain outputs, to see if you get proper size images out of
>> it, that would be great :-)
>
> I consistently get no border along the right hand side - see the
> attached example. It looks pretty good though :-)

Interesting. I don't get that here - what platform is that on? Mac?

Maybe just add a simple +20 pixels or something to the right to work
around it? ;-) Given that it's not exactly aligned to the edge of the
image anyway, that shouldn't be a problem?


> Now you just need to add options to include the data for each node and
> the query text :-p

Be my guest :-)

What would actually be *really* cool was an export in SVG including
those, but wx doesn't do that :-)

//Magnus

Re: Saving explain output graphically

From
"Dave Page"
Date:
Yeah, it's mac. I assume it doesn't do it on win32/unix? An additional
few px seems reasonable btw.

/D

On 1/16/08, Magnus Hagander <magnus@hagander.net> wrote:
> Dave Page wrote:
> > On 14/01/2008, Magnus Hagander <magnus@hagander.net> wrote:
> >> There was some talk a while back about being able to save the explain
> >> output graphically, and I've taken a stab at it. Attached patch appears
> >> to be working for me, but I had a lot of trouble getting things to work
> >> properly before I found the right track. Specifically, I got the wrong
> >> size of the image all the time.
> >>
> >> So if some people could test the patch with a bunch of different queries
> >> and strange explain outputs, to see if you get proper size images out of
> >> it, that would be great :-)
> >
> > I consistently get no border along the right hand side - see the
> > attached example. It looks pretty good though :-)
>
> Interesting. I don't get that here - what platform is that on? Mac?
>
> Maybe just add a simple +20 pixels or something to the right to work
> around it? ;-) Given that it's not exactly aligned to the edge of the
> image anyway, that shouldn't be a problem?
>
>
> > Now you just need to add options to include the data for each node and
> > the query text :-p
>
> Be my guest :-)
>
> What would actually be *really* cool was an export in SVG including
> those, but wx doesn't do that :-)
>
> //Magnus
>

--
Sent from my mobile device