"Fossies" - the Fresh Open Source Software Archive

Member "fityk-1.3.1/wxgui/uplot.cpp" (13 May 2016, 7846 Bytes) of package /linux/misc/fityk-1.3.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "uplot.cpp" see the Fossies "Dox" file reference documentation.

    1 // This file is part of fityk program. Copyright 2001-2013 Marcin Wojdyr
    2 // Licence: GNU General Public License ver. 2+
    3 // (It is also part of xyconvert and can be distributed under LGPL2.1)
    4 
    5 /// utilities for making plot (BufferedPanel, scale_tics_step())
    6 
    7 #include <wx/wx.h>
    8 #include <wx/dcgraph.h>
    9 
   10 #include "uplot.h"
   11 //#include "cmn.h"
   12 
   13 #if !defined(XYCONVERT) && !defined(STANDALONE_POWDIFPAT)
   14 #include "frame.h" // frame->antialias()
   15 inline bool antialias() { return frame->antialias(); }
   16 #else
   17 inline bool antialias() { return false; }
   18 #endif
   19 
   20 using namespace std;
   21 
   22 BufferedPanel::BufferedPanel(wxWindow *parent)
   23    : wxPanel(parent, -1, wxDefaultPosition, wxDefaultSize,
   24              wxNO_BORDER|wxFULL_REPAINT_ON_RESIZE),
   25      support_antialiasing_(true), dirty_(true)
   26 {
   27     SetBackgroundStyle(wxBG_STYLE_CUSTOM);
   28     Connect(wxEVT_IDLE, wxIdleEventHandler(BufferedPanel::OnIdle));
   29 }
   30 
   31 void BufferedPanel::redraw_now()
   32 {
   33     dirty_ = true;
   34     Refresh(false);
   35     Update();
   36 }
   37 
   38 void BufferedPanel::gc_draw(wxMemoryDC& dc)
   39 {
   40     if (antialias() && support_antialiasing_) {
   41         wxGCDC gdc(dc);
   42 #ifdef __WXMSW__
   43         // this is necessary only for PNG output on Windows,
   44         // together with explicit 32-bit bitmap depth in
   45         // PlotPane::prepare_bitmap_for_export()
   46         gdc.SetBackground(wxBrush(bg_color_));
   47         gdc.Clear();
   48 #endif
   49         draw(gdc);
   50     } else
   51         draw(dc);
   52 }
   53 
   54 wxBitmap BufferedPanel::draw_on_bitmap(int w, int h, int depth)
   55 {
   56     wxBitmap bmp = wxBitmap(w, h, depth);
   57     memory_dc_.SelectObject(bmp);
   58     memory_dc_.SetBackground(wxBrush(bg_color_));
   59     memory_dc_.Clear();
   60     gc_draw(memory_dc_);
   61     if (buffer_.Ok()) {
   62         memory_dc_.SelectObject(buffer_);
   63         memory_dc_.SetBackground(wxBrush(bg_color_));
   64     }
   65     return bmp;
   66 }
   67 
   68 
   69 void BufferedPanel::update_buffer_and_blit()
   70 {
   71     //cout << "BufferedPanel::update_buffer_and_blit()" << endl;
   72     wxPaintDC pdc(this);
   73     // check size
   74     wxCoord w, h;
   75     pdc.GetSize(&w, &h);
   76     if (w == 0 || h == 0)
   77         return;
   78     if (!buffer_.Ok() || w != buffer_.GetWidth() || h != buffer_.GetHeight()) {
   79         memory_dc_.SelectObject(wxNullBitmap);
   80         buffer_ = wxBitmap(w, h);
   81         memory_dc_.SelectObject(buffer_);
   82         memory_dc_.SetBackground(wxBrush(bg_color_));
   83         dirty_ = true;
   84     }
   85 
   86     // update the buffer if necessary
   87     if (dirty_) {
   88         memory_dc_.SetLogicalFunction(wxCOPY);
   89         memory_dc_.Clear();
   90         gc_draw(memory_dc_);
   91         // This condition is almost always true. It was added because on
   92         // wxGTK 2.8 with some window managers, after loading a data file
   93         // the next paint event had the update region set to the area
   94         // of the file dialog, and the rest of the plot remained not updated.
   95         if (GetUpdateRegion().GetBox().GetSize() == pdc.GetSize())
   96             dirty_ = false;
   97     }
   98     blit(pdc);
   99 }
  100 
  101 void BufferedPanel::blit(wxDC& dc)
  102 {
  103     dc.Blit(0, 0, buffer_.GetWidth(), buffer_.GetHeight(), &memory_dc_, 0, 0);
  104 }
  105 
  106 void BufferedPanel::OnIdle(wxIdleEvent&)
  107 {
  108     if (dirty_)
  109         Refresh(false);
  110 }
  111 
  112 void BufferedPanel::set_bg_color(wxColour const& c)
  113 {
  114     bg_color_ = c;
  115     if (memory_dc_.IsOk())
  116         memory_dc_.SetBackground(wxBrush(c));
  117 }
  118 
  119 PlotWithTics::PlotWithTics(wxWindow* parent)
  120     : BufferedPanel(parent)
  121 {
  122     Connect(GetId(), wxEVT_PAINT,
  123                   (wxObjectEventFunction) &PlotWithTics::OnPaint);
  124 }
  125 
  126 void PlotWithTics::draw_tics(wxDC &dc, double x_min, double x_max,
  127                              double y_min, double y_max)
  128 {
  129     // prepare scaling
  130     double const margin = 0.1;
  131     double dx = x_max - x_min;
  132     double dy = y_max - y_min;
  133     int W = dc.GetSize().GetWidth();
  134     int H = dc.GetSize().GetHeight();
  135     xScale = (1 - 1.2 * margin) *  W / dx;
  136     yScale = - (1 - 1.2 * margin) * H / dy;
  137     xOffset = - x_min * xScale + margin * W;
  138     yOffset = H - y_min * yScale - margin * H;
  139 
  140     // draw scale
  141     dc.SetPen(*wxWHITE_PEN);
  142     dc.SetTextForeground(*wxWHITE);
  143     dc.SetFont(*wxSMALL_FONT);
  144 
  145     // ... horizontal
  146     vector<double> minors;
  147     vector<double> tics = scale_tics_step(x_min, x_max, 4, minors);
  148     for (vector<double>::const_iterator i = tics.begin(); i != tics.end(); ++i){
  149         int X = getX(*i);
  150         wxString label = format_label(*i, x_max - x_min);
  151         wxCoord tw, th;
  152         dc.GetTextExtent (label, &tw, &th);
  153         int Y = dc.DeviceToLogicalY(H - th - 2);
  154         dc.DrawText (label, X - tw/2, Y + 1);
  155         dc.DrawLine (X, Y, X, Y - 4);
  156     }
  157 
  158     // ... vertical
  159     tics = scale_tics_step(y_min, y_max, 4, minors);
  160     for (vector<double>::const_iterator i = tics.begin(); i != tics.end(); ++i){
  161         int Y = getY(*i);
  162         wxString label = format_label(*i, y_max - y_min);
  163         wxCoord tw, th;
  164         dc.GetTextExtent (label, &tw, &th);
  165         dc.DrawText (label, dc.DeviceToLogicalX(5), Y - th/2);
  166         dc.DrawLine (dc.DeviceToLogicalX(0), Y, dc.DeviceToLogicalX(4), Y);
  167     }
  168 }
  169 
  170 void PlotWithTics::draw_axis_labels(wxDC& dc, string const& x_name,
  171                                     string const& y_name)
  172 {
  173     int W = dc.GetSize().GetWidth();
  174     int H = dc.GetSize().GetHeight();
  175     if (!x_name.empty()) {
  176         wxCoord tw, th;
  177         dc.GetTextExtent(x_name, &tw, &th);
  178         dc.DrawText(x_name, (W - tw)/2, 2);
  179     }
  180     if (!y_name.empty()) {
  181         wxCoord tw, th;
  182         dc.GetTextExtent(y_name, &tw, &th);
  183         dc.DrawRotatedText(y_name, W - 2, (H - tw)/2, 270);
  184     }
  185 }
  186 
  187 
  188 vector<double> scale_tics_step (double beg, double end, int max_tics,
  189                                 vector<double> &minors, bool logarithm)
  190 {
  191     vector<double> result;
  192     minors.clear();
  193     if (beg >= end || max_tics <= 0)
  194         return result;
  195     if (logarithm) {
  196         if (beg <= 0)
  197             beg = 1e-1;
  198         if (end <= beg)
  199             end = 2*beg;
  200         double min_logstep = (log10(end/beg)) / max_tics;
  201         bool with_2_5 = (min_logstep < log10(2.));
  202         double logstep = ceil(min_logstep);
  203         double step0 = pow(10, logstep * ceil(log10(beg) / logstep));
  204         for (int i = 2; i <= 9; ++i) {
  205             double v = step0/10. * i;
  206             if (v > beg && v < end) {
  207                 if (with_2_5 && (i == 2 || i == 5))
  208                     result.push_back(v);
  209                 else
  210                     minors.push_back(v);
  211             }
  212         }
  213         for (double t = step0; t < end; t *= pow(10,logstep)) {
  214             result.push_back(t);
  215             for (int i = 2; i <= 9; ++i) {
  216                 double v = t * i;
  217                 if (v > beg && v < end) {
  218                     if (with_2_5 && (i == 2 || i == 5))
  219                         result.push_back(v);
  220                     else
  221                         minors.push_back(v);
  222                 }
  223             }
  224         }
  225     } else { // !logarithm
  226         double min_step = (end - beg) / max_tics;
  227         double s = pow(10, floor (log10 (min_step)));
  228         int minor_div = 5; //ratio of major-step to minor-step
  229         // now s <= min_step
  230         if (s >= min_step)
  231             ;
  232         else if (s * 2 >= min_step) {
  233             s *= 2;
  234             minor_div = 2;
  235         } else if (s * 2.5 >= min_step)
  236             s *= 2.5;
  237         else if (s * 5 >=  min_step)
  238             s *= 5;
  239         else
  240             s *= 10;
  241         for (double t = s * floor(beg / s); t < end; t += s) {
  242             if (t > beg) {
  243                 // make sure that 0 is not displayed as e.g. -2.7893e-17
  244                 if (fabs(t) < 1e-6 * fabs(min_step))
  245                     t = 0.;
  246                 result.push_back(t);
  247             }
  248             for (int i = 1; i < minor_div; ++i) {
  249                 double v = t + s * i / minor_div;
  250                 if (v > beg && v < end)
  251                     minors.push_back(v);
  252             }
  253         }
  254     }
  255     return result;
  256 }
  257