source: trunk/lib/Graph.cc @ 1330

Last change on this file since 1330 was 1330, checked in by Peter Johansson, 11 years ago

change confusing function and variable from xticks to dates (the vector holds the date/time for each revision).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 5.4 KB
Line 
1// $Id: Graph.cc 1330 2011-01-27 01:49:35Z peter $
2
3/*
4  Copyright (C) 2009, 2010 Jari Häkkinen, Peter Johansson
5  Copyright (C) 2011 Peter Johansson
6
7  This file is part of svndigest, http://dev.thep.lu.se/svndigest
8
9  svndigest is free software; you can redistribute it and/or modify it
10  under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 3 of the License, or
12  (at your option) any later version.
13
14  svndigest is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#include "Graph.h"
24
25#include "Date.h"
26
27#include <algorithm>
28#include <cassert>
29#include <cmath>
30#include <sstream>
31
32namespace theplu {
33namespace svndigest {
34
35  svn_revnum_t Graph::rev_max_=0;
36  svn_revnum_t Graph::rev_min_=0;
37  std::vector<time_t> Graph::dates_;
38
39  Graph::Graph(const std::string& filename, const std::string& format)
40#ifdef HAVE_PLPLOT
41    : plots_(0), pls_(1,1,format.c_str(),filename.c_str()),
42      title_(filename), xmin_(0.0), xmax_(0.0), ymin_(0.0), ymax_(0.0)
43  {
44    // should match the maximum number of authors plotted, change this
45    // when the maximum number of authors becomes configurable
46    legend_.reserve(10);
47    // we use color map 0 position 0 for background color
48    pls_.scolbga(255,255,255,0);
49    pls_.setopt("geometry", "600x500");
50    pls_.init();
51    pls_.adv(0);
52    pls_.vsta();
53    pls_.syax(6,0);
54  }
55#else
56{}
57#endif
58
59
60  Graph::~Graph(void)
61  {
62    print_legend();
63  }
64
65
66  bool Graph::date_xticks(void)
67  {
68    return dates_.size() != 0;
69  }
70
71
72  void Graph::current_color(const legend_data& legend)
73  {
74    // we use color map 0 position 1 for current color
75#ifdef HAVE_PLPLOT
76    pls_.scol0a(1,legend.r,legend.g,legend.b,1.0);
77#endif
78  }
79
80
81  void Graph::current_color(unsigned char r, unsigned char g, unsigned char b)
82  {
83    // we use color map 0 position 1 for current color
84#ifdef HAVE_PLPLOT
85    pls_.scol0a(1,r,g,b,1.0);
86#endif
87  }
88
89
90  void Graph::plot(const SumVector& y, const std::string& label,
91                   unsigned int lines)
92  {
93#ifdef HAVE_PLPLOT
94    if (!plots_) {
95      assert(!date_xticks() || rev_min_<dates_.size());
96      assert(!date_xticks() || dates_[rev_min_]);
97      assert(rev_min_<dates_.size() || !date_xticks());
98      xmin_= date_xticks() ? dates_[rev_min_] : rev_min_;
99      assert(rev_max_<dates_.size() || !date_xticks());
100      xmax_= date_xticks() ? dates_[rev_max_] : rev_max_;
101      xrange_=xmax_-xmin_;
102      yrange_=ymax_-ymin_;
103      pls_.wind(xmin_, xmax_, ymin_, ymax_);
104
105      // draw plot frame, x and y ticks only for the first plot
106      pls_.scol0a(2,0,0,0,1.0);
107      pls_.col0(2);
108
109      std::string xopt("bcnstv");
110      if (date_xticks()) {
111        pls_.timefmt("%Y-%b");
112        xopt="bcnstd";
113      }
114
115      pls_.box(xopt.c_str(), 0, 1, "bcnstv", 0, 2);
116      pls_.lab("Date", "Number of lines", title_.c_str());
117    }
118    ++plots_;
119
120    pls_.col0(1);
121
122    SumVector::const_iterator iter = y.begin();
123    svn_revnum_t x0=rev_min_;
124    PLFLT y0=0;
125    for (; iter!=y.end(); ++iter) {
126      staircase(x0, y0, iter->first, iter->second);
127      x0 = iter->first;
128      y0 = iter->second;
129    }
130    staircase(x0, y0, rev_max_, y0);
131
132    legend_data legend;
133    legend.label=label;
134    legend.lines=lines;
135    pls_.gcol0(1,legend.r,legend.g,legend.b);
136    legend_.push_back(legend);
137#endif
138  }
139
140
141  void Graph::print_legend(void)
142  {
143#ifdef HAVE_PLPLOT
144    PLFLT line_length=0.05*xrange_;
145    PLFLT x=xmin_+1.7*line_length;
146    unsigned char characteristic=log10(ymax_);
147    PLFLT legend_lines_length=0.016*xrange_*(characteristic+1);
148    PLFLT dx=0.005*xrange_;
149    PLFLT dy=0.003*yrange_;
150    unsigned int row=0;
151    std::vector<legend_data>::const_reverse_iterator end = legend_.rend();
152    for (std::vector<legend_data>::const_reverse_iterator i=legend_.rbegin();
153         i!=end; ++i, ++row) {
154      PLFLT y=(0.95-0.04*row)*yrange_;
155      current_color(*i);
156      pls_.col0(1);
157      pls_.join(x-line_length, y-dy, x, y-dy);
158      std::stringstream ss;
159      ss << i->lines;
160      pls_.col0(2);
161      pls_.ptex(x+legend_lines_length+dx*2, y, 0, 0, 0, i->label.c_str());
162      pls_.ptex(x+legend_lines_length+dx  , y, 0, 0, 1, ss.str().c_str());
163    }
164#endif
165  }
166
167
168  void Graph::rev_max(svn_revnum_t rev)
169  {
170    rev_max_ = rev;
171  }
172
173
174  svn_revnum_t Graph::rev_max(void)
175  {
176    return rev_max_;
177  }
178
179
180  void Graph::rev_min(svn_revnum_t rev)
181  {
182    rev_min_ = rev;
183  }
184
185
186  svn_revnum_t Graph::rev_min(void)
187  {
188    return rev_min_;
189  }
190
191
192  void Graph::set_dates(const std::vector<time_t>& date)
193  {
194    dates_=date;
195  }
196
197
198  void Graph::staircase(svn_revnum_t rev0, PLFLT y0, 
199                        svn_revnum_t rev1, PLFLT y1)
200  {
201    PLFLT x0 = rev0;
202    PLFLT x1 = rev1;
203    if (date_xticks()) {
204      assert(rev0<dates_.size());
205      assert(dates_[rev0]);
206      x0 = dates_[rev0];
207      assert(rev1<dates_.size());
208      assert(dates_[rev1]);
209      x1 = dates_[rev1];
210    }
211#ifdef HAVE_PLPLOT
212    // join {x0,y0} with {x1,y1} via {x1,y0}
213    pls_.join(x0,y0,x1,y0);
214    pls_.join(x1,y0,x1,y1);
215#endif
216  }
217
218
219  unsigned int Graph::tick_spacing(const double range) const
220  {
221    // range = msn * 10^characteristic = msn * power
222    unsigned char characteristic= static_cast<unsigned char>(std::log10(range));
223    double power = std::pow(10.0, characteristic);
224    double msn = range/power;
225    if (msn>=5.0)
226      return power;
227    if (msn>=2.0)
228      return 0.5 * power;
229    return 0.2 * power;
230  }
231
232
233  const std::vector<time_t>& Graph::dates(void)
234  {
235    return dates_;
236  }
237
238
239  double Graph::ymax(double ymax)
240  {
241    return ymax_=ymax;
242  }
243
244}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.