aboutsummaryrefslogtreecommitdiffstats
path: root/stats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2021-02-07 20:48:43 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2021-02-13 13:02:54 -0800
commit21b8cded56854f81327f4f553e32a15ffe5c7b82 (patch)
tree354194513eed9bdb69d31f1855edbade60bb0ad5 /stats
parentbd252fc8201c7e77882ac95ef90ddbf4a16356d3 (diff)
downloadsubsurface-21b8cded56854f81327f4f553e32a15ffe5c7b82.tar.gz
statistics: highlight selected pie slices
In analogy to the other charts, highlight selected pie slices. Overlay them with a checkerboard pattern, like in the bar charts. Since all charts now support highlighting, the divesSelected() virtual function now doesn't need a default implementation anymore. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'stats')
-rw-r--r--stats/chartitem.cpp30
-rw-r--r--stats/chartitem.h2
-rw-r--r--stats/pieseries.cpp18
-rw-r--r--stats/pieseries.h2
-rw-r--r--stats/statsseries.cpp4
-rw-r--r--stats/statsseries.h2
6 files changed, 44 insertions, 14 deletions
diff --git a/stats/chartitem.cpp b/stats/chartitem.cpp
index 1a93de0c9..fb5a0d9ca 100644
--- a/stats/chartitem.cpp
+++ b/stats/chartitem.cpp
@@ -11,6 +11,8 @@
#include <QSGTexture>
#include <QSGTextureMaterial>
+static int selectionOverlayPixelSize = 2;
+
static int round_up(double f)
{
return static_cast<int>(ceil(f));
@@ -289,10 +291,26 @@ ChartPieItem::ChartPieItem(StatsView &v, ChartZValue z, double borderWidth) : Ch
{
}
-void ChartPieItem::drawSegment(double from, double to, QColor fill, QColor border)
+static QBrush makeBrush(QColor fill, bool selected)
+{
+ if (!selected)
+ return QBrush(fill);
+ QImage img(2 * selectionOverlayPixelSize, 2 * selectionOverlayPixelSize, QImage::Format_ARGB32);
+ img.fill(fill);
+ for (int x = 0; x < selectionOverlayPixelSize; ++x) {
+ for (int y = 0; y < selectionOverlayPixelSize; ++y) {
+ img.setPixelColor(x, y, selectionOverlayColor);
+ img.setPixelColor(x + selectionOverlayPixelSize, y + selectionOverlayPixelSize,
+ selectionOverlayColor);
+ }
+ }
+ return QBrush(img);
+}
+
+void ChartPieItem::drawSegment(double from, double to, QColor fill, QColor border, bool selected)
{
painter->setPen(QPen(border, borderWidth));
- painter->setBrush(QBrush(fill));
+ painter->setBrush(makeBrush(fill, selected));
// For whatever obscure reason, angles of pie pieces are given as 16th of a degree...?
// Angles increase CCW, whereas pie charts usually are read CW. Therfore, startAngle
// is dervied from "from" and subtracted from the origin angle at 12:00.
@@ -487,13 +505,13 @@ void ChartBarItem::render()
}
if (selected && positionDirty) {
- // The checkerboard texture is 2x2. By dividing the coordinates by 4, every square is 2x2 pixels on the screen.
+ double pixelFactor = 2.0 * selectionOverlayPixelSize; // The texture image is 2x2 pixels.
auto selectionVertices = selectionGeometry->vertexDataAsTexturedPoint2D();
selectionNode->markDirty(QSGNode::DirtyGeometry);
setPoint(selectionVertices[0], rect.topLeft(), QPointF());
- setPoint(selectionVertices[1], rect.topRight(), QPointF(rect.width() / 4.0, 0.0));
- setPoint(selectionVertices[2], rect.bottomRight(), QPointF(rect.width() / 4.0, rect.height() / 4.0));
- setPoint(selectionVertices[3], rect.bottomLeft(), QPointF(0.0, rect.height() / 4.0));
+ setPoint(selectionVertices[1], rect.topRight(), QPointF(rect.width() / pixelFactor, 0.0));
+ setPoint(selectionVertices[2], rect.bottomRight(), QPointF(rect.width() / pixelFactor, rect.height() / pixelFactor));
+ setPoint(selectionVertices[3], rect.bottomLeft(), QPointF(0.0, rect.height() / pixelFactor));
}
positionDirty = colorDirty = selectedDirty = false;
diff --git a/stats/chartitem.h b/stats/chartitem.h
index ca04d6afd..598e854bc 100644
--- a/stats/chartitem.h
+++ b/stats/chartitem.h
@@ -107,7 +107,7 @@ private:
class ChartPieItem : public ChartPixmapItem {
public:
ChartPieItem(StatsView &v, ChartZValue z, double borderWidth);
- void drawSegment(double from, double to, QColor fill, QColor border); // from and to are relative (0-1 is full disk).
+ void drawSegment(double from, double to, QColor fill, QColor border, bool selected); // from and to are relative (0-1 is full disk).
void resize(QSizeF size); // As in base class, but clears the canvas
private:
double borderWidth;
diff --git a/stats/pieseries.cpp b/stats/pieseries.cpp
index 61579df74..5d940c2b2 100644
--- a/stats/pieseries.cpp
+++ b/stats/pieseries.cpp
@@ -20,7 +20,8 @@ static const double outerLabelRadius = 1.01; // 1.0 = at outer border of pie
PieSeries::Item::Item(StatsView &view, const QString &name, int from, std::vector<dive *> divesIn, int totalCount,
int bin_nr, int numBins) :
name(name),
- dives(std::move(divesIn))
+ dives(std::move(divesIn)),
+ selected(allDivesSelected(dives))
{
QFont f; // make configurable
QLocale loc;
@@ -72,7 +73,7 @@ void PieSeries::Item::highlight(ChartPieItem &item, int bin_nr, bool highlight,
QColor border = highlight ? highlightedBorderColor : ::borderColor;
if (innerLabel)
innerLabel->setColor(highlight ? darkLabelColor : labelColor(bin_nr, numBins), fill);
- item.drawSegment(angleFrom, angleTo, fill, border);
+ item.drawSegment(angleFrom, angleTo, fill, border, selected);
}
PieSeries::PieSeries(StatsView &view, StatsAxis *xAxis, StatsAxis *yAxis, const QString &categoryName,
@@ -277,3 +278,16 @@ bool PieSeries::selectItemsUnderMouse(const QPointF &pos, bool)
setSelection(dives, dives.empty() ? nullptr : dives.front());
return true;
}
+
+void PieSeries::divesSelected(const QVector<dive *> &)
+{
+ for (Item &segment: items) {
+ bool selected = allDivesSelected(segment.dives);
+ if (segment.selected != selected) {
+ segment.selected = selected;
+
+ int idx = &segment - &items[0];
+ segment.highlight(*item, idx, idx == highlighted, (int)items.size());
+ }
+ }
+}
diff --git a/stats/pieseries.h b/stats/pieseries.h
index 05372e84f..83e9acba7 100644
--- a/stats/pieseries.h
+++ b/stats/pieseries.h
@@ -46,6 +46,7 @@ private:
double angleFrom, angleTo; // In fraction of total
std::vector<dive *> dives;
QPointF innerLabelPos, outerLabelPos; // With respect to a (-1, -1)-(1, 1) rectangle.
+ bool selected;
Item(StatsView &view, const QString &name, int from, std::vector<dive *> dives, int totalCount,
int bin_nr, int numBins);
void updatePositions(const QPointF &center, double radius);
@@ -65,6 +66,7 @@ private:
QPointF center; // center of drawing area
double radius; // radius of pie
int highlighted;
+ void divesSelected(const QVector<dive *> &) override;
};
#endif
diff --git a/stats/statsseries.cpp b/stats/statsseries.cpp
index 0885f14de..379628fe1 100644
--- a/stats/statsseries.cpp
+++ b/stats/statsseries.cpp
@@ -17,10 +17,6 @@ QPointF StatsSeries::toScreen(QPointF p)
: QPointF(0.0, 0.0);
}
-void StatsSeries::divesSelected(const QVector<dive *> &)
-{
-}
-
bool StatsSeries::supportsLassoSelection() const
{
return false;
diff --git a/stats/statsseries.h b/stats/statsseries.h
index bc7cd2c57..196427eaf 100644
--- a/stats/statsseries.h
+++ b/stats/statsseries.h
@@ -24,7 +24,7 @@ public:
virtual bool supportsLassoSelection() const;
// Needs only be defined if supportsLassoSelection() returns true.
virtual void selectItemsInRect(const QRectF &rect, bool shiftPressed, const std::vector<dive *> &oldSelection);
- virtual void divesSelected(const QVector<dive *> &dives);
+ virtual void divesSelected(const QVector<dive *> &dives) = 0;
protected:
StatsView &view;