diff --git a/src/Charts/RChart.cpp b/src/Charts/RChart.cpp index 16f6f8f85..b7b066cff 100644 --- a/src/Charts/RChart.cpp +++ b/src/Charts/RChart.cpp @@ -257,7 +257,7 @@ void RConsole::contextMenuEvent(QContextMenuEvent *e) Q_UNUSED(e) } -RChart::RChart(Context *context) : GcChartWindow(context), context(context) +RChart::RChart(Context *context, bool ridesummary) : GcChartWindow(context), context(context), ridesummary(ridesummary) { setControls(NULL); @@ -290,9 +290,9 @@ RChart::RChart(Context *context) : GcChartWindow(context), context(context) setScript("## R script will run on selection.\n" "##\n" "## GC.activity()\n" - "## GC.metrics()\n" + "## GC.metrics(all=FALSE)\n" "##\n" - "## Get the current ride or date range.\n" + "## Get the current ride or metrics\n" "##\n"); leftsplitter->addWidget(script); @@ -310,7 +310,12 @@ RChart::RChart(Context *context) : GcChartWindow(context), context(context) canvas->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding)); splitter->addWidget(canvas); - connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(runScript())); + if (ridesummary) { + connect(this, SIGNAL(rideItemChanged(RideItem*)), this, SLOT(runScript())); + } else { + connect(this, SIGNAL(dateRangeChanged(DateRange)), this, SLOT(runScript())); + } + } else { // not starting diff --git a/src/Charts/RChart.h b/src/Charts/RChart.h index 82454b0a3..ccf9b028a 100644 --- a/src/Charts/RChart.h +++ b/src/Charts/RChart.h @@ -82,7 +82,7 @@ class RChart : public GcChartWindow { Q_PROPERTY(QString script READ getScript WRITE setScript USER true) public: - RChart(Context *context); + RChart(Context *context, bool ridesummary); // receives all the events QTextEdit *script; @@ -102,6 +102,7 @@ class RChart : public GcChartWindow { private: Context *context; QString text; // if Rtool not alive + bool ridesummary; }; diff --git a/src/Gui/GcWindowRegistry.cpp b/src/Gui/GcWindowRegistry.cpp index 1cc5c3908..e1880c4ac 100644 --- a/src/Gui/GcWindowRegistry.cpp +++ b/src/Gui/GcWindowRegistry.cpp @@ -75,7 +75,7 @@ GcWindowRegistry* GcWindows; void GcWindowRegistry::initialize() { - static GcWindowRegistry GcWindowsInit[30] = { + static GcWindowRegistry GcWindowsInit[31] = { // name GcWinID { VIEW_HOME|VIEW_DIARY, tr("Metric Trends"),GcWindowTypes::LTM }, { VIEW_HOME|VIEW_DIARY, tr("Collection TreeMap"),GcWindowTypes::TreeMap }, @@ -93,7 +93,8 @@ GcWindowRegistry::initialize() { VIEW_ANALYSIS, tr("Pedal Force vs Velocity"),GcWindowTypes::PfPv }, { VIEW_ANALYSIS, tr("Heartrate vs Power"),GcWindowTypes::HrPw }, { VIEW_ANALYSIS|VIEW_INTERVAL, tr("Map"),GcWindowTypes::RideMapWindow }, - { VIEW_ANALYSIS|VIEW_HOME, tr("R Console"),GcWindowTypes::RConsole }, + { VIEW_ANALYSIS, tr("R Chart"),GcWindowTypes::RConsole }, + { VIEW_HOME, tr("R Chart "),GcWindowTypes::RConsoleSeason }, //{ VIEW_ANALYSIS, tr("Bing Map"),GcWindowTypes::BingMap }, { VIEW_ANALYSIS, tr("2d Plot"),GcWindowTypes::Scatter }, { VIEW_ANALYSIS, tr("3d Plot"),GcWindowTypes::Model }, @@ -165,9 +166,11 @@ GcWindowRegistry::newGcWindow(GcWinID id, Context *context) #endif case GcWindowTypes::Histogram: returning = new HistogramWindow(context); break; #ifdef GC_WANT_R - case GcWindowTypes::RConsole: returning = new RChart(context); break; + case GcWindowTypes::RConsole: returning = new RChart(context, true); break; + case GcWindowTypes::RConsoleSeason: returning = new RChart(context, false); break; #else case GcWindowTypes::RConsole: returning = new GcWindow(); break; + case GcWindowTypes::RConsoleSeason: returning = new GcWindow(); break; #endif case GcWindowTypes::Distribution: returning = new HistogramWindow(context, true); break; case GcWindowTypes::PerformanceManager: diff --git a/src/Gui/GcWindowRegistry.h b/src/Gui/GcWindowRegistry.h index e0728d852..afa555598 100644 --- a/src/Gui/GcWindowRegistry.h +++ b/src/Gui/GcWindowRegistry.h @@ -64,7 +64,8 @@ enum gcwinid { RouteSegment = 35, WorkoutWindow = 36, RideMapWindow = 37, - RConsole = 38 + RConsole = 38, + RConsoleSeason = 39 }; }; typedef enum GcWindowTypes::gcwinid GcWinID; diff --git a/src/R/RTool.cpp b/src/R/RTool.cpp index 4c509b50c..89e4f6ea7 100644 --- a/src/R/RTool.cpp +++ b/src/R/RTool.cpp @@ -90,7 +90,10 @@ RTool::RTool() { "GC.athlete.home", (DL_FUNC) &RTool::athleteHome, 0 }, { "GC.activities", (DL_FUNC) &RTool::activities, 0 }, { "GC.activity", (DL_FUNC) &RTool::activity, 0 }, - { "GC.metrics", (DL_FUNC) &RTool::metrics, 0 }, + + // metrics is passed a Rboolean for "all": + // TRUE -> return all metrics, FALSE -> apply date range selection + { "GC.metrics", (DL_FUNC) &RTool::metrics, 1 }, { NULL, NULL, 0 } }; @@ -109,7 +112,7 @@ RTool::RTool() "GC.athlete.home <- function() { .Call(\"GC.athlete.home\") }\n" "GC.activities <- function() { .Call(\"GC.activities\") }\n" "GC.activity <- function() { .Call(\"GC.activity\") }\n" - "GC.metrics <- function() { .Call(\"GC.metrics\") }\n" + "GC.metrics <- function(all=FALSE) { .Call(\"GC.metrics\", all) }\n" "GC.version <- function() {\n" " return(\"%1\")\n" "}\n" @@ -237,16 +240,33 @@ RTool::activities() } SEXP -RTool::metrics() +RTool::metrics(SEXP pAll) { + // return value SEXP ans=NULL; + // p1 - all=TRUE|FALSE - return all metrics or just within + // the currently selected date range + pAll = Rf_coerceVector(pAll, LGLSXP); + bool all = LOGICAL(pAll)[0]; + if (rtool->context && rtool->context->athlete && rtool->context->athlete->rideCache) { const RideMetricFactory &factory = RideMetricFactory::instance(); int rides = rtool->context->athlete->rideCache->count(); int metrics = factory.metricCount(); + // how many rides to return if we're limiting to the + // currently selected date range ? + DateRange range = rtool->context->currentDateRange(); + if (!all) { + // we need to count rides that are in range... + rides = 0; + foreach(RideItem *ride, rtool->context->athlete->rideCache->rides()) { + if (range.pass(ride->dateTime.date())) rides++; + } + } + // get a listAllocated PROTECT(ans=Rf_allocList(metrics+1)); @@ -261,9 +281,12 @@ RTool::metrics() SEXP time; PROTECT(time=Rf_allocVector(REALSXP, rides)); - // fill with values for date and class - for(int k=0; kcontext->athlete->rideCache->rides()[k]->dateTime.toUTC().toTime_t(); + // fill with values for date and class if its one we need to return + int k=0; + foreach(RideItem *ride, rtool->context->athlete->rideCache->rides()) { + if (all || range.pass(ride->dateTime.date())) + REAL(time)[k] = ride->dateTime.toUTC().toTime_t(); + } // POSIXct class SEXP clas; @@ -296,8 +319,10 @@ RTool::metrics() int index=0; foreach(RideItem *item, rtool->context->athlete->rideCache->rides()) { - REAL(m)[index++] = item->metrics()[i] * (useMetricUnits ? 1.0f : metric->conversion()) - + (useMetricUnits ? 0.0f : metric->conversionSum()); + if (all || range.pass(item->dateTime.date())) { + REAL(m)[index++] = item->metrics()[i] * (useMetricUnits ? 1.0f : metric->conversion()) + + (useMetricUnits ? 0.0f : metric->conversionSum()); + } } // add to the list diff --git a/src/R/RTool.h b/src/R/RTool.h index 64b25cb53..ae5f6348a 100644 --- a/src/R/RTool.h +++ b/src/R/RTool.h @@ -46,7 +46,7 @@ class RTool { static SEXP athleteHome(); static SEXP activities(); static SEXP activity(); - static SEXP metrics(); + static SEXP metrics(SEXP); bool starting; bool failed;