mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-12 05:36:59 -04:00
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
This commit is contained in:
+43
-16
@@ -22,7 +22,6 @@ 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_COLLECTION(pair<String COMMA String>);
|
||||||
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; }
|
||||||
|
|
||||||
@@ -30,6 +29,14 @@ template <typename T> inline T sgn(T v) { return v < 0 ? -1 : 1; }
|
|||||||
|
|
||||||
DEFINE_EVENT_TYPE(EVENT_GRAPH_SELECT);
|
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
|
// ----------------------------------------------------------------------------- : GraphData
|
||||||
|
|
||||||
GraphElement::GraphElement(const String& v1) {
|
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<String COMMA UInt COMMA SmartLess>);
|
||||||
|
|
||||||
GraphData::GraphData(const GraphDataPre& d)
|
GraphData::GraphData(const GraphDataPre& d)
|
||||||
: axes(d.axes)
|
: axes(d.axes)
|
||||||
{
|
{
|
||||||
@@ -67,11 +79,33 @@ GraphData::GraphData(const GraphDataPre& d)
|
|||||||
// find groups on each axis
|
// find groups on each axis
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
FOR_EACH(a, axes) {
|
FOR_EACH(a, axes) {
|
||||||
map<String,UInt> counts; // note: default constructor for UInt() does initialize to 0
|
map<String,UInt,SmartLess> counts; // note: default constructor for UInt() does initialize to 0
|
||||||
FOR_EACH_CONST(e, d.elements) {
|
FOR_EACH_CONST(e, d.elements) {
|
||||||
counts[e->values[i]] += 1;
|
counts[e->values[i]] += 1;
|
||||||
}
|
}
|
||||||
if (a->numeric) {
|
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()<<i, 0);
|
||||||
|
}
|
||||||
|
prev = next + 1;
|
||||||
|
}
|
||||||
|
// add
|
||||||
|
a->addGroup(c.first, c.second);
|
||||||
|
}
|
||||||
|
a->mean /= numeric_count;
|
||||||
|
/*
|
||||||
// TODO: start at something other than 0?
|
// TODO: start at something other than 0?
|
||||||
// TODO: support fractions?
|
// TODO: support fractions?
|
||||||
a->mean = 0;
|
a->mean = 0;
|
||||||
@@ -82,17 +116,16 @@ GraphData::GraphData(const GraphDataPre& d)
|
|||||||
map<String,UInt>::const_iterator it = counts.find(is);
|
map<String,UInt>::const_iterator it = counts.find(is);
|
||||||
if (it == counts.end()) {
|
if (it == counts.end()) {
|
||||||
// not found, add a 0 bar
|
// not found, add a 0 bar
|
||||||
a->groups.push_back(GraphGroup(is, 0));
|
a->addGroup(is, 0);
|
||||||
} else {
|
} else {
|
||||||
a->groups.push_back(GraphGroup(is, it->second));
|
a->addGroup(is, it->second);
|
||||||
a->max = max(a->max, it->second);
|
|
||||||
a->total += it->second;
|
|
||||||
a->mean += i * it->second;
|
a->mean += i * it->second;
|
||||||
counts.erase(is);
|
counts.erase(is);
|
||||||
left--;
|
left--;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
UInt numeric_count = a->total;
|
||||||
a->mean /= a->total;
|
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) {
|
||||||
@@ -100,23 +133,17 @@ GraphData::GraphData(const GraphDataPre& d)
|
|||||||
}
|
}
|
||||||
// Also keep non-numeric entries
|
// Also keep non-numeric entries
|
||||||
FOR_EACH(c, counts) {
|
FOR_EACH(c, counts) {
|
||||||
a->groups.push_back(GraphGroup(c.first, c.second));
|
a->addGroup(c.first, c.second);
|
||||||
a->max = max(a->max, c.second);
|
|
||||||
a->total += c.second;
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
} else if (a->order) {
|
} else if (a->order) {
|
||||||
// specific group order
|
// specific group order
|
||||||
FOR_EACH_CONST(gn, *a->order) {
|
FOR_EACH_CONST(gn, *a->order) {
|
||||||
UInt count = counts[gn];
|
a->addGroup(gn, counts[gn]);
|
||||||
a->groups.push_back(GraphGroup(gn, count));
|
|
||||||
a->max = max(a->max, count);
|
|
||||||
a->total += count;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FOR_EACH(c, counts) {
|
FOR_EACH(c, counts) {
|
||||||
a->groups.push_back(GraphGroup(c.first, c.second));
|
a->addGroup(c.first, c.second);
|
||||||
a->max = max(a->max, c.second);
|
|
||||||
a->total += c.second;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// colors
|
// colors
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ class GraphAxis : public IntrusivePtrBase<GraphAxis> {
|
|||||||
double mean; ///< Mean value, only for numeric axes
|
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)
|
||||||
|
|
||||||
|
/// Add a graph group
|
||||||
|
void addGroup(const String& name, UInt size);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// A single data point of a graph
|
/// A single data point of a graph
|
||||||
|
|||||||
Reference in New Issue
Block a user