source: trunk/lib/Graph.cc @ 948

Last change on this file since 948 was 948, checked in by Peter Johansson, 12 years ago

dealing with the case when repo is imported using cvs2svn, in whcih case date of rev 0 becomes the date of the importion (which is after date of rev 1)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 4.6 KB
Line 
1// $Id: Graph.cc 948 2009-12-04 00:33:12Z peter $
2
3/*
4  Copyright (C) 2009 Jari Häkkinen, Peter Johansson
5
6  This file is part of svndigest, http://dev.thep.lu.se/svndigest
7
8  svndigest is free software; you can redistribute it and/or modify it
9  under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 3 of the License, or
11  (at your option) any later version.
12
13  svndigest is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with svndigest. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "Graph.h"
23
24#include "Date.h"
25
26#include <algorithm>
27#include <cmath>
28#include <sstream>
29
30namespace theplu {
31namespace svndigest {
32
33  std::vector<std::string> Graph::xticks_;
34
35  Graph::Graph(const std::string& filename)
36#ifdef HAVE_PLPLOT
37    : plots_(0), pls_(1,1,"svg",filename.c_str()), timeformat_("%y-%b"),
38      title_(filename), xmin_(0.0), xmax_(0.0), ymin_(0.0), ymax_(0.0)
39  {
40    legend_.reserve(20);
41    // we use color map 0 position 0 for background color
42    pls_.scolbga(255,255,255,0);
43    pls_.init();
44    pls_.adv(0);
45    pls_.vsta();
46  }
47#else
48{}
49#endif
50
51
52  Graph::~Graph(void)
53  {
54    print_legend();
55  }
56
57
58  bool Graph::date_xticks(void)
59  {
60    return xticks_.size() != 0;
61  }
62
63
64  void Graph::current_color(const legend_data& legend)
65  {
66    // we use color map 0 position 1 for current color
67#ifdef HAVE_PLPLOT
68    pls_.scol0a(1,legend.r,legend.g,legend.b,1.0);
69#endif
70  }
71
72
73  void Graph::current_color(unsigned char r, unsigned char g, unsigned char b)
74  {
75    // we use color map 0 position 1 for current color
76#ifdef HAVE_PLPLOT
77    pls_.scol0a(1,r,g,b,1.0);
78#endif
79  }
80
81
82  void Graph::plot(const std::vector<unsigned int>& y, const std::string& label,
83                   unsigned int lines)
84  {
85#ifdef HAVE_PLPLOT
86    if (!plots_) {
87      // date[0] is not the oldest when repo is imported with cvs2svn
88      xmin_= date_xticks() ? 
89        std::min( Date(xticks_[0]), Date(xticks_[1]) ).seconds() : 0;
90      xmax_= date_xticks() ? Date(xticks_.back()).seconds() : y.size();
91      xrange_=xmax_-xmin_;
92      yrange_=ymax_-ymin_;
93      pls_.wind(xmin_, xmax_, ymin_, ymax_);
94
95      // draw plot frame, x and y ticks only for the first plot
96      pls_.scol0a(2,0,0,0,1.0);
97      pls_.col0(2);
98
99      std::string xopt("bcnstv");
100      if (date_xticks()) {
101        pls_.timefmt(timeformat_.c_str());
102        xopt="bcnstd";
103      }
104
105      unsigned int ytickspacing=tick_spacing(ymax_-ymin_);
106      unsigned int xtickspacing=tick_spacing(xmax_-xmin_);
107      pls_.box(xopt.c_str(), xtickspacing, 1, "bcnstv", ytickspacing, 2);
108      pls_.lab("Date", "Number of lines", title_.c_str());
109    }
110    ++plots_;
111
112    pls_.col0(1);
113    for (unsigned int i=1; i<y.size(); ++i) {
114      PLFLT x0=i-1;
115      PLFLT x1=i;
116      if (date_xticks()) {
117        x0=Date(xticks_[i-1]).seconds();
118        x1=Date(xticks_[i]).seconds();
119      }
120      pls_.join(x0, y[i-1], x0, y[i]);
121      pls_.join(x0, y[i]  , x1, y[i]);
122    }
123
124    legend_data legend;
125    legend.label=label;
126    legend.lines=lines;
127    pls_.gcol0(1,legend.r,legend.g,legend.b);
128    legend_.push_back(legend);
129#endif
130  }
131
132
133  void Graph::print_legend(void)
134  {
135#ifdef HAVE_PLPLOT
136    PLFLT line_length=0.05*xrange_;
137    PLFLT x=xmin_+1.7*line_length;
138    unsigned char characteristic=log10(ymax_);
139    PLFLT legend_lines_length=0.016*xrange_*(characteristic+1);
140    PLFLT dx=0.005*xrange_;
141    PLFLT dy=0.003*yrange_;
142    unsigned int row=0;
143    std::reverse(legend_.begin(), legend_.end());
144    for (std::vector<legend_data>::const_iterator i=legend_.begin();
145         i!=legend_.end(); i++, ++row) {
146      PLFLT y=(0.95-0.04*row)*yrange_;
147      current_color(*i);
148      pls_.col0(1);
149      pls_.join(x-line_length, y-dy, x, y-dy);
150      std::stringstream ss;
151      ss << i->lines;
152      pls_.col0(2);
153      pls_.ptex(x+legend_lines_length+dx*2, y, 0, 0, 0, i->label.c_str());
154      pls_.ptex(x+legend_lines_length+dx  , y, 0, 0, 1, ss.str().c_str());
155    }
156#endif
157  }
158
159
160  void Graph::set_dates(const std::vector<std::string>& date)
161  {
162    xticks_=date;
163  }
164
165
166  unsigned int Graph::tick_spacing(const double range) const
167  {
168    double frac=range/5;
169    unsigned char characteristic= static_cast<unsigned char>(std::log10(frac));
170    unsigned int power=static_cast<unsigned int>(std::pow(10.0, characteristic));
171    unsigned char msn=static_cast<unsigned char>(frac/power);
172    return power*msn;
173  }
174
175
176  void Graph::timeformat(const std::string& format)
177  {
178    timeformat_=format;
179  }
180
181
182  const std::vector<std::string>& Graph::xticks(void)
183  {
184    return xticks_;
185  }
186
187
188  double Graph::ymax(double ymax)
189  {
190    return ymax_=ymax;
191  }
192
193}} // end of namespace svndigest and namespace theplu
Note: See TracBrowser for help on using the repository browser.