source: trunk/lib/Gnuplot.h @ 63

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

Fixed problem with mapping revison to date. Removed mkstemps. name of
png files are now in line with their html file name. Binary works on
svnstat, but is asserted on c++_tools.

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