From f235eeb1007104eccdd7ba2a5610b9f9dee2d5d9 Mon Sep 17 00:00:00 2001 From: twanvl Date: Fri, 11 Jul 2008 16:38:14 +0000 Subject: [PATCH] Non-integer numeric values are sorted correctly in graphs git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1020 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/gui/control/graph.cpp | 59 ++++++++++++++++++++++++++++----------- src/gui/control/graph.hpp | 3 ++ 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/gui/control/graph.cpp b/src/gui/control/graph.cpp index e2807c0b..c8fa9437 100644 --- a/src/gui/control/graph.cpp +++ b/src/gui/control/graph.cpp @@ -22,7 +22,6 @@ DECLARE_TYPEOF_COLLECTION(vector); DECLARE_TYPEOF_COLLECTION(String); DECLARE_TYPEOF_COLLECTION(UInt); DECLARE_TYPEOF_COLLECTION(pair); -DECLARE_TYPEOF(map); template inline T sgn(T v) { return v < 0 ? -1 : 1; } @@ -30,6 +29,14 @@ template inline T sgn(T v) { return v < 0 ? -1 : 1; } DEFINE_EVENT_TYPE(EVENT_GRAPH_SELECT); +// ----------------------------------------------------------------------------- : GraphAxis + +void GraphAxis::addGroup(const String& name, UInt size) { + groups.push_back(GraphGroup(name, size)); + max = std::max(max, size); + total += size; +} + // ----------------------------------------------------------------------------- : GraphData GraphElement::GraphElement(const String& v1) { @@ -59,6 +66,11 @@ void GraphDataPre::splitList(size_t axis) { } +struct SmartLess{ + inline operator () (const String& a, const String& b) const { return smart_less(a,b); } +}; +DECLARE_TYPEOF(map); + GraphData::GraphData(const GraphDataPre& d) : axes(d.axes) { @@ -67,11 +79,33 @@ GraphData::GraphData(const GraphDataPre& d) // find groups on each axis size_t i = 0; FOR_EACH(a, axes) { - map counts; // note: default constructor for UInt() does initialize to 0 + map counts; // note: default constructor for UInt() does initialize to 0 FOR_EACH_CONST(e, d.elements) { counts[e->values[i]] += 1; } if (a->numeric) { + // Add all values, calculate mean of the numeric ones + UInt numeric_count = 0; + int prev = 0; + FOR_EACH(c, counts) { + // numeric? + double d; + if (c.first.ToDouble(&d)) { + // update mean + a->mean += d * c.second; + numeric_count += c.second; + // add 0 bars before this value + int next = (int)floor(d); + for (int i = prev ; i < next ; i++) { + a->addGroup(String()<addGroup(c.first, c.second); + } + a->mean /= numeric_count; + /* // TODO: start at something other than 0? // TODO: support fractions? a->mean = 0; @@ -82,17 +116,16 @@ GraphData::GraphData(const GraphDataPre& d) map::const_iterator it = counts.find(is); if (it == counts.end()) { // not found, add a 0 bar - a->groups.push_back(GraphGroup(is, 0)); + a->addGroup(is, 0); } else { - a->groups.push_back(GraphGroup(is, it->second)); - a->max = max(a->max, it->second); - a->total += it->second; + a->addGroup(is, it->second); a->mean += i * it->second; counts.erase(is); left--; } i++; } + UInt numeric_count = a->total; a->mean /= a->total; // drop empty tail while (a->groups.size() > 1 && a->groups.back().size == 0) { @@ -100,23 +133,17 @@ GraphData::GraphData(const GraphDataPre& d) } // Also keep non-numeric entries FOR_EACH(c, counts) { - a->groups.push_back(GraphGroup(c.first, c.second)); - a->max = max(a->max, c.second); - a->total += c.second; + a->addGroup(c.first, c.second); } + */ } else if (a->order) { // specific group order FOR_EACH_CONST(gn, *a->order) { - UInt count = counts[gn]; - a->groups.push_back(GraphGroup(gn, count)); - a->max = max(a->max, count); - a->total += count; + a->addGroup(gn, counts[gn]); } } else { FOR_EACH(c, counts) { - a->groups.push_back(GraphGroup(c.first, c.second)); - a->max = max(a->max, c.second); - a->total += c.second; + a->addGroup(c.first, c.second); } } // colors diff --git a/src/gui/control/graph.hpp b/src/gui/control/graph.hpp index 3ff2e572..4a52bfa1 100644 --- a/src/gui/control/graph.hpp +++ b/src/gui/control/graph.hpp @@ -72,6 +72,9 @@ class GraphAxis : public IntrusivePtrBase { double mean; ///< Mean value, only for numeric axes const map* colors; ///< Colors for each choice (optional) const vector* order; ///< Order of the items (optional) + + /// Add a graph group + void addGroup(const String& name, UInt size); }; /// A single data point of a graph