From 83848fb2a8a987aa2bbe75847f53bbbb5fe15b36 Mon Sep 17 00:00:00 2001 From: Berthold Stoeger Date: Sat, 9 Jan 2021 14:04:28 +0100 Subject: [PATCH] statistics: add a dive-# variable This was requested on the mailing list and it makes sense to have it. Of course, not all charts make sense: e.g. a plot dive-# vs. count is a bit redundant... Sadly, this can't use the generic IntRangeBinner, because dive-#s start at 1, not 0. Suggested-by: Christof Arnosti Signed-off-by: Berthold Stoeger --- stats/statsvariables.cpp | 62 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/stats/statsvariables.cpp b/stats/statsvariables.cpp index 5da823849..c163fd0df 100644 --- a/stats/statsvariables.cpp +++ b/stats/statsvariables.cpp @@ -1302,6 +1302,65 @@ struct WeightVariable : public StatsVariableTemplate { + int bin_size; + DiveNrBinner(int bin_size) : bin_size(bin_size) + { + } + QString format(const StatsBin &bin) const override { + int value = derived_bin(bin).value; + QLocale loc; + return StatsTranslations::tr("%1–%2").arg(loc.toString(value * bin_size + 1), + loc.toString((value + 1) * bin_size)); + } + QString formatLowerBound(const StatsBin &bin) const override { + int value = derived_bin(bin).value; + return QStringLiteral("%L1").arg(value * bin_size + 1); + } + double lowerBoundToFloatBase(int value) const { + return static_cast(value * bin_size + 1); + } + QString name() const override { + return StatsTranslations::tr("in %L2 steps").arg(bin_size); + } + int to_bin_value(const dive *d) const { + if (d->number <= 0) + return invalid_value(); + return (d->number - 1) / bin_size; + } +}; + +static DiveNrBinner dive_nr_binner_5(5); +static DiveNrBinner dive_nr_binner_10(10); +static DiveNrBinner dive_nr_binner_20(20); +static DiveNrBinner dive_nr_binner_50(50); +static DiveNrBinner dive_nr_binner_100(100); +static DiveNrBinner dive_nr_binner_200(200); + +struct DiveNrVariable : public StatsVariableTemplate { + QString name() const override { + return StatsTranslations::tr("Dive #"); + } + std::vector binners() const override { + if (dive_table.nr > 1000) + return { &dive_nr_binner_20, &dive_nr_binner_50, &dive_nr_binner_100, &dive_nr_binner_200 }; + else + return { &dive_nr_binner_5, &dive_nr_binner_10, &dive_nr_binner_20, &dive_nr_binner_50 }; + } + double toFloat(const dive *d) const override { + return d->number >= 0 ? static_cast(d->number) + : invalid_value(); + } + std::vector supportedOperations() const override { + return { StatsOperation::Median, StatsOperation::Mean }; + } +}; + // ============ Dive mode ============ struct DiveModeBinner : public SimpleBinner { @@ -1773,6 +1832,7 @@ static SACVariable sac_variable; static WaterTemperatureVariable water_temperature_variable; static AirTemperatureVariable air_temperature_variable; static WeightVariable weight_variable; +static DiveNrVariable dive_nr_variable; static DiveModeVariable dive_mode_variable; static BuddyVariable buddy_variable; static GasTypeVariable gas_type_variable; @@ -1789,7 +1849,7 @@ static VisibilityVariable visibility_variable; const std::vector stats_variables = { &date_variable, &max_depth_variable, &mean_depth_variable, &duration_variable, &sac_variable, - &water_temperature_variable, &air_temperature_variable, &weight_variable, + &water_temperature_variable, &air_temperature_variable, &weight_variable, &dive_nr_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, &weightsystem_variable, &cylinder_type_variable, &location_variable, &day_of_week_variable,