mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
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>
This commit is contained in:
parent
bd252fc820
commit
21b8cded56
6 changed files with 44 additions and 14 deletions
|
@ -11,6 +11,8 @@
|
||||||
#include <QSGTexture>
|
#include <QSGTexture>
|
||||||
#include <QSGTextureMaterial>
|
#include <QSGTextureMaterial>
|
||||||
|
|
||||||
|
static int selectionOverlayPixelSize = 2;
|
||||||
|
|
||||||
static int round_up(double f)
|
static int round_up(double f)
|
||||||
{
|
{
|
||||||
return static_cast<int>(ceil(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->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...?
|
// 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
|
// 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.
|
// is dervied from "from" and subtracted from the origin angle at 12:00.
|
||||||
|
@ -487,13 +505,13 @@ void ChartBarItem::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selected && positionDirty) {
|
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();
|
auto selectionVertices = selectionGeometry->vertexDataAsTexturedPoint2D();
|
||||||
selectionNode->markDirty(QSGNode::DirtyGeometry);
|
selectionNode->markDirty(QSGNode::DirtyGeometry);
|
||||||
setPoint(selectionVertices[0], rect.topLeft(), QPointF());
|
setPoint(selectionVertices[0], rect.topLeft(), QPointF());
|
||||||
setPoint(selectionVertices[1], rect.topRight(), QPointF(rect.width() / 4.0, 0.0));
|
setPoint(selectionVertices[1], rect.topRight(), QPointF(rect.width() / pixelFactor, 0.0));
|
||||||
setPoint(selectionVertices[2], rect.bottomRight(), QPointF(rect.width() / 4.0, rect.height() / 4.0));
|
setPoint(selectionVertices[2], rect.bottomRight(), QPointF(rect.width() / pixelFactor, rect.height() / pixelFactor));
|
||||||
setPoint(selectionVertices[3], rect.bottomLeft(), QPointF(0.0, rect.height() / 4.0));
|
setPoint(selectionVertices[3], rect.bottomLeft(), QPointF(0.0, rect.height() / pixelFactor));
|
||||||
}
|
}
|
||||||
|
|
||||||
positionDirty = colorDirty = selectedDirty = false;
|
positionDirty = colorDirty = selectedDirty = false;
|
||||||
|
|
|
@ -107,7 +107,7 @@ private:
|
||||||
class ChartPieItem : public ChartPixmapItem {
|
class ChartPieItem : public ChartPixmapItem {
|
||||||
public:
|
public:
|
||||||
ChartPieItem(StatsView &v, ChartZValue z, double borderWidth);
|
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
|
void resize(QSizeF size); // As in base class, but clears the canvas
|
||||||
private:
|
private:
|
||||||
double borderWidth;
|
double borderWidth;
|
||||||
|
|
|
@ -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,
|
PieSeries::Item::Item(StatsView &view, const QString &name, int from, std::vector<dive *> divesIn, int totalCount,
|
||||||
int bin_nr, int numBins) :
|
int bin_nr, int numBins) :
|
||||||
name(name),
|
name(name),
|
||||||
dives(std::move(divesIn))
|
dives(std::move(divesIn)),
|
||||||
|
selected(allDivesSelected(dives))
|
||||||
{
|
{
|
||||||
QFont f; // make configurable
|
QFont f; // make configurable
|
||||||
QLocale loc;
|
QLocale loc;
|
||||||
|
@ -72,7 +73,7 @@ void PieSeries::Item::highlight(ChartPieItem &item, int bin_nr, bool highlight,
|
||||||
QColor border = highlight ? highlightedBorderColor : ::borderColor;
|
QColor border = highlight ? highlightedBorderColor : ::borderColor;
|
||||||
if (innerLabel)
|
if (innerLabel)
|
||||||
innerLabel->setColor(highlight ? darkLabelColor : labelColor(bin_nr, numBins), fill);
|
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,
|
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());
|
setSelection(dives, dives.empty() ? nullptr : dives.front());
|
||||||
return true;
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ private:
|
||||||
double angleFrom, angleTo; // In fraction of total
|
double angleFrom, angleTo; // In fraction of total
|
||||||
std::vector<dive *> dives;
|
std::vector<dive *> dives;
|
||||||
QPointF innerLabelPos, outerLabelPos; // With respect to a (-1, -1)-(1, 1) rectangle.
|
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,
|
Item(StatsView &view, const QString &name, int from, std::vector<dive *> dives, int totalCount,
|
||||||
int bin_nr, int numBins);
|
int bin_nr, int numBins);
|
||||||
void updatePositions(const QPointF ¢er, double radius);
|
void updatePositions(const QPointF ¢er, double radius);
|
||||||
|
@ -65,6 +66,7 @@ private:
|
||||||
QPointF center; // center of drawing area
|
QPointF center; // center of drawing area
|
||||||
double radius; // radius of pie
|
double radius; // radius of pie
|
||||||
int highlighted;
|
int highlighted;
|
||||||
|
void divesSelected(const QVector<dive *> &) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,10 +17,6 @@ QPointF StatsSeries::toScreen(QPointF p)
|
||||||
: QPointF(0.0, 0.0);
|
: QPointF(0.0, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatsSeries::divesSelected(const QVector<dive *> &)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StatsSeries::supportsLassoSelection() const
|
bool StatsSeries::supportsLassoSelection() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
virtual bool supportsLassoSelection() const;
|
virtual bool supportsLassoSelection() const;
|
||||||
// Needs only be defined if supportsLassoSelection() returns true.
|
// Needs only be defined if supportsLassoSelection() returns true.
|
||||||
virtual void selectItemsInRect(const QRectF &rect, bool shiftPressed, const std::vector<dive *> &oldSelection);
|
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:
|
protected:
|
||||||
StatsView &view;
|
StatsView &view;
|
||||||
|
|
Loading…
Reference in a new issue