summaryrefslogtreecommitdiffstats
path: root/stats/statsview.h
diff options
context:
space:
mode:
Diffstat (limited to 'stats/statsview.h')
-rw-r--r--stats/statsview.h139
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