A user configurable chart for showing ride metrics and
other calculated values over time.
* Uses SQLITE database to store metrics
* Supports any metric available from the metric factory
* Adds new MaxHr, VI, Peak Power and Time In Zone metric
* Also includes LTS/STS/SB for PM charting
* Aggregates in days, weeks, months or years
* Reads and Updates seasons.xml
* Adds cycles and adhoc date ranges in seasons.xml
* Date ranges can be selected on the plot with shift-left click
* Allows users to customise preferences for color, symbols et al
* Allows user to customise metric names and unit names
* Supports smooth curves and topN highlighting
* Has a linear regress trend line function
* Allows users to save charts to charts.xml
* A default charts.xml is built-in
* A chart manager to import/export/rename/delete charts etc
* Provides a tooltip to provide basic datapoint information
* Performance Manager adjusted to use the MetricDB
* User configurable setting for SB calculation (today/tomorrow)
This patch adds Aerolab, a virtual elevation module. A
new tab is added in which the user can perform virtual
elevation analysis. This version is a manual Aerolab,
where user can use the following sliders to elevation-match
to a known elevation profile:
Crr -coefficient of rolling resistance
CdA -aero coefficient of drag * frontal area
Eta -drivetrain efficiency (to be used when using a crank-
or bottom-brack-based power meter)
Mass -total mass of bike + rider
Rho -density of air
E_offset -an elevation offset to align elevations
Scrolling up and down the ride files is painfully slow when
3d is compiled in. This patch uses a setActive mechanism in
the same fashion as the pfpv and performance manager tabs.
Additionally, a recent patch to support user preferences for
units added a settings lookup that was called for every point.
This is also fixed.
fixes#16
I think the previous implementation could have referenced already-deleted
RideItem objects during calls to Split Ride.
This commit removes the calendar's own map of RideItems, and instead
uses the list of rides in MainWindow::allRideItems. Because I use
binary search on that list, this implementation should be just as fast
as the old one. But because I don't hang on to any RideItem pointers
beyond a single call to RideCalendar::paintCell, it shouldn't be
vulnerable to referencing already-deleted RideItem objects.
Need to call item->ride() in order to load the ride, and should ignore those
for which the result is NULL. Do this after checking the date, though, so
that we don't load older rides into memory.
A new tab on the ride analysis view for analysing ride data in three
dimensions. Interval selection is supported and a z-axis slider is
available for helping to identify data in the z-plane. A color legend
is displayed since coloring is independent of x/y/z values.
Coloring and Z axis values are averages for associated values of x/y.
The code requires qwtplot3d to be installed (see gcconfig.pri.in) and
with older Mac dev envs you will need to add -lz to LIBS too. (LIBS += -lz).
On Linux qwt3d_function.h needs a #include <stdio.h> added to compile.
Greg Steele helped design and test.
There are 2 open issues x/y/z axis labels occasionally appear in the
wrong place. lastly, the bin selection is for X&Y bin sizes and it
would be better to have separate sliders.
Move the logic for how to compute RideMetrics from a RideFile, including
dependency tracking, out of RideItem and into RideMetric. I'm going to start
using them for intervals as well as rides, and I don't want to construct a
RideItem for each interval. It also seems more natural here. For
performance, RideItem still caches the computed metrics for a RideFile.
Another rightclick menu for intervals, adding a bring to front and send to
back option but only when viewing the pfPvPlot, additionally the algorithm in
PfPv plot for determining which interval a point is used for has been adjusted
to fully populate every interval curve where appropriate (and incorrect
comments and redundant code have been removed).
IntervalItems now have a display sequence number so when you have
overlapping intervals you can bring to front and send to back on the
PfPv plot. The display sequence could be used on other plots if/when
they distinguish between intervals.
Previously, the coloring of intervals on PfPvPlot was determined solely
by the order they were defined which could be quite confusing.
This patch removes the QToolBox from commit e93970 and replaces it with
a QComboBox instead. A new object ViewSelection can be included in any
new views and will manage the interaction with MainWindow to switch
between views. It is essentially a QComboBox with some code to interact
with MainWindow.
A new signal viewChanged(int) has been implemented in MainWindow to
notify of a view change. The parameter will be set to VIEW_ANALYSIS
or VIEW_TRAIN depending upon which view was selected.
In addition, a new TrainWindow object has been created which implements
the Realtime code and is comprised of the TrainTool and TrainTabs
implemented in e93970. It also sets its splitters from remembered values
in the same fashion as the central splitter on the Analysis view.
The left side of MainWindow is now a toolbox which contains
Ride Analysis and Racing and Training options. The Right side
tabs have been reorganised and associated with the toolbox.
To support the population of the Racing and Training left tool
the config dialog has been updated to enable the user to configure
the location of their workouts.
In addition, the config dialog now calls upon MainWindow to issue
a configUpdate() signal to notify widgets when config has been
updated. This is a refactoring of the existing mechanism that
only called realtimeWindow->updateConfig, now any widget can
connect to the MainWindow signal and re-read its config appropriately.
Currently, the TrainTool and RealtimeWindow widgets have been coded to
use this.
With the introduction of the rideSelected signal the RideFile was
opened (as previously) by the RideSummaryWindow::htmlSummary()
member. In some cases, this signal was processed by RideSummary window
AFTER the other charts (AllPlot etc) this results in 'No data' being
shown on other charts.
This patch moves the file reading to RideItem::ride() which was previously
a public RideFile * (that is now a protected member ride_). As a happy by
product it removes the need to check if the file has already been read
across all other functions ensuring in-core values are not accidentally
overwritten. The read errors are made available by a new RideItem::errors()
member.
This modification is required to support the RideImportWizard in freeing
loaded RideFiles during batch import to ensure virtual memory is not
exhausted when large numbers of files are imported at once. This modification
is also included in this patch.
The find peak intervals added intervals with 0km for start and stop. They
now get set appropriately, so peak intervals display correctly when viewed
in byDistance on AllPlot.
The find peak powers functions was previously adding peak intervals for
durations that were longer than the entire ride, for example a 20 minute
ride would still have a 30min and 60min peak power interval added.
The duration of the ride is now checked and only peak intervals that
are shorter or equal to the length of the ride are added.
The class member IntervalItem::name is redundant since it is a duplicate
of the text() member of the base class QTreeWidgetItem. By removing it
we both simplify the code and remove the need to keep name and text in
sync when renaming and creating intervals.
As a result the itemChanged signal that was connected for renames and
then disconnected when the items are cleared can be connected once
and no disconnect is neccessary.
This connect/disconnect oddity was originally to avoid a SEGV that
resulted from accessing text() whilst the QTreeWidgetItem was being
destroyed. The code for removing intervals when a new ride is selected
no longer destroys and recreats MainWindow::allIntervals (which was also an
artefact of the original code to avoid a SEGV).
This change allows us to connect the zonesChanged signal to the ride summary,
so that we don't have to call ride->htmlSummary as a special case whenever
we call zonesChanged. It will also come in useful later when I introduce a
rideSelected signal.