diff options
Diffstat (limited to 'stats/statsview.h')
-rw-r--r-- | stats/statsview.h | 139 |
1 files changed, 77 insertions, 62 deletions
diff --git a/stats/statsview.h b/stats/statsview.h index b1e178565..0af91b382 100644 --- a/stats/statsview.h +++ b/stats/statsview.h @@ -3,13 +3,12 @@ #define STATS_VIEW_H #include "statsstate.h" +#include "statshelper.h" #include <memory> #include <QFont> -#include <QGraphicsScene> #include <QImage> #include <QPainter> #include <QQuickItem> -#include <QGraphicsPolygonItem> struct dive; struct StatsBinner; @@ -17,27 +16,25 @@ struct StatsBin; struct StatsState; struct StatsVariable; -class QGraphicsLineItem; -class QGraphicsSimpleTextItem; class StatsSeries; class CategoryAxis; +class ChartItem; +class ChartTextItem; class CountAxis; class HistogramAxis; +class HistogramMarker; +class QuartileMarker; +class RegressionItem; class StatsAxis; class StatsGrid; class Legend; class QSGTexture; +class RootNode; // Internal implementation detail enum class ChartSubType : int; +enum class ChartZValue : int; enum class StatsOperation : int; -struct regression_data { - double a,b; - double res2, r2, sx2, xavg; - int n; -}; - - class StatsView : public QQuickItem { Q_OBJECT public: @@ -46,16 +43,32 @@ public: ~StatsView(); void plot(const StatsState &state); + void updateFeatures(const StatsState &state); // Updates the visibility of chart features, such as legend, regression, etc. + QQuickWindow *w() const; // Make window available to items + QSizeF size() const; + QRectF plotArea() const; + void addQSGNode(QSGNode *node, ChartZValue z); // Must only be called in render thread! + void registerChartItem(ChartItem &item); + void registerDirtyChartItem(ChartItem &item); + + // Create a chart item and add it to the scene. + // The item must not be deleted by the caller, but can be + // scheduled for deletion using deleteChartItem() below. + // Most items can be made invisible, which is preferred over deletion. + // All items on the scene will be deleted once the chart is reset. + template <typename T, class... Args> + ChartItemPtr<T> createChartItem(Args&&... args); + + template <typename T> + void deleteChartItem(ChartItemPtr<T> &item); private slots: void replotIfVisible(); private: + bool resetChart; + // QtQuick related things QRectF plotRect; QSGNode *updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override; - std::unique_ptr<QImage> img; - std::unique_ptr<QPainter> painter; - QGraphicsScene scene; - std::unique_ptr<QSGTexture> texture; void plotAreaChanged(const QSizeF &size); void reset(); // clears all series and axes @@ -63,39 +76,39 @@ private: void plotBarChart(const std::vector<dive *> &dives, ChartSubType subType, const StatsVariable *categoryVariable, const StatsBinner *categoryBinner, - const StatsVariable *valueVariable, const StatsBinner *valueBinner, bool labels, bool legend); + const StatsVariable *valueVariable, const StatsBinner *valueBinner); void plotValueChart(const std::vector<dive *> &dives, ChartSubType subType, const StatsVariable *categoryVariable, const StatsBinner *categoryBinner, - const StatsVariable *valueVariable, StatsOperation valueAxisOperation, bool labels); + const StatsVariable *valueVariable, StatsOperation valueAxisOperation); void plotDiscreteCountChart(const std::vector<dive *> &dives, ChartSubType subType, - const StatsVariable *categoryVariable, const StatsBinner *categoryBinner, bool labels); + const StatsVariable *categoryVariable, const StatsBinner *categoryBinner); void plotPieChart(const std::vector<dive *> &dives, - const StatsVariable *categoryVariable, const StatsBinner *categoryBinner, bool labels, bool legend); + const StatsVariable *categoryVariable, const StatsBinner *categoryBinner); void plotDiscreteBoxChart(const std::vector<dive *> &dives, const StatsVariable *categoryVariable, const StatsBinner *categoryBinner, const StatsVariable *valueVariable); void plotDiscreteScatter(const std::vector<dive *> &dives, const StatsVariable *categoryVariable, const StatsBinner *categoryBinner, - const StatsVariable *valueVariable, bool quartiles); + const StatsVariable *valueVariable); void plotHistogramCountChart(const std::vector<dive *> &dives, ChartSubType subType, - const StatsVariable *categoryVariable, const StatsBinner *categoryBinner, - bool labels, bool showMedian, bool showMean); + const StatsVariable *categoryVariable, const StatsBinner *categoryBinner); void plotHistogramValueChart(const std::vector<dive *> &dives, ChartSubType subType, const StatsVariable *categoryVariable, const StatsBinner *categoryBinner, - const StatsVariable *valueVariable, StatsOperation valueAxisOperation, bool labels); + const StatsVariable *valueVariable, StatsOperation valueAxisOperation); void plotHistogramStackedChart(const std::vector<dive *> &dives, ChartSubType subType, const StatsVariable *categoryVariable, const StatsBinner *categoryBinner, - const StatsVariable *valueVariable, const StatsBinner *valueBinner, bool labels, bool legend); + const StatsVariable *valueVariable, const StatsBinner *valueBinner); void plotHistogramBoxChart(const std::vector<dive *> &dives, const StatsVariable *categoryVariable, const StatsBinner *categoryBinner, const StatsVariable *valueVariable); void plotScatter(const std::vector<dive *> &dives, const StatsVariable *categoryVariable, const StatsVariable *valueVariable); void setTitle(const QString &); void updateTitlePos(); // After resizing, set title to correct position void plotChart(); + void updateFeatures(); // Updates the visibility of chart features, such as legend, regression, etc. template <typename T, class... Args> T *createSeries(Args&&... args); @@ -114,53 +127,55 @@ private: // Helper functions to add feature to the chart void addLineMarker(double pos, double low, double high, const QPen &pen, bool isHorizontal); - // A short line used to mark quartiles - struct QuartileMarker { - std::unique_ptr<QGraphicsLineItem> item; - StatsAxis *xAxis, *yAxis; - double pos, value; - QuartileMarker(double pos, double value, QGraphicsScene *scene, StatsAxis *xAxis, StatsAxis *yAxis); - void updatePosition(); - }; - - // A regression line - struct RegressionLine { - std::unique_ptr<QGraphicsPolygonItem> item; - std::unique_ptr<QGraphicsPolygonItem> central; - StatsAxis *xAxis, *yAxis; - const struct regression_data reg; - void updatePosition(); - RegressionLine(const struct regression_data reg, QBrush brush, QGraphicsScene *scene, StatsAxis *xAxis, StatsAxis *yAxis); - }; - - // A line marking median or mean in histograms - struct HistogramMarker { - std::unique_ptr<QGraphicsLineItem> item; - StatsAxis *xAxis, *yAxis; - double val; - bool horizontal; - void updatePosition(); - HistogramMarker(double val, bool horizontal, QPen pen, QGraphicsScene *scene, StatsAxis *xAxis, StatsAxis *yAxis); - }; - - void addLinearRegression(const struct regression_data reg, StatsAxis *xAxis, StatsAxis *yAxis); - void addHistogramMarker(double pos, const QPen &pen, bool isHorizontal, StatsAxis *xAxis, StatsAxis *yAxis); StatsState state; QFont titleFont; - std::vector<std::unique_ptr<StatsAxis>> axes; - std::unique_ptr<StatsGrid> grid; std::vector<std::unique_ptr<StatsSeries>> series; - std::unique_ptr<Legend> legend; - std::vector<QuartileMarker> quartileMarkers; - std::vector<RegressionLine> regressionLines; - std::vector<HistogramMarker> histogramMarkers; - std::unique_ptr<QGraphicsSimpleTextItem> title; + std::unique_ptr<StatsGrid> grid; + std::vector<ChartItemPtr<QuartileMarker>> quartileMarkers; + ChartItemPtr<HistogramMarker> medianMarker, meanMarker; StatsSeries *highlightedSeries; StatsAxis *xAxis, *yAxis; + ChartItemPtr<ChartTextItem> title; + ChartItemPtr<Legend> legend; + Legend *draggedItem; + ChartItemPtr<RegressionItem> regressionItem; + QPointF dragStartMouse, dragStartItem; void hoverEnterEvent(QHoverEvent *event) override; void hoverMoveEvent(QHoverEvent *event) override; + void mousePressEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; + void mouseMoveEvent(QMouseEvent *event) override; + RootNode *rootNode; + + // There are three double linked lists of chart items: + // clean items, dirty items and items to be deleted. + struct ChartItemList { + ChartItemList(); + ChartItem *first, *last; + void append(ChartItem &item); + void remove(ChartItem &item); + void clear(); + void splice(ChartItemList &list); + }; + ChartItemList cleanItems, dirtyItems, deletedItems; + void deleteChartItemInternal(ChartItem &item); }; +// This implementation detail must be known to users of the class. +// Perhaps move it into a statsview_impl.h file. +template <typename T, class... Args> +ChartItemPtr<T> StatsView::createChartItem(Args&&... args) +{ + return ChartItemPtr(new T(*this, std::forward<Args>(args)...)); +} + +template <typename T> +void StatsView::deleteChartItem(ChartItemPtr<T> &item) +{ + deleteChartItemInternal(*item); + item.reset(); +} + #endif |