summaryrefslogtreecommitdiffstats
path: root/stats
diff options
context:
space:
mode:
Diffstat (limited to 'stats')
-rw-r--r--stats/CMakeLists.txt2
-rw-r--r--stats/informationbox.cpp75
-rw-r--r--stats/informationbox.h31
3 files changed, 108 insertions, 0 deletions
diff --git a/stats/CMakeLists.txt b/stats/CMakeLists.txt
index bf11d06fd..e8f49e35f 100644
--- a/stats/CMakeLists.txt
+++ b/stats/CMakeLists.txt
@@ -5,6 +5,8 @@ include_directories(.
)
set(SUBSURFACE_STATS_SRCS
+ informationbox.h
+ informationbox.cpp
legend.h
legend.cpp
statsaxis.h
diff --git a/stats/informationbox.cpp b/stats/informationbox.cpp
new file mode 100644
index 000000000..015f821be
--- /dev/null
+++ b/stats/informationbox.cpp
@@ -0,0 +1,75 @@
+#include "informationbox.h"
+#include "statscolors.h"
+#include "zvalues.h"
+
+#include <QChart>
+#include <QFontMetrics>
+
+static const QColor informationBorderColor(Qt::black);
+static const QColor informationColor(0xff, 0xff, 0x00, 192); // Note: fourth argument is opacity
+static const int informationBorder = 2;
+static const int distanceFromPointer = 10; // Distance to place box from mouse pointer or scatter item
+
+InformationBox::InformationBox(QtCharts::QChart *chart) : QGraphicsRectItem(chart), chart(chart)
+{
+ setPen(QPen(informationBorderColor, informationBorder));
+ setBrush(informationColor);
+ setZValue(ZValues::informationBox);
+}
+
+void InformationBox::setText(const std::vector<QString> &text, QPointF pos)
+{
+ width = height = 0.0;
+ textItems.clear();
+
+ for (const QString &s: text) {
+ if (!s.isEmpty())
+ addLine(s);
+ }
+
+ width += 4.0 * informationBorder;
+ height += 4.0 * informationBorder;
+
+ // Setting the position will also set the proper size
+ setPos(pos);
+}
+
+void InformationBox::setPos(QPointF pos)
+{
+ QRectF plotArea = chart->plotArea();
+
+ double x = pos.x() + distanceFromPointer;
+ if (x + width >= plotArea.right() && pos.x() - width >= plotArea.x())
+ x = pos.x() - width;
+ double y = pos.y() + distanceFromPointer;
+ if (y + height >= plotArea.bottom() && pos.y() - height >= plotArea.y())
+ y = pos.y() - height;
+
+ setRect(x, y, width, height);
+ double actY = y + 2.0 * informationBorder;
+ for (auto &item: textItems) {
+ item->setPos(QPointF(x + 2.0 * informationBorder, actY));
+ actY += item->boundingRect().height();
+ }
+}
+
+void InformationBox::addLine(const QString &s)
+{
+ textItems.emplace_back(new QGraphicsSimpleTextItem(s, this));
+ QGraphicsSimpleTextItem &item = *textItems.back();
+ item.setBrush(QBrush(darkLabelColor));
+ item.setPos(QPointF(0.0, height));
+ item.setFont(font);
+ item.setZValue(ZValues::informationBox);
+ QRectF rect = item.boundingRect();
+ width = std::max(width, rect.width());
+ height += rect.height();
+}
+
+// Try to stay within three-thirds of the chart height
+int InformationBox::recommendedMaxLines() const
+{
+ QFontMetrics fm(font);
+ int maxHeight = static_cast<int>(chart->plotArea().height());
+ return maxHeight * 2 / fm.height() / 3;
+}
diff --git a/stats/informationbox.h b/stats/informationbox.h
new file mode 100644
index 000000000..7e9253dc7
--- /dev/null
+++ b/stats/informationbox.h
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+// A small box displaying statistics information, notably
+// for a scatter-plot item or a bar in a bar chart.
+#ifndef INFORMATION_BOX_H
+#define INFORMATION_BOX_H
+
+#include <vector>
+#include <memory>
+#include <QGraphicsRectItem>
+#include <QFont>
+
+namespace QtCharts {
+ class QChart;
+}
+struct dive;
+
+// Information window showing data of highlighted dive
+struct InformationBox : QGraphicsRectItem {
+ InformationBox(QtCharts::QChart *chart);
+ void setText(const std::vector<QString> &text, QPointF pos);
+ void setPos(QPointF pos);
+ int recommendedMaxLines() const;
+private:
+ QtCharts::QChart *chart;
+ QFont font; // For future specialization.
+ double width, height;
+ void addLine(const QString &s);
+ std::vector<std::unique_ptr<QGraphicsSimpleTextItem>> textItems;
+};
+
+#endif