summaryrefslogtreecommitdiffstats
path: root/stats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2021-01-05 13:04:53 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2021-01-06 12:31:22 -0800
commit8dfa3f6db3eda8bce432afb7407efe2d8822ebbd (patch)
tree2a1c6f629fc161c33da6e7515c42fad138a0d6de /stats
parent4ab9f1c6b06204285267e79b5ed993514e0213e2 (diff)
downloadsubsurface-8dfa3f6db3eda8bce432afb7407efe2d8822ebbd.tar.gz
statistics: draw title of axes
Easy enough to implement, but one weirdness: To get the height of the rotated text, one has to access the width() member of the boundingRect. I'm not sure if that makes sense, but so be it. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'stats')
-rw-r--r--stats/statsaxis.cpp65
-rw-r--r--stats/statsaxis.h16
-rw-r--r--stats/statsview.cpp3
3 files changed, 55 insertions, 29 deletions
diff --git a/stats/statsaxis.cpp b/stats/statsaxis.cpp
index 1a425cc0c..23923e7ea 100644
--- a/stats/statsaxis.cpp
+++ b/stats/statsaxis.cpp
@@ -23,10 +23,10 @@ static const double axisLabelSpaceVertical = 2.0; // Space between axis or ticks
static const double axisTitleSpaceHorizontal = 2.0; // Space between labels and title
static const double axisTitleSpaceVertical = 2.0; // Space between labels and title
-StatsAxis::StatsAxis(QtCharts::QChart *chart, bool horizontal, bool labelsBetweenTicks) :
+StatsAxis::StatsAxis(QtCharts::QChart *chart, const QString &titleIn, bool horizontal, bool labelsBetweenTicks) :
QGraphicsLineItem(chart),
chart(chart), horizontal(horizontal), labelsBetweenTicks(labelsBetweenTicks),
- size(1.0), zeroOnScreen(0.0), min(0.0), max(1.0)
+ size(1.0), zeroOnScreen(0.0), min(0.0), max(1.0), labelWidth(0.0)
{
// use a Light version of the application fond for both labels and title
labelFont = QFont();
@@ -34,6 +34,13 @@ StatsAxis::StatsAxis(QtCharts::QChart *chart, bool horizontal, bool labelsBetwee
titleFont = labelFont;
setPen(QPen(axisColor, axisWidth));
setZValue(ZValues::axes);
+ if (!titleIn.isEmpty()) {
+ title = std::make_unique<QGraphicsSimpleTextItem>(titleIn, chart);
+ title->setFont(titleFont);
+ title->setBrush(darkLabelColor);
+ if (!horizontal)
+ title->setRotation(-90.0);
+ }
}
StatsAxis::~StatsAxis()
@@ -76,18 +83,19 @@ int StatsAxis::guessNumTicks(const std::vector<QString> &strings) const
return std::max(numTicks, 2);
}
+double StatsAxis::titleSpace() const
+{
+ if (!title)
+ return 0.0;
+ return horizontal ? QFontMetrics(titleFont).height() + axisTitleSpaceHorizontal
+ : QFontMetrics(titleFont).height() + axisTitleSpaceVertical;
+}
+
double StatsAxis::width() const
{
if (horizontal)
return 0.0; // Only supported for vertical axes
- double labelWidth = 0.0;
- for (const Label &label: labels) {
- double w = label.label->boundingRect().width();
- if (w > labelWidth)
- labelWidth = w;
- }
- return labelWidth + axisLabelSpaceVertical +
- QFontMetrics(titleFont).height() + axisTitleSpaceVertical +
+ return labelWidth + axisLabelSpaceVertical + titleSpace() +
(labelsBetweenTicks ? 0.0 : axisTickSizeVertical);
}
@@ -96,7 +104,7 @@ double StatsAxis::height() const
if (!horizontal)
return 0.0; // Only supported for horizontal axes
return QFontMetrics(labelFont).height() + axisLabelSpaceHorizontal +
- QFontMetrics(titleFont).height() + axisTitleSpaceHorizontal +
+ titleSpace() +
(labelsBetweenTicks ? 0.0 : axisTickSizeHorizontal);
}
@@ -146,6 +154,12 @@ void StatsAxis::setSize(double sizeIn)
{
size = sizeIn;
updateLabels();
+ labelWidth = 0.0;
+ for (const Label &label: labels) {
+ double w = label.label->boundingRect().width();
+ if (w > labelWidth)
+ labelWidth = w;
+ }
}
void StatsAxis::setPos(QPointF pos)
@@ -164,6 +178,9 @@ void StatsAxis::setPos(QPointF pos)
tick.item->setLine(x, y, x, y + axisTickSizeHorizontal);
}
setLine(zeroOnScreen, y, zeroOnScreen + size, y);
+ if (title)
+ title->setPos(zeroOnScreen + (size - title->boundingRect().width()) / 2.0,
+ labelY + QFontMetrics(labelFont).height() + axisTitleSpaceHorizontal);
} else {
double fontHeight = QFontMetrics(labelFont).height();
zeroOnScreen = pos.y();
@@ -178,12 +195,18 @@ void StatsAxis::setPos(QPointF pos)
double y = toScreen(tick.pos);
tick.item->setLine(x, y, x - axisTickSizeVertical, y);
}
+ // This is very confusing: even though we need the height of the title, the correct
+ // size is stored in boundingRect().width(). Presumably because the item is rotated
+ // by -90°. Apparently, the boundingRect is in item-local coordinates?
+ if (title)
+ title->setPos(labelX - labelWidth - QFontMetrics(labelFont).height() - axisTitleSpaceVertical,
+ zeroOnScreen - (size - title->boundingRect().width()) / 2.0);
setLine(x, zeroOnScreen, x, zeroOnScreen - size);
}
}
-ValueAxis::ValueAxis(QtCharts::QChart *chart, double min, double max, int decimals, bool horizontal) :
- StatsAxis(chart, horizontal, false),
+ValueAxis::ValueAxis(QtCharts::QChart *chart, const QString &title, double min, double max, int decimals, bool horizontal) :
+ StatsAxis(chart, title, horizontal, false),
min(min), max(max), decimals(decimals)
{
}
@@ -237,8 +260,8 @@ void ValueAxis::updateLabels()
}
}
-CountAxis::CountAxis(QtCharts::QChart *chart, int count, bool horizontal) :
- ValueAxis(chart, 0.0, (double)count, 0, horizontal),
+CountAxis::CountAxis(QtCharts::QChart *chart, const QString &title, int count, bool horizontal) :
+ ValueAxis(chart, title, 0.0, (double)count, 0, horizontal),
count(count)
{
}
@@ -290,8 +313,8 @@ void CountAxis::updateLabels()
}
}
-CategoryAxis::CategoryAxis(QtCharts::QChart *chart, const std::vector<QString> &labelsIn, bool horizontal) :
- StatsAxis(chart, horizontal, true)
+CategoryAxis::CategoryAxis(QtCharts::QChart *chart, const QString &title, const std::vector<QString> &labelsIn, bool horizontal) :
+ StatsAxis(chart, title, horizontal, true)
{
labels.reserve(labelsIn.size());
ticks.reserve(labelsIn.size() + 1);
@@ -309,8 +332,8 @@ void CategoryAxis::updateLabels()
{
}
-HistogramAxis::HistogramAxis(QtCharts::QChart *chart, std::vector<HistogramAxisEntry> bins, bool horizontal) :
- StatsAxis(chart, horizontal, false),
+HistogramAxis::HistogramAxis(QtCharts::QChart *chart, const QString &title, std::vector<HistogramAxisEntry> bins, bool horizontal) :
+ StatsAxis(chart, title, horizontal, false),
bin_values(std::move(bins))
{
if (bin_values.size() < 2) // Less than two makes no sense -> there must be at least one category
@@ -498,7 +521,7 @@ static std::vector<HistogramAxisEntry> timeRangeToBins(double from, double to)
return res;
}
-DateAxis::DateAxis(QtCharts::QChart *chart, double from, double to, bool horizontal) :
- HistogramAxis(chart, timeRangeToBins(from, to), horizontal)
+DateAxis::DateAxis(QtCharts::QChart *chart, const QString &title, double from, double to, bool horizontal) :
+ HistogramAxis(chart, title, timeRangeToBins(from, to), horizontal)
{
}
diff --git a/stats/statsaxis.h b/stats/statsaxis.h
index c9619a124..c25ffe692 100644
--- a/stats/statsaxis.h
+++ b/stats/statsaxis.h
@@ -31,7 +31,7 @@ public:
double toScreen(double) const;
double toValue(double) const;
protected:
- StatsAxis(QtCharts::QChart *chart, bool horizontal, bool labelsBetweenTicks);
+ StatsAxis(QtCharts::QChart *chart, const QString &title, bool horizontal, bool labelsBetweenTicks);
QtCharts::QChart *chart;
struct Label {
@@ -56,14 +56,18 @@ protected:
bool labelsBetweenTicks; // When labels are between ticks, they can be moved closer to the axis
QFont labelFont, titleFont;
+ std::unique_ptr<QGraphicsSimpleTextItem> title;
double size; // width for horizontal, height for vertical
double zeroOnScreen;
double min, max;
+ double labelWidth; // Maximum width of labels
+private:
+ double titleSpace() const; // Space needed for title
};
class ValueAxis : public StatsAxis {
public:
- ValueAxis(QtCharts::QChart *chart, double min, double max, int decimals, bool horizontal);
+ ValueAxis(QtCharts::QChart *chart, const QString &title, double min, double max, int decimals, bool horizontal);
private:
double min, max;
int decimals;
@@ -72,7 +76,7 @@ private:
class CountAxis : public ValueAxis {
public:
- CountAxis(QtCharts::QChart *chart, int count, bool horizontal);
+ CountAxis(QtCharts::QChart *chart, const QString &title, int count, bool horizontal);
private:
int count;
void updateLabels() override;
@@ -80,7 +84,7 @@ private:
class CategoryAxis : public StatsAxis {
public:
- CategoryAxis(QtCharts::QChart *chart, const std::vector<QString> &labels, bool horizontal);
+ CategoryAxis(QtCharts::QChart *chart, const QString &title, const std::vector<QString> &labels, bool horizontal);
private:
void updateLabels();
};
@@ -93,7 +97,7 @@ struct HistogramAxisEntry {
class HistogramAxis : public StatsAxis {
public:
- HistogramAxis(QtCharts::QChart *chart, std::vector<HistogramAxisEntry> bin_values, bool horizontal);
+ HistogramAxis(QtCharts::QChart *chart, const QString &title, std::vector<HistogramAxisEntry> bin_values, bool horizontal);
private:
void updateLabels() override;
std::vector<HistogramAxisEntry> bin_values;
@@ -102,7 +106,7 @@ private:
class DateAxis : public HistogramAxis {
public:
- DateAxis(QtCharts::QChart *chart, double from, double to, bool horizontal);
+ DateAxis(QtCharts::QChart *chart, const QString &title, double from, double to, bool horizontal);
};
#endif
diff --git a/stats/statsview.cpp b/stats/statsview.cpp
index fdf6e9dc3..394620d13 100644
--- a/stats/statsview.cpp
+++ b/stats/statsview.cpp
@@ -186,8 +186,7 @@ void StatsView::updateTitlePos()
template <typename T, class... Args>
T *StatsView::createAxis(const QString &title, Args&&... args)
{
- // TODO: set title
- T *res = new T(chart, std::forward<Args>(args)...);
+ T *res = new T(chart, title, std::forward<Args>(args)...);
axes.emplace_back(res);
return res;
}