[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [6589] Add averages sub-header to the group quote report (
From: |
gchicares |
Subject: |
[lmi-commits] [6589] Add averages sub-header to the group quote report (VZ) |
Date: |
Fri, 13 May 2016 14:04:33 +0000 (UTC) |
Revision: 6589
http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=6589
Author: chicares
Date: 2016-05-13 14:04:33 +0000 (Fri, 13 May 2016)
Log Message:
-----------
Add averages sub-header to the group quote report (VZ)
Modified Paths:
--------------
lmi/trunk/group_quote_pdf_gen_wx.cpp
Modified: lmi/trunk/group_quote_pdf_gen_wx.cpp
===================================================================
--- lmi/trunk/group_quote_pdf_gen_wx.cpp 2016-05-13 14:02:32 UTC (rev
6588)
+++ lmi/trunk/group_quote_pdf_gen_wx.cpp 2016-05-13 14:04:33 UTC (rev
6589)
@@ -526,7 +526,7 @@
,wxHtmlWinParser& html_parser
,int* pos_y
);
- void output_table_totals
+ void output_aggregate_values
(wxPdfDC& pdf_dc
,wx_table_generator& table_gen
,int* pos_y
@@ -599,6 +599,68 @@
};
totals_data totals_;
+ class averages_data
+ {
+ public:
+ averages_data()
+ {
+ for(int col = e_first_totalled_column; col < e_col_max; ++col)
+ {
+ int const n = index_from_col(col);
+ values_counts_[n] = 0;
+ mean_values_[n] = 0.0;
+ }
+ }
+
+ // Adds 1000*premium/face_amount to the values over which the mean
+ // value is computed. The value is silently ignored if the face amount
+ // is zero, which can happen if this column is not used at all in this
+ // quote.
+ void add_data_point(int col, double premium, double face_amount)
+ {
+ if(face_amount == 0.0)
+ {
+ return;
+ }
+
+ double const d = 1000.0*premium / face_amount;
+
+ // Iteratively compute the mean of the sequence of values using the
+ // simplified (as we don't need the standard deviation here)
+ // version of the algorithm described in Knuth's "The Art of
+ // Computer Programming, Volume 2: Seminumerical Algorithms",
+ // section 4.2.2.
+ //
+ // The algorithm defines the sequence M(k)
+ //
+ // M(1) = x(1), M(k) = M(k-1) + (x(k) - M(k-1)) / k
+ //
+ // where x(k) is the k-th value and the mean value of the sequence
+ // up to the member N is simply the last value M(N).
+ int const n = index_from_col(col);
+ if(values_counts_[n]++ == 0)
+ {
+ mean_values_[n] = d;
+ }
+ else
+ {
+ mean_values_[n] += (d - mean_values_[n]) / values_counts_[n];
+ }
+ }
+
+ double mean(int col) const
+ {
+ return mean_values_[index_from_col(col)];
+ }
+
+ private:
+ static int index_from_col(int col) { return col -
e_first_totalled_column; }
+
+ unsigned values_counts_[e_col_max - e_first_totalled_column];
+ double mean_values_ [e_col_max - e_first_totalled_column];
+ };
+ averages_data averages_;
+
struct page_metrics
{
page_metrics()
@@ -831,6 +893,10 @@
{
totals_.total(col, z);
}
+ else
+ {
+ averages_.add_data_point(col, z, basic_face_amount);
+ }
}
break;
case e_col_supplemental_face_amount:
@@ -850,6 +916,10 @@
{
totals_.total(col, z);
}
+ else
+ {
+ averages_.add_data_point(col, z, suppl_face_amount);
+ }
}
break;
case e_col_total_face_amount:
@@ -869,6 +939,10 @@
{
totals_.total(col, z);
}
+ else
+ {
+ averages_.add_data_point(col, z, total_face_amount);
+ }
}
break;
case e_col_max:
@@ -1020,7 +1094,7 @@
table_gen.add_column(header, cd.widest_text_);
}
- output_table_totals(pdf_dc, table_gen, &pos_y);
+ output_aggregate_values(pdf_dc, table_gen, &pos_y);
int const y_before_header = pos_y;
table_gen.output_header(&pos_y);
@@ -1310,7 +1384,7 @@
*pos_y += summary_height;
}
-void group_quote_pdf_generator_wx::output_table_totals
+void group_quote_pdf_generator_wx::output_aggregate_values
(wxPdfDC& pdf_dc
,wx_table_generator& table_gen
,int* pos_y
@@ -1323,8 +1397,10 @@
table_gen.output_vert_separator(e_col_max, y);
y += table_gen.row_height();
+ int const y_next = y + table_gen.row_height();
table_gen.output_vert_separator(e_col_number, y);
+ table_gen.output_vert_separator(e_col_number, y_next);
// Render "Census" in bold.
wxDCFontChanger set_bold_font(pdf_dc, pdf_dc.GetFont().Bold());
@@ -1334,7 +1410,7 @@
,wxALIGN_LEFT
);
- // And the totals in bold italic: notice that there is no need to create
+ // And the aggregates in bold italic: notice that there is no need to
create
// another wxDCFontChanger here, the original font will be restored by the
// one just above anyhow.
pdf_dc.SetFont(pdf_dc.GetFont().Italic());
@@ -1346,6 +1422,12 @@
,wxALIGN_RIGHT
);
+ pdf_dc.DrawLabel
+ ("Average Cost per $1000:"
+ ,table_gen.text_rect(e_first_totalled_column - 1, y_next)
+ ,wxALIGN_RIGHT
+ );
+
for(int col = e_first_totalled_column; col < e_col_max; ++col)
{
int const num_dec =
@@ -1365,12 +1447,27 @@
,"$"
,ledger_format(totals_.total(col), f)
);
+
+ // Only premium columns have averages, but we must output something for
+ // all cells to ensure that we use homogeneous background.
+ double const average = averages_.mean(col);
+ std::string lhs, rhs;
+ if(average != 0.0)
+ {
+ lhs = "$";
+ rhs = ledger_format(average, f);
+ }
+
+ table_gen.output_highlighted_cell(col, y_next, lhs, rhs);
}
table_gen.output_vert_separator(e_col_max, y);
table_gen.output_horz_separator(e_col_number, e_col_max, y);
- y += table_gen.row_height();
+ table_gen.output_vert_separator(e_col_max, y_next);
+ table_gen.output_horz_separator(e_first_totalled_column, e_col_max,
y_next);
+
+ y = y_next + table_gen.row_height();
}
void group_quote_pdf_generator_wx::output_footer
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lmi-commits] [6589] Add averages sub-header to the group quote report (VZ),
gchicares <=