R GC.metrics(all=TRUE) and Trend Chart

.. you can pass all=TRUE|FALSE to GC.metrics if you want to
   override the date range selection

.. also added connect to daterange select so a trend chart
   will refresh when you select a date range
This commit is contained in:
Mark Liversedge
2016-04-30 09:17:15 +01:00
parent 0620b42866
commit deccef46a6
6 changed files with 53 additions and 18 deletions

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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:

View File

@@ -64,7 +64,8 @@ enum gcwinid {
RouteSegment = 35,
WorkoutWindow = 36,
RideMapWindow = 37,
RConsole = 38
RConsole = 38,
RConsoleSeason = 39
};
};
typedef enum GcWindowTypes::gcwinid GcWinID;

View File

@@ -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; k<rides; k++)
REAL(time)[k] = rtool->context->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

View File

@@ -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;