diff --git a/gpxsee.pro b/gpxsee.pro index d4cd6ee1..f34c0818 100644 --- a/gpxsee.pro +++ b/gpxsee.pro @@ -97,7 +97,13 @@ HEADERS += src/config.h \ src/oddspinbox.h \ src/rectc.h \ src/searchpointer.h \ - src/percentslider.h + src/percentslider.h \ + src/elevationgraphitem.h \ + src/speedgraphitem.h \ + src/heartrategraphitem.h \ + src/temperaturegraphitem.h \ + src/cadencegraphitem.h \ + src/powergraphitem.h SOURCES += src/main.cpp \ src/gui.cpp \ src/poi.cpp \ @@ -167,7 +173,13 @@ SOURCES += src/main.cpp \ src/albersequal.cpp \ src/oddspinbox.cpp \ src/rectc.cpp \ - src/percentslider.cpp + src/percentslider.cpp \ + src/elevationgraphitem.cpp \ + src/speedgraphitem.cpp \ + src/heartrategraphitem.cpp \ + src/temperaturegraphitem.cpp \ + src/cadencegraphitem.cpp \ + src/powergraphitem.cpp RESOURCES += gpxsee.qrc TRANSLATIONS = lang/gpxsee_cs.ts \ lang/gpxsee_sv.ts \ diff --git a/lang/gpxsee_cs.qm b/lang/gpxsee_cs.qm new file mode 100644 index 00000000..cd24d6f9 Binary files /dev/null and b/lang/gpxsee_cs.qm differ diff --git a/lang/gpxsee_cs.ts b/lang/gpxsee_cs.ts index 7a2ff686..acc55d3e 100644 --- a/lang/gpxsee_cs.ts +++ b/lang/gpxsee_cs.ts @@ -25,6 +25,25 @@ Maximum + + CadenceGraphItem + + + Maximum + Maximum + + + + + 1/min + 1/min + + + + Average + Průměr + + Data @@ -82,36 +101,69 @@ Výška - + m m - + Ascent Stoupání - + Descent Klesání - + Minimum Minimum - + ft ft - + Maximum Maximum + + ElevationGraphItem + + + m + m + + + + ft + ft + + + + Ascent + Stoupání + + + + Descent + Klesání + + + + Maximum + Maximum + + + + Minimum + Minimum + + ExportDialog @@ -725,12 +777,12 @@ - + Distance Vzdálenost - + Time Čas @@ -759,6 +811,25 @@ Maximum + + HeartRateGraphItem + + + Maximum + Maximum + + + + + 1/min + 1/min + + + + Average + Průměr + + MapList @@ -1152,6 +1223,25 @@ Maximum + + PowerGraphItem + + + Maximum + Maximum + + + + + 1/min + 1/min + + + + Average + Průměr + + RouteItem @@ -1196,32 +1286,60 @@ SpeedGraph - + Speed Rychlost - + km/h km/h - + Average Průměr - + Maximum Maximum - + mi/h mi/h + + SpeedGraphItem + + + km/h + km/h + + + + mi/h + mi/h + + + + Maximum + Maximum + + + + Average + Průměr + + + + Moving average + Čistý průměr + + TemperatureGraph @@ -1246,16 +1364,44 @@ Maximum - + C C - + F F + + TemperatureGraphItem + + + C + C + + + + F + F + + + + Average + Průměr + + + + Maximum + Maximum + + + + Minimum + Minimum + + TrackItem diff --git a/lang/gpxsee_de.qm b/lang/gpxsee_de.qm new file mode 100644 index 00000000..437bb390 Binary files /dev/null and b/lang/gpxsee_de.qm differ diff --git a/lang/gpxsee_de.ts b/lang/gpxsee_de.ts index 37cefa49..db03ac70 100644 --- a/lang/gpxsee_de.ts +++ b/lang/gpxsee_de.ts @@ -25,6 +25,25 @@ Maximum + + CadenceGraphItem + + + Maximum + Maximum + + + + + 1/min + 1/min + + + + Average + Durchschnitt + + Data @@ -82,36 +101,69 @@ Höhe - + m m - + Ascent Steigung - + Descent Gefälle - + Minimum Minimum - + ft ft - + Maximum Maximum + + ElevationGraphItem + + + m + m + + + + ft + ft + + + + Ascent + Steigung + + + + Descent + Gefälle + + + + Maximum + Maximum + + + + Minimum + Minimum + + ExportDialog @@ -724,12 +776,12 @@ - + Distance Distanz - + Time Zeit @@ -758,6 +810,25 @@ Maximum + + HeartRateGraphItem + + + Maximum + Maximum + + + + + 1/min + 1/min + + + + Average + Durchschnitt + + MapList @@ -1151,6 +1222,25 @@ Maximum + + PowerGraphItem + + + Maximum + Maximum + + + + + 1/min + 1/min + + + + Average + Durchschnitt + + RouteItem @@ -1195,32 +1285,60 @@ SpeedGraph - + Speed Geschwindigkeit - + km/h km/h - + Average Durchschnitt - + Maximum Maximum - + mi/h mi/h + + SpeedGraphItem + + + km/h + km/h + + + + mi/h + mi/h + + + + Maximum + Maximum + + + + Average + Durchschnitt + + + + Moving average + Bewegungsdurchschnitt + + TemperatureGraph @@ -1245,16 +1363,44 @@ Maximum - + C C - + F F + + TemperatureGraphItem + + + C + C + + + + F + F + + + + Average + Durchschnitt + + + + Maximum + Maximum + + + + Minimum + Minimum + + TrackItem diff --git a/lang/gpxsee_sv.qm b/lang/gpxsee_sv.qm new file mode 100644 index 00000000..1ea5787a Binary files /dev/null and b/lang/gpxsee_sv.qm differ diff --git a/lang/gpxsee_sv.ts b/lang/gpxsee_sv.ts index d69380c6..729ccbd6 100644 --- a/lang/gpxsee_sv.ts +++ b/lang/gpxsee_sv.ts @@ -25,6 +25,25 @@ Maximal + + CadenceGraphItem + + + Maximum + + + + + + 1/min + 1/min + + + + Average + + + Data @@ -82,36 +101,69 @@ Höjd - + m m - + Ascent Stigning - + Descent Nedstigning - + Minimum Minimum - + ft ft - + Maximum Maximum + + ElevationGraphItem + + + m + m + + + + ft + ft + + + + Ascent + Stigning + + + + Descent + Nedstigning + + + + Maximum + + + + + Minimum + + + ExportDialog @@ -724,12 +776,12 @@ - + Distance Avstånd - + Time Tid @@ -758,6 +810,25 @@ Max + + HeartRateGraphItem + + + Maximum + + + + + + 1/min + 1/min + + + + Average + + + MapList @@ -1151,6 +1222,25 @@ Max + + PowerGraphItem + + + Maximum + + + + + + 1/min + 1/min + + + + Average + + + RouteItem @@ -1195,32 +1285,60 @@ SpeedGraph - + Speed Hastighet - + km/h km/h - + Average Medel - + Maximum Max - + mi/h mi/h + + SpeedGraphItem + + + km/h + km/h + + + + mi/h + mi/h + + + + Maximum + + + + + Average + + + + + Moving average + + + TemperatureGraph @@ -1245,16 +1363,44 @@ Max - + C C - + F F + + TemperatureGraphItem + + + C + C + + + + F + F + + + + Average + + + + + Maximum + + + + + Minimum + + + TrackItem diff --git a/src/cadencegraph.cpp b/src/cadencegraph.cpp index 7ada1768..904a48c2 100644 --- a/src/cadencegraph.cpp +++ b/src/cadencegraph.cpp @@ -1,10 +1,10 @@ #include "data.h" +#include "cadencegraphitem.h" #include "cadencegraph.h" CadenceGraph::CadenceGraph(QWidget *parent) : GraphTab(parent) { - _units = Metric; _showTracks = true; GraphView::setYUnits(tr("1/min")); @@ -28,21 +28,16 @@ void CadenceGraph::loadData(const Data &data, const QList &paths) { for (int i = 0; i < data.tracks().count(); i++) { const Graph &graph = data.tracks().at(i)->cadence(); - qreal sum = 0, w = 0; if (graph.size() < 2) { skipColor(); continue; } - for (int j = 1; j < graph.size(); j++) { - qreal ds = graph.at(j).s() - graph.at(j-1).s(); - sum += graph.at(j).y() * ds; - w += ds; - } - _avg.append(QPointF(data.tracks().at(i)->distance(), sum/w)); + CadenceGraphItem *gi = new CadenceGraphItem(graph); + GraphView::addGraph(gi, paths.at(i)); - GraphView::loadGraph(graph, paths.at(i)); + _avg.append(QPointF(data.tracks().at(i)->distance(), gi->avg())); } for (int i = 0; i < data.routes().count(); i++) diff --git a/src/cadencegraph.h b/src/cadencegraph.h index cd1764f9..362575fe 100644 --- a/src/cadencegraph.h +++ b/src/cadencegraph.h @@ -23,7 +23,6 @@ private: QList _avg; - enum Units _units; bool _showTracks; }; diff --git a/src/cadencegraphitem.cpp b/src/cadencegraphitem.cpp new file mode 100644 index 00000000..90e0e7be --- /dev/null +++ b/src/cadencegraphitem.cpp @@ -0,0 +1,26 @@ +#include "tooltip.h" +#include "cadencegraphitem.h" + +CadenceGraphItem::CadenceGraphItem(const Graph &graph, QGraphicsItem *parent) + : GraphItem(graph, parent) +{ + qreal sum = 0; + + for (int j = 1; j < graph.size(); j++) + sum += graph.at(j).y() * (graph.at(j).s() - graph.at(j-1).s()); + _avg = sum/graph.last().s(); + + setToolTip(toolTip()); +} + +QString CadenceGraphItem::toolTip() const +{ + ToolTip tt; + + tt.insert(tr("Maximum"), QString::number(max(), 'f', 1) + + UNIT_SPACE + tr("1/min")); + tt.insert(tr("Average"), QString::number(avg(), 'f', 1) + + UNIT_SPACE + tr("1/min")); + + return tt.toString(); +} diff --git a/src/cadencegraphitem.h b/src/cadencegraphitem.h new file mode 100644 index 00000000..a57e0ad5 --- /dev/null +++ b/src/cadencegraphitem.h @@ -0,0 +1,20 @@ +#ifndef CADENCEGRAPHITEM_H +#define CADENCEGRAPHITEM_H + +#include "graphitem.h" + +class CadenceGraphItem : public GraphItem +{ +public: + CadenceGraphItem(const Graph &graph, QGraphicsItem *parent = 0); + + qreal max() const {return -bounds().top();} + qreal avg() const {return _avg;} + +private: + QString toolTip() const; + + qreal _avg; +}; + +#endif // CADENCEGRAPHITEM_H diff --git a/src/elevationgraph.cpp b/src/elevationgraph.cpp index 952c3325..f5db929f 100644 --- a/src/elevationgraph.cpp +++ b/src/elevationgraph.cpp @@ -1,6 +1,8 @@ #include #include "config.h" #include "data.h" +#include "tooltip.h" +#include "elevationgraphitem.h" #include "elevationgraph.h" @@ -42,11 +44,8 @@ ElevationGraph::ElevationGraph(QWidget *parent) : GraphTab(parent) _showRoutes = true; _showTracks = true; - _units = Metric; - setYUnits(); setYLabel(tr("Elevation")); - setMinYRange(50.0); } @@ -68,43 +67,25 @@ void ElevationGraph::setInfo() void ElevationGraph::loadGraph(const Graph &graph, Type type, PathItem *path) { - qreal ascent = 0, descent = 0; - qreal min, max; - if (graph.size() < 2) { skipColor(); return; } - max = min = graph.at(0).y(); - for (int j = 1; j < graph.size(); j++) { - qreal cur = graph.at(j).y(); - qreal prev = graph.at(j-1).y(); - - if (cur > prev) - ascent += cur - prev; - if (cur < prev) - descent += prev - cur; - - if (cur < min) - min = cur; - if (cur > max) - max = cur; - } + ElevationGraphItem *gi = new ElevationGraphItem(graph); + GraphView::addGraph(gi, path, type); if (type == Track) { - _trackAscent += ascent; - _trackDescent += descent; - _trackMax = nMax(_trackMax, max); - _trackMin = nMin(_trackMin, min); + _trackAscent += gi->ascent(); + _trackDescent += gi->descent(); + _trackMax = nMax(_trackMax, gi->max()); + _trackMin = nMin(_trackMin, gi->min()); } else { - _routeAscent += ascent; - _routeDescent += descent; - _routeMax = nMax(_routeMax, max); - _routeMin = nMin(_routeMin, min); + _routeAscent += gi->ascent(); + _routeDescent += gi->descent(); + _routeMax = nMax(_routeMax, gi->max()); + _routeMin = nMin(_routeMin, gi->min()); } - - GraphView::loadGraph(graph, path, type); } void ElevationGraph::loadData(const Data &data, const QList &paths) @@ -148,11 +129,10 @@ void ElevationGraph::setYUnits() void ElevationGraph::setUnits(enum Units units) { - _units = units; + GraphView::setUnits(units); setYUnits(); setInfo(); - GraphView::setUnits(units); redraw(); } diff --git a/src/elevationgraph.h b/src/elevationgraph.h index 71e72c83..82078ca9 100644 --- a/src/elevationgraph.h +++ b/src/elevationgraph.h @@ -35,7 +35,6 @@ private: qreal _trackMax, _routeMax; qreal _trackMin, _routeMin; - enum Units _units; bool _showTracks, _showRoutes; }; diff --git a/src/elevationgraphitem.cpp b/src/elevationgraphitem.cpp new file mode 100644 index 00000000..3a4644ef --- /dev/null +++ b/src/elevationgraphitem.cpp @@ -0,0 +1,43 @@ +#include "tooltip.h" +#include "elevationgraphitem.h" + +ElevationGraphItem::ElevationGraphItem(const Graph &graph, QGraphicsItem *parent) + : GraphItem(graph, parent) +{ + _ascent = _descent = 0; + + for (int j = 1; j < graph.size(); j++) { + qreal cur = graph.at(j).y(); + qreal prev = graph.at(j-1).y(); + + if (cur > prev) + _ascent += cur - prev; + if (cur < prev) + _descent += prev - cur; + } + + setToolTip(toolTip(Metric)); +} + +QString ElevationGraphItem::toolTip(Units units) const +{ + ToolTip tt; + qreal scale = (units == Metric) ? 1.0 : M2FT; + QString su = (units == Metric) ? tr("m") : tr("ft"); + + tt.insert(tr("Ascent"), QString::number(ascent() * scale, 'f', 0) + + UNIT_SPACE + su); + tt.insert(tr("Descent"), QString::number(descent() * scale, 'f', 0) + + UNIT_SPACE + su); + tt.insert(tr("Maximum"), QString::number(max() * scale, 'f', 0) + + UNIT_SPACE + su); + tt.insert(tr("Minimum"), QString::number(min() * scale, 'f', 0) + + UNIT_SPACE + su); + + return tt.toString(); +} + +void ElevationGraphItem::setUnits(Units units) +{ + setToolTip(toolTip(units)); +} diff --git a/src/elevationgraphitem.h b/src/elevationgraphitem.h new file mode 100644 index 00000000..77e6c710 --- /dev/null +++ b/src/elevationgraphitem.h @@ -0,0 +1,24 @@ +#ifndef ELEVATIONGRAPHITEM_H +#define ELEVATIONGRAPHITEM_H + +#include "graphitem.h" + +class ElevationGraphItem : public GraphItem +{ +public: + ElevationGraphItem(const Graph &graph, QGraphicsItem *parent = 0); + + qreal ascent() const {return _ascent;} + qreal descent() const {return _descent;} + qreal min() const {return -bounds().bottom();} + qreal max() const {return -bounds().top();} + + void setUnits(Units units); + +private: + QString toolTip(Units units) const; + + qreal _ascent, _descent; +}; + +#endif // ELEVATIONGRAPHITEM_H diff --git a/src/graphitem.cpp b/src/graphitem.cpp index a316d45b..f5459a67 100644 --- a/src/graphitem.cpp +++ b/src/graphitem.cpp @@ -25,7 +25,17 @@ GraphItem::GraphItem(const Graph &graph, QGraphicsItem *parent) setZValue(1.0); updatePath(); + updateShape(); updateBounds(); + + setAcceptHoverEvents(true); +} + +void GraphItem::updateShape() +{ + QPainterPathStroker s; + s.setWidth(_width + 1); + _shape = s.createStroke(_path); } void GraphItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, @@ -50,6 +60,7 @@ void GraphItem::setGraphType(GraphType type) _type = type; updatePath(); + updateShape(); updateBounds(); } @@ -65,6 +76,8 @@ void GraphItem::setWidth(int width) _width = width; _pen.setWidth(width); + + updateShape(); } qreal GraphItem::yAtX(qreal x) @@ -143,9 +156,9 @@ void GraphItem::emitSliderPositionChanged(qreal pos) emit sliderPositionChanged(pos); } -void GraphItem::selected(bool selected) +void GraphItem::hover(bool hover) { - if (selected) { + if (hover) { _pen.setWidth(_width + 1); setZValue(zValue() + 1.0); } else { @@ -165,6 +178,7 @@ void GraphItem::setScale(qreal sx, qreal sy) _sx = sx; _sy = sy; updatePath(); + updateShape(); } void GraphItem::updatePath() @@ -199,3 +213,25 @@ void GraphItem::updateBounds() _bounds = QRectF(QPointF(left, top), QPointF(right, bottom)); } + +void GraphItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event); + + _pen.setWidthF(_width + 1); + setZValue(zValue() + 1.0); + update(); + + emit selected(true); +} + +void GraphItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) +{ + Q_UNUSED(event); + + _pen.setWidthF(_width); + setZValue(zValue() - 1.0); + update(); + + emit selected(false); +} diff --git a/src/graphitem.h b/src/graphitem.h index f4443bbd..2162d6d7 100644 --- a/src/graphitem.h +++ b/src/graphitem.h @@ -3,6 +3,7 @@ #include #include +#include "units.h" #include "graph.h" class GraphItem : public QGraphicsObject @@ -12,8 +13,8 @@ class GraphItem : public QGraphicsObject public: GraphItem(const Graph &graph, QGraphicsItem *parent = 0); - QRectF boundingRect() const - {return _path.boundingRect();} + QPainterPath shape() const {return _shape;} + QRectF boundingRect() const {return _shape.boundingRect();} void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); @@ -29,15 +30,22 @@ public: qreal yAtX(qreal x); qreal distanceAtTime(qreal time); + virtual void setUnits(Units units) {Q_UNUSED(units);} + signals: void sliderPositionChanged(qreal); + void selected(bool); public slots: void emitSliderPositionChanged(qreal); - void selected(bool selected); + void hover(bool hover); private: + void hoverEnterEvent(QGraphicsSceneHoverEvent *event); + void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); + void updatePath(); + void updateShape(); void updateBounds(); int _id; @@ -48,6 +56,7 @@ private: GraphType _type; QPainterPath _path; + QPainterPath _shape; QRectF _bounds; qreal _sx, _sy; diff --git a/src/graphview.cpp b/src/graphview.cpp index 35ae82fd..a21955bc 100644 --- a/src/graphview.cpp +++ b/src/graphview.cpp @@ -139,6 +139,10 @@ void GraphView::setXUnits() void GraphView::setUnits(Units units) { _units = units; + + for (int i = 0; i < _graphs.count(); i++) + _graphs.at(i)->setUnits(units); + setXUnits(); } @@ -167,29 +171,27 @@ void GraphView::showGrid(bool show) _grid->setVisible(show); } -void GraphView::loadGraph(const Graph &graph, PathItem *path, int id) +void GraphView::addGraph(GraphItem *graph, PathItem *path, int id) { - if (graph.size() < 2) - return; + graph->setUnits(_units); + graph->setGraphType(_graphType); + graph->setId(id); + graph->setColor(_palette.nextColor()); + graph->setWidth(_width); - GraphItem *gi = new GraphItem(graph); - gi->setGraphType(_graphType); - gi->setId(id); - gi->setColor(_palette.nextColor()); - gi->setWidth(_width); - - connect(this, SIGNAL(sliderPositionChanged(qreal)), gi, + connect(this, SIGNAL(sliderPositionChanged(qreal)), graph, SLOT(emitSliderPositionChanged(qreal))); - connect(gi, SIGNAL(sliderPositionChanged(qreal)), path, + connect(graph, SIGNAL(sliderPositionChanged(qreal)), path, SLOT(moveMarker(qreal))); - connect(path, SIGNAL(selected(bool)), gi, SLOT(selected(bool))); + connect(path, SIGNAL(selected(bool)), graph, SLOT(hover(bool))); + connect(graph, SIGNAL(selected(bool)), path, SLOT(hover(bool))); - _graphs.append(gi); + _graphs.append(graph); if (!_hide.contains(id)) { - _visible.append(gi); - _scene->addItem(gi); - _bounds |= gi->bounds(); + _visible.append(graph); + _scene->addItem(graph); + _bounds |= graph->bounds(); setXUnits(); } } diff --git a/src/graphview.h b/src/graphview.h index 85dcc4e0..dcd77de2 100644 --- a/src/graphview.h +++ b/src/graphview.h @@ -4,9 +4,9 @@ #include #include #include +#include "graph.h" #include "palette.h" #include "units.h" -#include "graph.h" class AxisItem; @@ -25,7 +25,7 @@ public: GraphView(QWidget *parent = 0); ~GraphView(); - void loadGraph(const Graph &graph, PathItem *path, int id = 0); + void addGraph(GraphItem *graph, PathItem *path, int id = 0); int count() const {return _graphs.count();} void redraw(); void clear(); @@ -68,6 +68,9 @@ protected: void clearInfo(); void skipColor() {_palette.nextColor();} + Units _units; + GraphType _graphType; + private slots: void emitSliderPositionChanged(const QPointF &pos); void newSliderPosition(const QPointF &pos); @@ -106,9 +109,6 @@ private: QRectF _bounds; Palette _palette; int _width; - - Units _units; - GraphType _graphType; }; #endif // GRAPHVIEW_H diff --git a/src/heartrategraph.cpp b/src/heartrategraph.cpp index a4530663..60c74ff1 100644 --- a/src/heartrategraph.cpp +++ b/src/heartrategraph.cpp @@ -1,10 +1,10 @@ #include "data.h" +#include "heartrategraphitem.h" #include "heartrategraph.h" HeartRateGraph::HeartRateGraph(QWidget *parent) : GraphTab(parent) { - _units = Metric; _showTracks = true; GraphView::setYUnits(tr("1/min")); @@ -28,21 +28,16 @@ void HeartRateGraph::loadData(const Data &data, const QList &paths) { for (int i = 0; i < data.tracks().count(); i++) { const Graph &graph = data.tracks().at(i)->heartRate(); - qreal sum = 0, w = 0; if (graph.size() < 2) { skipColor(); continue; } - for (int j = 1; j < graph.size(); j++) { - qreal ds = graph.at(j).s() - graph.at(j-1).s(); - sum += graph.at(j).y() * ds; - w += ds; - } - _avg.append(QPointF(data.tracks().at(i)->distance(), sum/w)); + HeartRateGraphItem *gi = new HeartRateGraphItem(graph); + GraphView::addGraph(gi, paths.at(i)); - GraphView::loadGraph(graph, paths.at(i)); + _avg.append(QPointF(data.tracks().at(i)->distance(), gi->avg())); } for (int i = 0; i < data.routes().count(); i++) diff --git a/src/heartrategraph.h b/src/heartrategraph.h index a0b0b062..2e06bb80 100644 --- a/src/heartrategraph.h +++ b/src/heartrategraph.h @@ -22,7 +22,6 @@ private: QList _avg; - enum Units _units; bool _showTracks; }; diff --git a/src/heartrategraphitem.cpp b/src/heartrategraphitem.cpp new file mode 100644 index 00000000..9a7fc4f4 --- /dev/null +++ b/src/heartrategraphitem.cpp @@ -0,0 +1,26 @@ +#include "tooltip.h" +#include "heartrategraphitem.h" + +HeartRateGraphItem::HeartRateGraphItem(const Graph &graph, QGraphicsItem *parent) + : GraphItem(graph, parent) +{ + qreal sum = 0; + + for (int j = 1; j < graph.size(); j++) + sum += graph.at(j).y() * (graph.at(j).s() - graph.at(j-1).s()); + _avg = sum/graph.last().s(); + + setToolTip(toolTip()); +} + +QString HeartRateGraphItem::toolTip() const +{ + ToolTip tt; + + tt.insert(tr("Maximum"), QString::number(max(), 'f', 0) + + UNIT_SPACE + tr("1/min")); + tt.insert(tr("Average"), QString::number(avg(), 'f', 0) + + UNIT_SPACE + tr("1/min")); + + return tt.toString(); +} diff --git a/src/heartrategraphitem.h b/src/heartrategraphitem.h new file mode 100644 index 00000000..f3941b68 --- /dev/null +++ b/src/heartrategraphitem.h @@ -0,0 +1,20 @@ +#ifndef HEARTRATEGRAPHITEM_H +#define HEARTRATEGRAPHITEM_H + +#include "graphitem.h" + +class HeartRateGraphItem : public GraphItem +{ +public: + HeartRateGraphItem(const Graph &graph, QGraphicsItem *parent = 0); + + qreal max() const {return -bounds().top();} + qreal avg() const {return _avg;} + +private: + QString toolTip() const; + + qreal _avg; +}; + +#endif // HEARTRATEGRAPHITEM_H diff --git a/src/pathitem.cpp b/src/pathitem.cpp index cf2950d4..59c34151 100644 --- a/src/pathitem.cpp +++ b/src/pathitem.cpp @@ -154,6 +154,19 @@ void PathItem::moveMarker(qreal distance) _marker->setVisible(false); } +void PathItem::hover(bool hover) +{ + if (hover) { + _pen.setWidth(_width + 1); + setZValue(zValue() + 1.0); + } else { + _pen.setWidth(_width); + setZValue(zValue() - 1.0); + } + + update(); +} + void PathItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { Q_UNUSED(event); diff --git a/src/pathitem.h b/src/pathitem.h index aabc6cbf..d4d4e4cc 100644 --- a/src/pathitem.h +++ b/src/pathitem.h @@ -32,6 +32,7 @@ public: public slots: void moveMarker(qreal distance); + void hover(bool hover); signals: void selected(bool); diff --git a/src/powergraph.cpp b/src/powergraph.cpp index c227fa01..90ee98e9 100644 --- a/src/powergraph.cpp +++ b/src/powergraph.cpp @@ -1,10 +1,10 @@ #include "data.h" +#include "powergraphitem.h" #include "powergraph.h" PowerGraph::PowerGraph(QWidget *parent) : GraphTab(parent) { - _units = Metric; _showTracks = true; GraphView::setYUnits(tr("W")); @@ -28,21 +28,16 @@ void PowerGraph::loadData(const Data &data, const QList &paths) { for (int i = 0; i < data.tracks().count(); i++) { const Graph &graph = data.tracks().at(i)->power(); - qreal sum = 0, w = 0; if (graph.size() < 2) { skipColor(); continue; } - for (int j = 1; j < graph.size(); j++) { - qreal ds = graph.at(j).s() - graph.at(j-1).s(); - sum += graph.at(j).y() * ds; - w += ds; - } - _avg.append(QPointF(data.tracks().at(i)->distance(), sum/w)); + PowerGraphItem *gi = new PowerGraphItem(graph); + GraphView::addGraph(gi, paths.at(i)); - GraphView::loadGraph(graph, paths.at(i)); + _avg.append(QPointF(data.tracks().at(i)->distance(), gi->avg())); } for (int i = 0; i < data.routes().count(); i++) diff --git a/src/powergraph.h b/src/powergraph.h index d369756d..58553a11 100644 --- a/src/powergraph.h +++ b/src/powergraph.h @@ -22,7 +22,6 @@ private: QList _avg; - enum Units _units; bool _showTracks; }; diff --git a/src/powergraphitem.cpp b/src/powergraphitem.cpp new file mode 100644 index 00000000..c5921f9d --- /dev/null +++ b/src/powergraphitem.cpp @@ -0,0 +1,26 @@ +#include "tooltip.h" +#include "powergraphitem.h" + +PowerGraphItem::PowerGraphItem(const Graph &graph, QGraphicsItem *parent) + : GraphItem(graph, parent) +{ + qreal sum = 0; + + for (int j = 1; j < graph.size(); j++) + sum += graph.at(j).y() * (graph.at(j).s() - graph.at(j-1).s()); + _avg = sum/graph.last().s(); + + setToolTip(toolTip()); +} + +QString PowerGraphItem::toolTip() const +{ + ToolTip tt; + + tt.insert(tr("Maximum"), QString::number(max(), 'f', 1) + + UNIT_SPACE + tr("1/min")); + tt.insert(tr("Average"), QString::number(avg(), 'f', 1) + + UNIT_SPACE + tr("1/min")); + + return tt.toString(); +} diff --git a/src/powergraphitem.h b/src/powergraphitem.h new file mode 100644 index 00000000..d05edb64 --- /dev/null +++ b/src/powergraphitem.h @@ -0,0 +1,20 @@ +#ifndef POWERGRAPHITEM_H +#define POWERGRAPHITEM_H + +#include "graphitem.h" + +class PowerGraphItem : public GraphItem +{ +public: + PowerGraphItem(const Graph &graph, QGraphicsItem *parent = 0); + + qreal max() const {return -bounds().top();} + qreal avg() const {return _avg;} + +private: + QString toolTip() const; + + qreal _avg; +}; + +#endif // POWERGRAPHITEM_H diff --git a/src/routeitem.cpp b/src/routeitem.cpp index 46022663..33bfab26 100644 --- a/src/routeitem.cpp +++ b/src/routeitem.cpp @@ -7,7 +7,7 @@ #include "routeitem.h" -QString RouteItem::toolTip(Units units) +QString RouteItem::toolTip(Units units) const { ToolTip tt; diff --git a/src/routeitem.h b/src/routeitem.h index 9b5cf2fd..2c818e5f 100644 --- a/src/routeitem.h +++ b/src/routeitem.h @@ -14,7 +14,6 @@ class RouteItem : public PathItem public: RouteItem(const Route &route, Map *map, QGraphicsItem *parent = 0); - //void setScale(qreal scale); void setMap(Map *map); void setUnits(Units units); @@ -22,7 +21,7 @@ public: void showWaypointLabels(bool show); private: - QString toolTip(Units units); + QString toolTip(Units units) const; QString _name; QString _desc; diff --git a/src/speedgraph.cpp b/src/speedgraph.cpp index 6b3381b7..60b741a6 100644 --- a/src/speedgraph.cpp +++ b/src/speedgraph.cpp @@ -1,11 +1,12 @@ #include "config.h" #include "data.h" +#include "tooltip.h" +#include "speedgraphitem.h" #include "speedgraph.h" SpeedGraph::SpeedGraph(QWidget *parent) : GraphTab(parent) { - _units = Metric; _timeType = Total; _showTracks = true; @@ -29,18 +30,19 @@ void SpeedGraph::setInfo() void SpeedGraph::loadData(const Data &data, const QList &paths) { for (int i = 0; i < data.tracks().count(); i++) { - const Graph &graph = data.tracks().at(i)->speed(); + const Track *track = data.tracks().at(i); + const Graph &graph = track->speed(); + if (graph.size() < 2) { skipColor(); continue; } - _avg.append(QPointF(data.tracks().at(i)->distance(), - data.tracks().at(i)->distance() / data.tracks().at(i)->time())); - _avgM.append(QPointF(data.tracks().at(i)->distance(), - data.tracks().at(i)->distance() / data.tracks().at(i)->movingTime())); + SpeedGraphItem *gi = new SpeedGraphItem(graph, track->movingTime()); + GraphView::addGraph(gi, paths.at(i)); - GraphView::loadGraph(graph, paths.at(i)); + _avg.append(QPointF(track->distance(), gi->avg())); + _mavg.append(QPointF(track->distance(), gi->mavg())); } for (int i = 0; i < data.routes().count(); i++) @@ -55,7 +57,7 @@ qreal SpeedGraph::avg() const { qreal sum = 0, w = 0; QList::const_iterator it; - const QList &list = (_timeType == Moving) ? _avgM : _avg; + const QList &list = (_timeType == Moving) ? _mavg : _avg; for (it = list.begin(); it != list.end(); it++) { sum += it->y() * it->x(); @@ -68,7 +70,7 @@ qreal SpeedGraph::avg() const void SpeedGraph::clear() { _avg.clear(); - _avgM.clear(); + _mavg.clear(); GraphView::clear(); } @@ -86,11 +88,10 @@ void SpeedGraph::setYUnits() void SpeedGraph::setUnits(enum Units units) { - _units = units; + GraphView::setUnits(units); setYUnits(); setInfo(); - GraphView::setUnits(units); redraw(); } diff --git a/src/speedgraph.h b/src/speedgraph.h index 6fd12eef..fa0611e0 100644 --- a/src/speedgraph.h +++ b/src/speedgraph.h @@ -14,8 +14,8 @@ public: QString label() const {return tr("Speed");} void loadData(const Data &data, const QList &paths); void clear(); - void setUnits(enum Units units); - void setTimeType(enum TimeType type); + void setUnits(Units units); + void setTimeType(TimeType type); void showTracks(bool show); private: @@ -25,9 +25,8 @@ private: void setInfo(); QList _avg; - QList _avgM; + QList _mavg; - enum Units _units; enum TimeType _timeType; bool _showTracks; }; diff --git a/src/speedgraphitem.cpp b/src/speedgraphitem.cpp new file mode 100644 index 00000000..3449d939 --- /dev/null +++ b/src/speedgraphitem.cpp @@ -0,0 +1,32 @@ +#include "tooltip.h" +#include "speedgraphitem.h" + +SpeedGraphItem::SpeedGraphItem(const Graph &graph, qreal movingTime, + QGraphicsItem *parent) : GraphItem(graph, parent) +{ + _avg = graph.last().s() / graph.last().t(); + _mavg = graph.last().s() / movingTime; + + setToolTip(toolTip(Metric)); +} + +QString SpeedGraphItem::toolTip(Units units) const +{ + ToolTip tt; + qreal scale = (units == Metric) ? MS2KMH : MS2MIH; + QString su = (units == Metric) ? tr("km/h") : tr("mi/h"); + + tt.insert(tr("Maximum"), QString::number(max() * scale, 'f', 1) + + UNIT_SPACE + su); + tt.insert(tr("Average"), QString::number(avg() * scale, 'f', 1) + + UNIT_SPACE + su); + tt.insert(tr("Moving average"), QString::number(mavg() * scale, 'f', 1) + + UNIT_SPACE + su); + + return tt.toString(); +} + +void SpeedGraphItem::setUnits(Units units) +{ + setToolTip(toolTip(units)); +} diff --git a/src/speedgraphitem.h b/src/speedgraphitem.h new file mode 100644 index 00000000..ec3705aa --- /dev/null +++ b/src/speedgraphitem.h @@ -0,0 +1,24 @@ +#ifndef SPEEDGRAPHITEM_H +#define SPEEDGRAPHITEM_H + +#include "graphitem.h" + +class SpeedGraphItem : public GraphItem +{ +public: + SpeedGraphItem(const Graph &graph, qreal movingTime, + QGraphicsItem *parent = 0); + + qreal max() const {return -bounds().top();} + qreal avg() const {return _avg;} + qreal mavg() const {return _mavg;} + + void setUnits(Units units); + +private: + QString toolTip(Units units) const; + + qreal _avg, _mavg; +}; + +#endif // SPEEDGRAPHITEM_H diff --git a/src/temperaturegraph.cpp b/src/temperaturegraph.cpp index e315da92..3f1bb18a 100644 --- a/src/temperaturegraph.cpp +++ b/src/temperaturegraph.cpp @@ -1,10 +1,10 @@ #include "data.h" +#include "temperaturegraphitem.h" #include "temperaturegraph.h" TemperatureGraph::TemperatureGraph(QWidget *parent) : GraphTab(parent) { - _units = Metric; _showTracks = true; setYUnits(); @@ -30,21 +30,16 @@ void TemperatureGraph::loadData(const Data &data, const QList &paths { for (int i = 0; i < data.tracks().count(); i++) { const Graph &graph = data.tracks().at(i)->temperature(); - qreal sum = 0, w = 0; if (graph.size() < 2) { skipColor(); continue; } - for (int j = 1; j < graph.size(); j++) { - qreal ds = graph.at(j).s() - graph.at(j-1).s(); - sum += graph.at(j).y() * ds; - w += ds; - } - _avg.append(QPointF(data.tracks().at(i)->distance(), sum/w)); + TemperatureGraphItem *gi = new TemperatureGraphItem(graph); + GraphView::addGraph(gi, paths.at(i)); - GraphView::loadGraph(graph, paths.at(i)); + _avg.append(QPointF(data.tracks().at(i)->distance(), gi->avg())); } for (int i = 0; i < data.routes().count(); i++) @@ -90,11 +85,10 @@ void TemperatureGraph::setYUnits() void TemperatureGraph::setUnits(enum Units units) { - _units = units; + GraphView::setUnits(units); setYUnits(); setInfo(); - GraphView::setUnits(units); redraw(); } diff --git a/src/temperaturegraph.h b/src/temperaturegraph.h index 54e6fefd..4f9f7159 100644 --- a/src/temperaturegraph.h +++ b/src/temperaturegraph.h @@ -25,7 +25,6 @@ private: QList _avg; - enum Units _units; bool _showTracks; }; diff --git a/src/temperaturegraphitem.cpp b/src/temperaturegraphitem.cpp new file mode 100644 index 00000000..8ba96ffa --- /dev/null +++ b/src/temperaturegraphitem.cpp @@ -0,0 +1,37 @@ +#include "tooltip.h" +#include "temperaturegraphitem.h" + +TemperatureGraphItem::TemperatureGraphItem(const Graph &graph, + QGraphicsItem *parent) : GraphItem(graph, parent) +{ + qreal sum = 0; + + for (int j = 1; j < graph.size(); j++) + sum += graph.at(j).y() * (graph.at(j).s() - graph.at(j-1).s()); + _avg = sum/graph.last().s(); + + setToolTip(toolTip(Metric)); +} + +QString TemperatureGraphItem::toolTip(Units units) const +{ + ToolTip tt; + qreal scale = (units == Metric) ? 1.0 : C2FS; + qreal offset = (units == Metric) ? 0 : C2FO; + QString su = (units == Metric) ? + QChar(0x00B0) + tr("C") : QChar(0x00B0) + tr("F"); + + tt.insert(tr("Average"), QString::number(avg() * scale + offset, 'f', 1) + + UNIT_SPACE + su); + tt.insert(tr("Maximum"), QString::number(max() * scale + offset, 'f', 1) + + UNIT_SPACE + su); + tt.insert(tr("Minimum"), QString::number(min() * scale + offset, 'f', 1) + + UNIT_SPACE + su); + + return tt.toString(); +} + +void TemperatureGraphItem::setUnits(Units units) +{ + setToolTip(toolTip(units)); +} diff --git a/src/temperaturegraphitem.h b/src/temperaturegraphitem.h new file mode 100644 index 00000000..a102b4d5 --- /dev/null +++ b/src/temperaturegraphitem.h @@ -0,0 +1,23 @@ +#ifndef TEMPERATUREGRAPHITEM_H +#define TEMPERATUREGRAPHITEM_H + +#include "graphitem.h" + +class TemperatureGraphItem : public GraphItem +{ +public: + TemperatureGraphItem(const Graph &graph, QGraphicsItem *parent = 0); + + qreal max() const {return -bounds().top();} + qreal min() const {return -bounds().bottom();} + qreal avg() const {return _avg;} + + void setUnits(Units units); + +private: + QString toolTip(Units units) const; + + qreal _avg; +}; + +#endif // TEMPERATUREGRAPHITEM_H diff --git a/src/trackitem.cpp b/src/trackitem.cpp index 19c22bc2..c586c5ce 100644 --- a/src/trackitem.cpp +++ b/src/trackitem.cpp @@ -5,7 +5,7 @@ #include "trackitem.h" -QString TrackItem::toolTip(Units units) +QString TrackItem::toolTip(Units units) const { ToolTip tt; diff --git a/src/trackitem.h b/src/trackitem.h index 6774dda5..616a6e54 100644 --- a/src/trackitem.h +++ b/src/trackitem.h @@ -19,7 +19,7 @@ public: void setUnits(Units units); private: - QString toolTip(Units units); + QString toolTip(Units units) const; QString _name; QString _desc;