source: trunk/lib/Gnuplot.h @ 60

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

plotting vs date rather than revision

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