diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2021-02-07 20:48:43 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2021-02-13 13:02:54 -0800 |
commit | 21b8cded56854f81327f4f553e32a15ffe5c7b82 (patch) | |
tree | 354194513eed9bdb69d31f1855edbade60bb0ad5 /stats | |
parent | bd252fc8201c7e77882ac95ef90ddbf4a16356d3 (diff) | |
download | subsurface-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.cpp | 30 | ||||
-rw-r--r-- | stats/chartitem.h | 2 | ||||
-rw-r--r-- | stats/pieseries.cpp | 18 | ||||
-rw-r--r-- | stats/pieseries.h | 2 | ||||
-rw-r--r-- | stats/statsseries.cpp | 4 | ||||
-rw-r--r-- | stats/statsseries.h | 2 |
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 ¢er, 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; |