summaryrefslogtreecommitdiffstats
path: root/stats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2021-01-09 13:47:47 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2021-01-09 14:17:56 -0800
commitb00009ef4e923a3ac2d7f517a6a37e4a6cb70300 (patch)
tree62a28b5d1562cb771cffa92474d92df7842351fe /stats
parent4ecb8ba0cc828defad6f4278fac8998ab48a0b23 (diff)
downloadsubsurface-b00009ef4e923a3ac2d7f517a6a37e4a6cb70300.tar.gz
statistics: add a mean depth variable
This was requested on the mailing list. Reduce code size somewhat by deriving the binner and the variable classes from common base classes with a mean-vs-max flag. Suggested-by: Christof Arnosti <charno@charno.ch> Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'stats')
-rw-r--r--stats/statsvariables.cpp71
1 files changed, 52 insertions, 19 deletions
diff --git a/stats/statsvariables.cpp b/stats/statsvariables.cpp
index 3b6d55761..5da823849 100644
--- a/stats/statsvariables.cpp
+++ b/stats/statsvariables.cpp
@@ -930,11 +930,18 @@ struct DateVariable : public StatsVariableTemplate<StatsVariable::Type::Continuo
}
};
-// ============ Dive depth, binned in 5, 10, 20 m or 15, 30, 60 ft bins ============
+// ============ Dive depth (max and mean), binned in 5, 10, 20 m or 15, 30, 60 ft bins ============
+
+static int dive_depth_in_mm(const dive *d, bool mean)
+{
+ return mean ? d->meandepth.mm : d->maxdepth.mm;
+}
struct DepthBinner : public IntRangeBinner<DepthBinner, IntBin> {
bool metric;
- DepthBinner(int bin_size, bool metric) : IntRangeBinner(bin_size), metric(metric)
+ bool mean;
+ DepthBinner(int bin_size, bool metric, bool mean) :
+ IntRangeBinner(bin_size), metric(metric), mean(mean)
{
}
QString name() const override {
@@ -946,20 +953,21 @@ struct DepthBinner : public IntRangeBinner<DepthBinner, IntBin> {
return get_depth_unit(metric);
}
int to_bin_value(const dive *d) const {
- return metric ? d->maxdepth.mm / 1000 / bin_size
- : lrint(mm_to_feet(d->maxdepth.mm)) / bin_size;
+ int depth = dive_depth_in_mm(d, mean);
+ return metric ? depth / 1000 / bin_size
+ : lrint(mm_to_feet(depth)) / bin_size;
}
};
-static DepthBinner meter_binner5(5, true);
-static DepthBinner meter_binner10(10, true);
-static DepthBinner meter_binner20(20, true);
-static DepthBinner feet_binner15(15, false);
-static DepthBinner feet_binner30(30, false);
-static DepthBinner feet_binner60(60, false);
-struct DepthVariable : public StatsVariableTemplate<StatsVariable::Type::Numeric> {
- QString name() const override {
- return StatsTranslations::tr("Max. Depth");
+struct DepthVariableBase : public StatsVariableTemplate<StatsVariable::Type::Numeric> {
+ bool mean;
+ DepthBinner meter5, meter10, meter20;
+ DepthBinner feet15, feet30, feet60;
+ DepthVariableBase(bool mean) :
+ mean(mean),
+ meter5(5, true, mean), meter10(10, true, mean), meter20(10, true, mean),
+ feet15(15, false, mean), feet30(30, false, mean), feet60(60, false, mean)
+ {
}
QString unitSymbol() const override {
return get_depth_unit();
@@ -969,19 +977,43 @@ struct DepthVariable : public StatsVariableTemplate<StatsVariable::Type::Numeric
}
std::vector<const StatsBinner *> binners() const override {
if (prefs.units.length == units::METERS)
- return { &meter_binner5, &meter_binner10, &meter_binner20 };
+ return { &meter5, &meter10, &meter20 };
else
- return { &feet_binner15, &feet_binner30, &feet_binner60 };
+ return { &feet15, &feet30, &feet60 };
}
double toFloat(const dive *d) const override {
- return prefs.units.length == units::METERS ? d->maxdepth.mm / 1000.0
- : mm_to_feet(d->maxdepth.mm);
+ int depth = dive_depth_in_mm(d, mean);
+ return prefs.units.length == units::METERS ? depth / 1000.0
+ : mm_to_feet(depth);
+ }
+ std::vector<StatsOperation> supportedOperations() const override {
+ return { StatsOperation::Median, StatsOperation::Mean, StatsOperation::Sum };
+ }
+};
+
+struct MaxDepthVariable : public DepthVariableBase {
+ MaxDepthVariable() : DepthVariableBase(false) {
+ }
+ QString name() const override {
+ return StatsTranslations::tr("Max. Depth");
}
std::vector<StatsOperation> supportedOperations() const override {
return { StatsOperation::Median, StatsOperation::Mean, StatsOperation::Sum };
}
};
+struct MeanDepthVariable : public DepthVariableBase {
+ MeanDepthVariable() : DepthVariableBase(true)
+ {
+ }
+ QString name() const override {
+ return StatsTranslations::tr("Mean Depth");
+ }
+ std::vector<StatsOperation> supportedOperations() const override {
+ return { StatsOperation::Median, StatsOperation::Mean, StatsOperation::TimeWeightedMean };
+ }
+};
+
// ============ Bottom time, binned in 5, 10, 30 min or 1 h bins ============
struct MinuteBinner : public IntRangeBinner<MinuteBinner, IntBin> {
@@ -1734,7 +1766,8 @@ struct VisibilityVariable : public StatsVariableTemplate<StatsVariable::Type::Di
};
static DateVariable date_variable;
-static DepthVariable depth_variable;
+static MaxDepthVariable max_depth_variable;
+static MeanDepthVariable mean_depth_variable;
static DurationVariable duration_variable;
static SACVariable sac_variable;
static WaterTemperatureVariable water_temperature_variable;
@@ -1755,7 +1788,7 @@ static RatingVariable rating_variable;
static VisibilityVariable visibility_variable;
const std::vector<const StatsVariable *> stats_variables = {
- &date_variable, &depth_variable, &duration_variable, &sac_variable,
+ &date_variable, &max_depth_variable, &mean_depth_variable, &duration_variable, &sac_variable,
&water_temperature_variable, &air_temperature_variable, &weight_variable,
&gas_content_o2_variable, &gas_content_o2_he_max_variable, &gas_content_he_variable,
&dive_mode_variable, &buddy_variable, &gas_type_variable, &suit_variable,