mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -64,7 +64,8 @@ enum gcwinid {
|
||||
RouteSegment = 35,
|
||||
WorkoutWindow = 36,
|
||||
RideMapWindow = 37,
|
||||
RConsole = 38
|
||||
RConsole = 38,
|
||||
RConsoleSeason = 39
|
||||
};
|
||||
};
|
||||
typedef enum GcWindowTypes::gcwinid GcWinID;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user