lib/StatsPlotter.cc

Code
Comments
Other
Rev Date Author Line
1290 12 Nov 10 peter 1 // $Id$
1290 12 Nov 10 peter 2
1290 12 Nov 10 peter 3 /*
1635 30 Mar 23 peter 4   Copyright (C) 2010, 2012, 2023 Peter Johansson
1290 12 Nov 10 peter 5
1290 12 Nov 10 peter 6   This file is part of svndigest, http://dev.thep.lu.se/svndigest
1290 12 Nov 10 peter 7
1290 12 Nov 10 peter 8   svndigest is free software; you can redistribute it and/or modify it
1290 12 Nov 10 peter 9   under the terms of the GNU General Public License as published by
1290 12 Nov 10 peter 10   the Free Software Foundation; either version 3 of the License, or
1290 12 Nov 10 peter 11   (at your option) any later version.
1290 12 Nov 10 peter 12
1290 12 Nov 10 peter 13   svndigest is distributed in the hope that it will be useful, but
1290 12 Nov 10 peter 14   WITHOUT ANY WARRANTY; without even the implied warranty of
1290 12 Nov 10 peter 15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1290 12 Nov 10 peter 16   General Public License for more details.
1290 12 Nov 10 peter 17
1290 12 Nov 10 peter 18   You should have received a copy of the GNU General Public License
1290 12 Nov 10 peter 19   along with svndigest. If not, see <http://www.gnu.org/licenses/>.
1290 12 Nov 10 peter 20 */
1290 12 Nov 10 peter 21
1619 12 Mar 23 peter 22 #include <config.h>
1619 12 Mar 23 peter 23
1290 12 Nov 10 peter 24 #include "StatsPlotter.h"
1290 12 Nov 10 peter 25
1290 12 Nov 10 peter 26 #include "Colors.h"
1290 12 Nov 10 peter 27 #include "Configuration.h"
1290 12 Nov 10 peter 28 #include "Functor.h"
1290 12 Nov 10 peter 29 #include "Graph.h"
1290 12 Nov 10 peter 30 #include "Stats.h"
1290 12 Nov 10 peter 31 #include "utility.h"
1290 12 Nov 10 peter 32
1290 12 Nov 10 peter 33 #include <algorithm>
1290 12 Nov 10 peter 34 #include <cassert>
1290 12 Nov 10 peter 35 #include <cstdlib>
1290 12 Nov 10 peter 36 #include <iostream>
1290 12 Nov 10 peter 37 #include <iterator>
1290 12 Nov 10 peter 38 #include <map>
1290 12 Nov 10 peter 39 #include <numeric>
1290 12 Nov 10 peter 40 #include <string>
1290 12 Nov 10 peter 41 #include <sstream>
1290 12 Nov 10 peter 42 #include <unistd.h>
1290 12 Nov 10 peter 43 #include <utility>
1290 12 Nov 10 peter 44 #include <vector>
1290 12 Nov 10 peter 45
1290 12 Nov 10 peter 46 namespace theplu{
1290 12 Nov 10 peter 47 namespace svndigest{
1290 12 Nov 10 peter 48
1290 12 Nov 10 peter 49
1290 12 Nov 10 peter 50   StatsPlotter::StatsPlotter(const Stats& stats)
1290 12 Nov 10 peter 51     :  stats_(stats)
1290 12 Nov 10 peter 52   {
1290 12 Nov 10 peter 53   }
1290 12 Nov 10 peter 54
1290 12 Nov 10 peter 55
1290 12 Nov 10 peter 56   StatsPlotter::~StatsPlotter(void)
1290 12 Nov 10 peter 57   {
1290 12 Nov 10 peter 58   }
1290 12 Nov 10 peter 59
1513 23 Sep 12 peter 60
1290 12 Nov 10 peter 61   std::string StatsPlotter::plot(const std::string& filename,
1614 15 Feb 23 peter 62                                  const std::string& linetype,
1614 15 Feb 23 peter 63                                  const std::string& title) const
1290 12 Nov 10 peter 64   {
1290 12 Nov 10 peter 65     const std::string& format = Configuration::instance().image_format();
1290 12 Nov 10 peter 66     if (format=="none")
1290 12 Nov 10 peter 67       return filename;
1614 15 Feb 23 peter 68     plot(filename, linetype, format, title);
1513 23 Sep 12 peter 69     const std::string& anchor_format =
1290 12 Nov 10 peter 70       Configuration::instance().image_anchor_format();
1290 12 Nov 10 peter 71
1290 12 Nov 10 peter 72     if (format!=anchor_format)
1290 12 Nov 10 peter 73       plot(filename, linetype, anchor_format);
1290 12 Nov 10 peter 74     return filename;
1290 12 Nov 10 peter 75   }
1290 12 Nov 10 peter 76
1290 12 Nov 10 peter 77
1290 12 Nov 10 peter 78   void StatsPlotter::plot(const std::string& filename,
1290 12 Nov 10 peter 79                           const std::string& linetype,
1614 15 Feb 23 peter 80                           const std::string& format,
1614 15 Feb 23 peter 81                           const std::string& title) const
1290 12 Nov 10 peter 82   {
1614 15 Feb 23 peter 83     Graph gp(filename+"."+format, format, title);
1290 12 Nov 10 peter 84     const Author2Vector* stat=NULL;
1290 12 Nov 10 peter 85     if (linetype=="total")
1290 12 Nov 10 peter 86       stat = &stats_.total_stats();
1290 12 Nov 10 peter 87     else if (linetype=="code")
1290 12 Nov 10 peter 88       stat = &stats_.code_stats();
1290 12 Nov 10 peter 89     else if (linetype=="comments")
1290 12 Nov 10 peter 90       stat = &stats_.comment_or_copy_stats();
1290 12 Nov 10 peter 91     else if (linetype=="empty")
1290 12 Nov 10 peter 92       stat = &stats_.other_stats();
1290 12 Nov 10 peter 93     assert(stat);
1290 12 Nov 10 peter 94     assert(stat->size());
1290 12 Nov 10 peter 95     assert(stat->find("all")!=stat->end());
1513 23 Sep 12 peter 96     const SumVector& total=stats_.get_vector(*stat, "all");
1290 12 Nov 10 peter 97     double yrange_max=1.03 * stats_.max_element(total) +1.0;
1290 12 Nov 10 peter 98     gp.ymax(yrange_max);
1290 12 Nov 10 peter 99
1290 12 Nov 10 peter 100     typedef std::vector<std::pair<std::string, SumVector> > vec_type;
1290 12 Nov 10 peter 101     vec_type author_cont;
1290 12 Nov 10 peter 102     author_cont.reserve(stat->size());
1513 23 Sep 12 peter 103     for (std::set<std::string>::const_iterator i=stats_.authors_.begin();
1290 12 Nov 10 peter 104          i != stats_.authors_.end(); ++i) {
1290 12 Nov 10 peter 105       assert(stat->find(*i)!=stat->end());
1290 12 Nov 10 peter 106       const SumVector& vec = stats_.get_vector(*stat,*i);
1290 12 Nov 10 peter 107       if (stats_.max_element(vec)) {
1290 12 Nov 10 peter 108         author_cont.push_back(std::make_pair(*i,vec));
1290 12 Nov 10 peter 109       }
1290 12 Nov 10 peter 110     }
1290 12 Nov 10 peter 111
1290 12 Nov 10 peter 112     LessReversed<SumVector> lr;
1513 23 Sep 12 peter 113     PairSecondCompare<std::string, SumVector, LessReversed<SumVector> >
1290 12 Nov 10 peter 114       compare(lr);
1290 12 Nov 10 peter 115     std::sort(author_cont.begin(), author_cont.end(), compare);
1290 12 Nov 10 peter 116
1290 12 Nov 10 peter 117     vec_type::iterator end(author_cont.end());
1290 12 Nov 10 peter 118     vec_type::iterator i(author_cont.begin());
1290 12 Nov 10 peter 119     const vec_type::size_type maxauthors=8;
1290 12 Nov 10 peter 120     int authskip=author_cont.size()-maxauthors;
1290 12 Nov 10 peter 121     if (authskip>1) {
1290 12 Nov 10 peter 122       // only use others if there is more than 1 author to be skipped,
1290 12 Nov 10 peter 123       // there is no reason to add only 1 author to others.
1290 12 Nov 10 peter 124       vec_type::iterator j(i);
1290 12 Nov 10 peter 125       i+=authskip;
1290 12 Nov 10 peter 126       SumVector others;
1290 12 Nov 10 peter 127       sum(j, i, others, PairValuePlusAssign<std::string, SumVector>());
1290 12 Nov 10 peter 128       unsigned char r, g, b;
1290 12 Nov 10 peter 129       std::string label("others");
1290 12 Nov 10 peter 130       Colors::instance().get_color(label, r,g,b);
1290 12 Nov 10 peter 131       gp.current_color(r,g,b);
1495 27 Aug 12 peter 132       gp.plot(others, label, others.size() ? others.back() : 0);
1290 12 Nov 10 peter 133     }
1290 12 Nov 10 peter 134     for ( ; i!=end; ++i) {
1290 12 Nov 10 peter 135       unsigned char r, g, b;
1290 12 Nov 10 peter 136       Colors::instance().get_color(i->first,r,g,b);
1290 12 Nov 10 peter 137       gp.current_color(r,g,b);
1290 12 Nov 10 peter 138       gp.plot(i->second, i->first, stats_.get_back(*stat, i->first));
1290 12 Nov 10 peter 139     }
1290 12 Nov 10 peter 140     gp.current_color(255,0,0);
1290 12 Nov 10 peter 141     gp.plot(total, "total", stats_.get_back(*stat, "all"));
1290 12 Nov 10 peter 142   }
1290 12 Nov 10 peter 143
1290 12 Nov 10 peter 144
1290 12 Nov 10 peter 145   void StatsPlotter::plot_summary(const std::string& filename) const
1290 12 Nov 10 peter 146   {
1290 12 Nov 10 peter 147     const std::string& format = Configuration::instance().image_format();
1290 12 Nov 10 peter 148     if (format=="none")
1290 12 Nov 10 peter 149       return;
1290 12 Nov 10 peter 150     plot_summary(filename, format);
1513 23 Sep 12 peter 151     const std::string& anchor_format =
1290 12 Nov 10 peter 152       Configuration::instance().image_anchor_format();
1290 12 Nov 10 peter 153
1290 12 Nov 10 peter 154     if (format!=anchor_format)
1290 12 Nov 10 peter 155       plot_summary(filename, anchor_format);
1290 12 Nov 10 peter 156   }
1290 12 Nov 10 peter 157
1290 12 Nov 10 peter 158
1513 23 Sep 12 peter 159   void StatsPlotter::plot_summary(const std::string& filename,
1290 12 Nov 10 peter 160                                   const std::string& format) const
1290 12 Nov 10 peter 161   {
1614 15 Feb 23 peter 162     Graph gp(filename+"."+format, format, "");
1290 12 Nov 10 peter 163     const SumVector& total = stats_.get_vector(stats_.total_stats(), "all");
1290 12 Nov 10 peter 164     double yrange_max=1.03*stats_.max_element(total)+1;
1290 12 Nov 10 peter 165     gp.ymax(yrange_max);
1513 23 Sep 12 peter 166
1290 12 Nov 10 peter 167     const SumVector& x(stats_.get_vector(stats_.code_stats(), "all"));
1290 12 Nov 10 peter 168     gp.current_color(255,255,0);
1290 12 Nov 10 peter 169     gp.plot(x, "code", x.back());
1290 12 Nov 10 peter 170
1513 23 Sep 12 peter 171     const SumVector& y = stats_.get_vector(stats_.comment_or_copy_stats(),
1290 12 Nov 10 peter 172                                            "all");
1290 12 Nov 10 peter 173     gp.current_color(0,0,255);
1290 12 Nov 10 peter 174     gp.plot(y, "comment", y.back());
1290 12 Nov 10 peter 175
1290 12 Nov 10 peter 176     const SumVector& z = stats_.get_vector(stats_.other_stats(), "all");
1290 12 Nov 10 peter 177     gp.current_color(0,255,0);
1290 12 Nov 10 peter 178     gp.plot(z, "other", z.back());
1290 12 Nov 10 peter 179
1290 12 Nov 10 peter 180     gp.current_color(255,0,0);
1290 12 Nov 10 peter 181     gp.plot(total, "total", total.back());
1290 12 Nov 10 peter 182   }
1290 12 Nov 10 peter 183
1290 12 Nov 10 peter 184 }} // end of namespace svndigest and namespace theplu