Commit 0a49d779 authored by twanvl's avatar twanvl

A box with the mean value in bar graphs.

parent 7c70535f
...@@ -20,6 +20,7 @@ DECLARE_TYPEOF_COLLECTION(int); ...@@ -20,6 +20,7 @@ DECLARE_TYPEOF_COLLECTION(int);
DECLARE_TYPEOF_COLLECTION(vector<int>); DECLARE_TYPEOF_COLLECTION(vector<int>);
DECLARE_TYPEOF_COLLECTION(String); DECLARE_TYPEOF_COLLECTION(String);
DECLARE_TYPEOF_COLLECTION(UInt); DECLARE_TYPEOF_COLLECTION(UInt);
DECLARE_TYPEOF_COLLECTION(pair<String COMMA String>);
DECLARE_TYPEOF(map<String COMMA UInt>); DECLARE_TYPEOF(map<String COMMA UInt>);
template <typename T> inline T sgn(T v) { return v < 0 ? -1 : 1; } template <typename T> inline T sgn(T v) { return v < 0 ? -1 : 1; }
...@@ -72,6 +73,7 @@ GraphData::GraphData(const GraphDataPre& d) ...@@ -72,6 +73,7 @@ GraphData::GraphData(const GraphDataPre& d)
if (a->numeric) { if (a->numeric) {
// TODO: start at something other than 0? // TODO: start at something other than 0?
// TODO: support fractions? // TODO: support fractions?
a->mean = 0;
size_t left = counts.size(); size_t left = counts.size();
int i = 0; int i = 0;
while (!counts.empty() && i < 100) { while (!counts.empty() && i < 100) {
...@@ -84,10 +86,12 @@ GraphData::GraphData(const GraphDataPre& d) ...@@ -84,10 +86,12 @@ GraphData::GraphData(const GraphDataPre& d)
a->groups.push_back(GraphGroup(is, it->second)); a->groups.push_back(GraphGroup(is, it->second));
a->max = max(a->max, it->second); a->max = max(a->max, it->second);
a->total += it->second; a->total += it->second;
a->mean += i * it->second;
counts.erase(is); counts.erase(is);
left--; left--;
} }
} }
a->mean /= a->total;
// drop empty tail // drop empty tail
while (a->groups.size() > 1 && a->groups.back().size == 0) { while (a->groups.size() > 1 && a->groups.back().size == 0) {
a->groups.pop_back(); a->groups.pop_back();
...@@ -555,6 +559,58 @@ void ScatterPieGraph::draw(RotatedDC& dc, const vector<int>& current, DrawLayer ...@@ -555,6 +559,58 @@ void ScatterPieGraph::draw(RotatedDC& dc, const vector<int>& current, DrawLayer
} }
// ----------------------------------------------------------------------------- : Graph Stats table
void GraphStats::setData(const GraphDataP& d) {
Graph1D::setData(d);
// update values
GraphAxis& axis = axis_data();
values.clear();
if (!axis.numeric) return;
values.push_back(make_pair(_("max"), axis.groups.back().name));
values.push_back(make_pair(_("mean"), String::Format(_("%.2f"), axis.mean)));
}
RealSize GraphStats::determineSize(RotatedDC& dc) const {
if (values.empty()) return RealSize(-1,-1);
dc.SetFont(*wxNORMAL_FONT);
item_size = RealSize(0,0);
label_width = 0;
FOR_EACH_CONST(v, values) {
RealSize this_item_size = dc.GetTextExtent(v.first);
double this_label_width = this_item_size.width + 3;
this_item_size = dc.GetTextExtent(v.second);
this_item_size = RealSize(this_item_size.width + 6, this_item_size.height + 5);
item_size = piecewise_max(item_size, this_item_size);
label_width = max(label_width, this_label_width);
}
item_size.width += label_width;
size = RealSize(item_size.width + 2, values.size() * item_size.height + 3); // margins
return size;
}
void GraphStats::draw(RotatedDC& dc, int current, DrawLayer layer) const {
if (values.empty()) return;
if (!size.width) determineSize(dc);
if (layer == LAYER_VALUES) {
RealRect rect = dc.getInternalRect();
RealPoint pos = align_in_rect(alignment, size, rect);
Color fg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
Color bg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
// draw border
dc.SetBrush(bg);
dc.DrawRectangle(RealRect(pos,size));
// draw items
dc.SetFont(*wxNORMAL_FONT);
dc.SetPen(fg);
double y = pos.y + 1;
FOR_EACH_CONST(v, values) {
dc.DrawText(v.first, RealPoint(pos.x + 3, y + 2));
dc.DrawText(v.second, RealPoint(pos.x + 3 + label_width, y + 2));
y += item_size.height;
}
}
}
// ----------------------------------------------------------------------------- : Graph Legend // ----------------------------------------------------------------------------- : Graph Legend
...@@ -814,6 +870,7 @@ void GraphControl::setLayout(GraphType type, bool force) { ...@@ -814,6 +870,7 @@ void GraphControl::setLayout(GraphType type, bool force) {
combined->add(new_intrusive2<GraphValueAxis>(0, true)); combined->add(new_intrusive2<GraphValueAxis>(0, true));
combined->add(new_intrusive2<GraphLabelAxis>(0, HORIZONTAL)); combined->add(new_intrusive2<GraphLabelAxis>(0, HORIZONTAL));
combined->add(new_intrusive1<BarGraph>(0)); combined->add(new_intrusive1<BarGraph>(0));
combined->add(new_intrusive2<GraphStats>(0, ALIGN_TOP_RIGHT));
graph = new_intrusive5<GraphWithMargins>(combined, 23,8,7,20); graph = new_intrusive5<GraphWithMargins>(combined, 23,8,7,20);
break; break;
} case GRAPH_TYPE_PIE: { } case GRAPH_TYPE_PIE: {
......
...@@ -58,6 +58,7 @@ class GraphAxis : public IntrusivePtrBase<GraphAxis> { ...@@ -58,6 +58,7 @@ class GraphAxis : public IntrusivePtrBase<GraphAxis> {
, numeric(numeric) , numeric(numeric)
, max(0) , max(0)
, total(0) , total(0)
, mean(0)
, colors(colors) , colors(colors)
, order(order) , order(order)
{} {}
...@@ -68,6 +69,7 @@ class GraphAxis : public IntrusivePtrBase<GraphAxis> { ...@@ -68,6 +69,7 @@ class GraphAxis : public IntrusivePtrBase<GraphAxis> {
bool numeric; ///< Numeric axis? bool numeric; ///< Numeric axis?
UInt max; ///< Maximum size of the groups UInt max; ///< Maximum size of the groups
UInt total; ///< Sum of the size of all groups UInt total; ///< Sum of the size of all groups
double mean; ///< Mean value, only for numeric axes
const map<String,Color>* colors; ///< Colors for each choice (optional) const map<String,Color>* colors; ///< Colors for each choice (optional)
const vector<String>* order; ///< Order of the items (optional) const vector<String>* order; ///< Order of the items (optional)
}; };
...@@ -231,6 +233,22 @@ class GraphLegend : public Graph1D { ...@@ -231,6 +233,22 @@ class GraphLegend : public Graph1D {
bool reverse; bool reverse;
}; };
/// Simple statistics like the mean
class GraphStats : public Graph1D {
public:
inline GraphStats(size_t axis, Alignment alignment)
: Graph1D(axis), alignment(alignment)
{}
virtual RealSize determineSize(RotatedDC& dc) const;
virtual void draw(RotatedDC& dc, int current, DrawLayer layer) const;
virtual void setData(const GraphDataP& d);
private:
mutable RealSize size, item_size;
mutable double label_width;
Alignment alignment;
vector<pair<String,String> > values;
};
//class GraphTable { //class GraphTable {
//}; //};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment