source: trunk/lib/Gnuplot.h @ 745

Last change on this file since 745 was 693, checked in by Jari Häkkinen, 13 years ago

Fixes #339. Change to GPLv3.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.6 KB
Line 
1#ifndef _theplu_svndigest_gnuplot_
2#define _theplu_svndigest_gnuplot_
3
4// $Id: Gnuplot.h 693 2008-09-11 20:42:56Z jari $
5
6/*
7  Copyright (C) 2006 Jari Häkkinen, Peter Johansson
8
9  This file is part of svndigest, http://dev.thep.lu.se/svndigest
10
11  svndigest is free software; you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation; either version 3 of the License, or
14  (at your option) any later version.
15
16  svndigest is distributed in the hope that it will be useful, but
17  WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20
21  You should have received a copy of the GNU General Public License
22  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
23*/
24
25#include <cassert>
26#include <cstdio>
27#include <list>
28#include <stdexcept>
29#include <sstream>
30#include <string>
31#include <vector>
32
33
34#include <iostream>
35
36namespace theplu {
37namespace svndigest {
38
39  ///
40  /// If something goes wrong in the use of the Gnuplot class, a
41  /// GnuplotException is thrown.
42  ///
43  struct GnuplotException : public std::runtime_error
44  { inline GnuplotException(const std::string& msg) : runtime_error(msg) {} };
45
46  ///
47  /// The Gnuplot class creates a pipe to 'gnuplot' and facilitates
48  /// communication with the gnuplot binary.
49  ///
50  /// @see GnuplotFE
51  ///
52  class Gnuplot
53  {
54  public:
55    ///
56    /// This constructor sets up the pipe to the first gnuplot
57    /// executable found in the PATH environment variable. The PATH
58    /// variable must exist.
59    ///
60    /// @throw Throws a GnuplotException if a no PATH variable is
61    /// found, if the gnuplot binary cannot be found, or if a pipe
62    /// cannot to the gnuplot binary cannot be established.
63    ///
64    Gnuplot(void);
65
66    ///
67    /// The destructor, closes the pipe to the gnuplot binary.
68    ///
69    virtual ~Gnuplot(void);
70
71    ///
72    /// @brief Send arbitrary commands to Gnuplot.
73    ///
74    /// @return 0 on success (underlying fputs, fputc, and fflush are
75    /// succesful), EOF otherwise.
76    ///
77    int command(const std::string&);
78
79    ///
80    /// Set the \a style of the line in the subsequent plot or
81    /// replot calls. The setting applies until this function is
82    /// called again.
83    ///
84    /// @note The \a style is not checked to be valid.
85    ///
86    inline void linestyle(const std::string& style) { linestyle_=style; }
87
88    ///
89    /// Set the \a title of the line in the subsequent plot or
90    /// replot calls. The setting applies until this function is
91    /// called again.
92    ///
93    inline void linetitle(const std::string& title) { linetitle_=title; }
94
95    ///
96    /// Plot the data \a y as a function of \a x using the Gnuplot
97    /// 'plot' command. The \a x vector can be omitted as in normal
98    /// Gnuplot usage.
99    ///
100    /// @return 0 on success, EOF otherwise.
101    ///
102    template <class T1, class T2>
103    int plot(const std::vector<T1>& y, const std::vector<T2>& x)
104    { return plot(y,x,"plot"); }
105
106    template <class T1>
107    int plot(const std::vector<T1>& y,const std::vector<T1>& x=std::vector<T1>())
108    { return plot(y,x,"plot"); }
109
110    ///
111    /// Plot the data \a y as a function of \a x using the Gnuplot
112    /// 'replot' command. The \a x vector can be omitted as in normal
113    /// Gnuplot usage.
114    ///
115    /// @return 0 on success, EOF otherwise.
116    ///
117    template <class T1, class T2>
118    int replot(const std::vector<T1>& y, const std::vector<T2>& x)
119    { return plot(y,x,"replot"); }
120
121    template <class T1>
122    int replot(const std::vector<T1>& y,
123              const std::vector<T1>& x=std::vector<T1>())
124    { return plot(y,x,"replot"); }
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    int 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
144      std::ostringstream cmdstring;
145      cmdstring << plotcmd << " '-' u 1:2 title '" << linetitle_ << "' with "
146                << linestyle_ << '\n';
147      for (size_t i=0; i<y.size(); ++i) {
148        if (!x.empty())
149          cmdstring << x[i] << '\t';
150        else
151          cmdstring << i << '\t';
152        cmdstring << y[i] << '\n';
153      }
154      cmdstring << "e\n";
155
156      return command(cmdstring.str());
157    }
158
159    void tokenizer(const std::string& in, std::list<std::string>& tokens,
160                   const std::string& delimiters = ":");
161
162    std::string gnuplot_binary_;
163    std::string linestyle_;
164    std::string linetitle_;
165    FILE* pipe_;
166};
167
168}} // end of namespace svndigest and namespace theplu
169
170#endif
Note: See TracBrowser for help on using the repository browser.