source: trunk/lib/Gnuplot.h @ 65

Last change on this file since 65 was 65, checked in by Peter Johansson, 16 years ago

corrected includes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.4 KB
Line 
1// $Id: Gnuplot.h 65 2006-01-20 09:32:00Z peter $
2
3#ifndef _theplu_svnstat_gnuplot_
4#define _theplu_svnstat_gnuplot_
5
6#include <cassert>
7#include <cstdio>
8#include <fstream>
9#include <list>
10#include <stdexcept>
11#include <string>
12#include <vector>
13
14
15namespace theplu {
16namespace svnstat {
17
18  ///
19  /// If something goes wrong in the use of the Gnuplot class, a
20  /// GnuplotException is thrown.
21  ///
22  struct GnuplotException : public std::runtime_error
23  { inline GnuplotException(const std::string& msg) : runtime_error(msg) {} };
24
25  ///
26  /// The Gnuplot class creates a pipe to 'gnuplot' and facilitates
27  /// communication with the binary.
28  ///
29  /// Temporary files are created in directory /tmp. These temporaru
30  /// files are removed on a normal program exit.
31  ///
32  class Gnuplot
33  {
34  public:
35    ///
36    /// This constructor sets up the pipe to the first gnuplot
37    /// executable found in the PATH environment variable. The PATH
38    /// variable must exist.
39    ///
40    /// @throw Throws a GnuplotException if a no PATH variable is
41    /// found, if the gnuplot binary cannot be found, or if a pipe
42    /// cannot to the gnuplot binary cannot be established.
43    ///
44    Gnuplot(void);
45
46    ///
47    /// The destructor deletes all temporary files created in the
48    /// calls to plot_xy and plot_x. If the program execution fails to
49    /// reach this destructor the temporary files will not be removed
50    /// from the storage area.
51    ///
52    ~Gnuplot(void);
53
54    ///
55    /// Send arbitrary commands to Gnuplot.
56    ///
57    void command(std::string);
58
59    ///
60    /// @return input format for date
61    ///
62    // Peter, obsolete ?
63    const std::string& date_input_format(void) { return date_input_format_; }
64
65    ///
66    ///
67    ///
68    void date_plot(const std::vector<double>& y, 
69                   const std::string& format="%y-%b-%d");
70    ///
71    ///
72    ///
73    void date_replot(const std::vector<double>& y,
74                     const std::string& format="%y-%b-%d");
75
76    ///
77    /// Set the \a style of the line in the subsequent plot or
78    /// replot calls. The setting applies until this function is
79    /// called again.
80    ///
81    /// @note The \a style is not checked to be valid.
82    ///
83    inline void linestyle(const std::string& style) { linestyle_=style; }
84
85    ///
86    /// Set the \a title of the line in the subsequent plot or
87    /// replot calls. The setting applies until this function is
88    /// called again.
89    ///
90    inline void linetitle(const std::string& title) { linetitle_=title; }
91
92    ///
93    /// Plot the data \a y as a function of \a x using the Gnuplot
94    /// 'plot' command. The \a x vector can be omitted as in normal
95    /// Gnuplot usage.
96    ///
97    // Peter, do we have to set xdata for replot
98    inline void
99    plot(const std::vector<double>& y,
100         const std::vector<double>& x=std::vector<double>())
101    { command("set xdata"); plot(y,x,"plot"); }
102
103    ///
104    /// Plot the data \a y as a function of \a x using the Gnuplot
105    /// 'replot' command. The \a x vector can be omitted as in normal
106    /// Gnuplot usage.
107    ///
108    inline void
109    replot(const std::vector<double>& y,
110           const std::vector<double>& x=std::vector<double>())
111    { command("set xdata"); plot(y,x,"replot"); }
112
113    ///
114    /// sets format of date output
115    ///
116    inline void set_date_format(const std::string& format) 
117    { date_output_format_ = format;}
118
119    ///
120    /// Function setting the dates. \a format must comply with strings
121    /// in date
122    ///
123    inline void set_dates(const std::vector<std::string>& date, 
124                          const std::string& format="%Y-%m-%d")
125    { date_=date; date_input_format_=format; }
126
127  private:
128    ///
129    /// Copy constructor, not implemented.
130    ///
131    Gnuplot(const Gnuplot&);
132
133    void acquire_program_path(const std::string&);
134
135    ///
136    /// @param \a plotcmd must be "plot" or "replot".
137    ///
138    template <class T1, class T2>
139    void plot(const std::vector<T1>& y, const std::vector<T2>& x,
140              const std::string& plotcmd)
141    {
142      assert(x.size()==y.size() || x.empty());
143      assert(plotcmd=="plot" || plotcmd=="replot");
144      char name[]="/tmp/svnstatXXXXXX";
145      if (mkstemp(name) == -1){
146        throw GnuplotException(std::string("Failed to get unique filename: ") +
147                               name);
148      }
149      std::ofstream tmp(name);
150      if (tmp.bad())
151        throw GnuplotException(std::string("Failed to create file: ") + name);
152     
153      for (size_t i = 0; i<y.size() && (i<x.size() || x.empty()); ++i ){
154        if (x.empty())
155          tmp << y[i] << '\n';
156        else
157          tmp << x[i] << '\t' << y[i] << '\n';
158      }
159      tmp.close();
160      std::string cmdstring(plotcmd + " '" + name + "' u 1:2 title '" + 
161                              linetitle_ + "' with " + linestyle_ + "\n");
162      if (x.empty())
163        cmdstring = plotcmd + " '" + name + "' u 1 title '" + 
164          linetitle_ + "' with " + linestyle_ + "\n";
165       
166      command(cmdstring);
167      // need to keep track of created files since the gnuplot command
168      // is not executed until pclose on MacOSX, shouldn't the fflush
169      // fix this in the command() member function?
170      tempfiles_.push_back(name);
171    }
172
173    void tokenizer(const std::string& in, std::list<std::string>& tokens,
174                   const std::string& delimiters = ":");
175
176    // need to keep track of created files since the gnuplot command
177    // is not executed until pclose on MacOSX, shouldn't the fflush
178    // fix this in the command() member function?
179    std::list<std::string> tempfiles_;
180    std::vector<std::string> date_;
181    std::string date_input_format_; 
182    std::string date_output_format_; 
183    std::string gnuplot_binary_;
184    std::string linestyle_;
185    std::string linetitle_;
186    FILE* pipe_;
187};
188
189}} // end of namespace svnstat and namespace theplu
190
191#endif
Note: See TracBrowser for help on using the repository browser.