From ba3c0bf34e927dbf74a385e5ce1d626abbd29d7f Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Wed, 18 Aug 2021 20:05:05 +0100 Subject: [PATCH] UserChart Bar/Stacked show Category on legend .. when hovering over a bar chart its sometimes useful to see the category name (x-axis) on the legend. --- src/Charts/GenericLegend.cpp | 16 +++++++++++----- src/Charts/GenericLegend.h | 9 ++++++--- src/Charts/GenericPlot.cpp | 25 ++++++++++++++++++++++--- src/Charts/GenericPlot.h | 1 + src/Charts/GenericSelectTool.cpp | 5 ++++- 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/Charts/GenericLegend.cpp b/src/Charts/GenericLegend.cpp index 2f66c1a7d..d1700ccd5 100644 --- a/src/Charts/GenericLegend.cpp +++ b/src/Charts/GenericLegend.cpp @@ -34,6 +34,7 @@ GenericLegendItem::GenericLegendItem(Context *context, GenericLegend *parent, QS enabled=true; clickable=true; hasvalue=false; + hasstring=false; // set height and width, gets reset when configchanges configChanged(0); @@ -147,11 +148,13 @@ GenericLegendItem::paintEvent(QPaintEvent *) QString string; if (hasvalue) { if (datetime) string=QDateTime::fromMSecsSinceEpoch(value).toString(datetimeformat); - else string=QString("%1").arg(value, 0, 'f', 2); + else { + string=QString("%1").arg(value, 0, 'f', 2); + string = Utils::removeDP(string); + } } else string=" "; - // remove redundat dps (e.g. trailing zeroes) - string = Utils::removeDP(string); + if (hasstring) string=this->string; // set pen to series color for now if (enabled) painter.setPen(GCColor::invertColor(legend->plot()->backgroundColor())); // use invert - usually black or white @@ -289,14 +292,17 @@ GenericLegend::removeAllSeries() } void -GenericLegend::setValue(GPointF value, QString name) +GenericLegend::setValue(GPointF value, QString name, QString label) { GenericLegendItem *call = items.value(name, NULL); if (call) call->setValue(value.y()); // xaxis GenericLegendItem *xaxis = items.value(xname, NULL); - if (xaxis) xaxis->setValue(value.x()); + if (xaxis) { + if (label != "(null)") xaxis->setValue(label); + else xaxis->setValue(value.x()); + } } void diff --git a/src/Charts/GenericLegend.h b/src/Charts/GenericLegend.h index 3a9c09ad1..248ffa209 100644 --- a/src/Charts/GenericLegend.h +++ b/src/Charts/GenericLegend.h @@ -60,8 +60,9 @@ class GenericLegendItem : public QWidget { public slots: void paintEvent(QPaintEvent *event); - void setValue(double p) { if (enabled) { hasvalue=true; value=p; update(); } } // set value to display - void noValue() { if (enabled) { hasvalue=false; update(); } } // no value to display + void setValue(double p) { if (enabled) { hasvalue=true;hasstring=false; value=p; update(); } } // set value to display + void setValue(QString s) { if (enabled) { hasvalue=false;hasstring=true; string=s; update(); } } // set value to display + void noValue() { if (enabled) { hasstring=false;hasvalue=false; update(); } } // no value to display void setClickable(bool x) { clickable=x; } void setDateTime(bool x, QString xf) { datetime=x; datetimeformat=xf; } void configChanged(qint32); // context changed @@ -73,11 +74,13 @@ class GenericLegendItem : public QWidget { GenericLegend *legend; bool hasvalue; + bool hasstring; bool enabled; bool clickable; bool datetime; QString datetimeformat; double value; + QString string; // geometry for painting fast / updated on config changes QRectF blockrect, namerect, valuerect, linerect, hoverrect; @@ -105,7 +108,7 @@ class GenericLegend : public QWidget { public slots: - void setValue(GPointF value, QString name); + void setValue(GPointF value, QString name, QString xcategory="(null)"); void unhover(QString name); void unhoverx(); void setClickable(bool x); diff --git a/src/Charts/GenericPlot.cpp b/src/Charts/GenericPlot.cpp index 8ab076e7c..dc3ea8fcf 100644 --- a/src/Charts/GenericPlot.cpp +++ b/src/Charts/GenericPlot.cpp @@ -325,9 +325,15 @@ GenericPlot::pieHover(QPieSlice *slice, bool state) // handle hover on barset void GenericPlot::barsetHover(bool status, int index, QBarSet *) { + QString category; + if (categories.count() > index) category = categories[index]; + foreach(QBarSet *barset, barsets) { - if (status) legend->setValue(GPointF(0, barset->at(index), -1), barset->label()); - else legend->unhover(barset->label()); + if (status) legend->setValue(GPointF(0, barset->at(index), -1), barset->label(), category); + else { + legend->unhover(barset->label()); + legend->unhoverx(); + } } } @@ -1054,6 +1060,7 @@ GenericPlot::finaliseChart() for(int i=0; icategories.count(); i++) if (axisinfo->categories.at(i) == "") axisinfo->categories[i]="(blank)"; caxis->setCategories(axisinfo->categories); + categories = axisinfo->categories; } } break; @@ -1091,7 +1098,7 @@ GenericPlot::finaliseChart() } } - if (charttype == GC_CHART_SCATTER || charttype == GC_CHART_LINE) { + if (charttype == GC_CHART_SCATTER || charttype == GC_CHART_LINE || charttype == GC_CHART_BAR || charttype == GC_CHART_STACK) { bool havexaxis=false; foreach(QAbstractSeries *series, qchart->series()) { @@ -1135,6 +1142,12 @@ GenericPlot::finaliseChart() foreach(QAbstractAxis *axis, qchart->axes(Qt::Vertical)) barseries->attachAxis(axis); + // add first X axis we find + foreach(QAbstractAxis *axis, qchart->axes(Qt::Horizontal)) { + legend->addX(static_cast(axis)->titleText(), false, ""); + break; + } + // and legend foreach(QBarSet *set, barsets) legend->addSeries(set->label(), set->color()); @@ -1144,6 +1157,12 @@ GenericPlot::finaliseChart() // stacked bar uses stackbarseries, but otherwise very similar if (charttype==GC_CHART_STACK && stackbarseries) { + // add first X axis we find + foreach(QAbstractAxis *axis, qchart->axes(Qt::Horizontal)) { + legend->addX(static_cast(axis)->titleText(), false, ""); + break; + } + // need to attach stackbarseries to the value axes foreach(QAbstractAxis *axis, qchart->axes(Qt::Vertical)) stackbarseries->attachAxis(axis); diff --git a/src/Charts/GenericPlot.h b/src/Charts/GenericPlot.h index f3bfdb32b..3fce6ac3d 100644 --- a/src/Charts/GenericPlot.h +++ b/src/Charts/GenericPlot.h @@ -173,6 +173,7 @@ class GenericPlot : public QWidget { QList barsets; QBarSeries *barseries; QStackedBarSeries *stackbarseries; + QList categories; // axis placement (before user interacts) // alternates as axis added diff --git a/src/Charts/GenericSelectTool.cpp b/src/Charts/GenericSelectTool.cpp index 26617c316..ef638a941 100644 --- a/src/Charts/GenericSelectTool.cpp +++ b/src/Charts/GenericSelectTool.cpp @@ -665,8 +665,11 @@ GenericSelectTool::moved(QPointF pos) } // we need to clear x-axis if we aren't hovering on anything at all + // but bar and stack charts already get status in hover signals + // so don't do this for those chart types. if (hoverv == GPointF()) { - emit unhoverx(); + if (host->charttype != GC_CHART_BAR && host->charttype != GC_CHART_STACK) + emit unhoverx(); } // for mouse moves..