Fixup GenericPlot legend hover for pie and bar charts

.. the legend is mostly static for pie and bar charts
   but should be shown nonetheless.
This commit is contained in:
Mark Liversedge
2020-02-28 18:56:21 +00:00
parent 0ecfa0e67e
commit 40195ab0ce
4 changed files with 81 additions and 19 deletions

View File

@@ -32,6 +32,7 @@ GenericLegendItem::GenericLegendItem(Context *context, QWidget *parent, QString
value=0;
enabled=true;
clickable=true;
hasvalue=false;
// set height and width, gets reset when configchanges
@@ -93,7 +94,7 @@ GenericLegendItem::eventFilter(QObject *obj, QEvent *e)
switch (e->type()) {
case QEvent::MouseButtonRelease: // for now just one event, but may do more later
{
if (underMouse()) {
if (clickable && underMouse()) {
enabled=!enabled;
if (!enabled) hasvalue=false;
emit clicked(name, enabled);
@@ -120,7 +121,7 @@ GenericLegendItem::paintEvent(QPaintEvent *)
painter.drawRect(0,0,geometry().width()-1, geometry().height()-1);
// under mouse show
if (underMouse()) {
if (clickable && underMouse()) {
QColor mask=GCColor::invertColor(GColor(CPLOTBACKGROUND));
mask.setAlphaF(0.1);
painter.setBrush(mask);
@@ -161,16 +162,18 @@ GenericLegend::GenericLegend(Context *context, GenericPlot *plot) : context(cont
layout->addStretch();
xname="";
clickable=true;
}
void
GenericLegend::addSeries(QString name, QAbstractSeries *series)
GenericLegend::addSeries(QString name, QColor color)
{
// if it already exists remove it
if (items.value(name,NULL) != NULL) removeSeries(name);
GenericLegendItem *add = new GenericLegendItem(context, this, name, GenericPlot::seriesColor(series));
GenericLegendItem *add = new GenericLegendItem(context, this, name, color);
add->setClickable(clickable);
layout->insertWidget(0, add);
items.insert(name,add);
@@ -188,6 +191,7 @@ GenericLegend::addX(QString name)
if (items.value(name,NULL) != NULL) removeSeries(name);
GenericLegendItem *add = new GenericLegendItem(context, this, name, GColor(CPLOTMARKER));
add->setClickable(false);
layout->insertWidget(0, add);
items.insert(name,add);
@@ -224,7 +228,7 @@ GenericLegend::removeAllSeries()
}
void
GenericLegend::hover(QPointF value, QString name, QAbstractSeries*)
GenericLegend::setValue(QPointF value, QString name)
{
GenericLegendItem *call = items.value(name, NULL);
if (call) call->setValue(value.y());
@@ -234,6 +238,18 @@ GenericLegend::hover(QPointF value, QString name, QAbstractSeries*)
if (xaxis) xaxis->setValue(value.x());
}
void
GenericLegend::setClickable(bool clickable)
{
this->clickable=clickable;
QMapIterator<QString, GenericLegendItem*> i(items);
while (i.hasNext()) {
i.next();
if (i.key() != xname)
i.value()->setClickable(clickable);
}
}
void
GenericLegend::unhover(QString name)
{

View File

@@ -61,6 +61,7 @@ class GenericLegendItem : public QWidget {
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 setClickable(bool x) { clickable=x; }
void configChanged(qint32); // context changed
private:
@@ -70,6 +71,7 @@ class GenericLegendItem : public QWidget {
bool hasvalue;
bool enabled;
bool clickable;
double value;
// geometry for painting fast / updated on config changes
@@ -84,7 +86,7 @@ class GenericLegend : public QWidget {
public:
GenericLegend(Context *context, GenericPlot *parent);
void addSeries(QString name, QAbstractSeries *series);
void addSeries(QString name, QColor color);
void addX(QString name);
void removeSeries(QString name);
void removeAllSeries();
@@ -93,9 +95,10 @@ class GenericLegend : public QWidget {
void clicked(QString name, bool enabled); // someone clicked on a legend and enabled/disabled it
public slots:
void hover(QPointF value, QString name, QAbstractSeries*series);
void setValue(QPointF value, QString name);
void unhover(QString name);
void unhoverx();
void setClickable(bool x);
private:
// a label has a unique name, not directly tide to
@@ -105,6 +108,7 @@ class GenericLegend : public QWidget {
QHBoxLayout *layout;
QMap<QString,GenericLegendItem*> items;
QString xname;
bool clickable;
};
#endif

View File

@@ -73,7 +73,7 @@ GenericPlot::GenericPlot(QWidget *parent, Context *context) : QWidget(parent), c
connect(context, SIGNAL(configChanged(qint32)), this, SLOT(configChanged(qint32)));
// get notifications when values change
connect(selector, SIGNAL(hover(QPointF,QString,QAbstractSeries*)), legend, SLOT(hover(QPointF,QString,QAbstractSeries*)));
connect(selector, SIGNAL(hover(QPointF,QString,QAbstractSeries*)), legend, SLOT(setValue(QPointF,QString)));
connect(selector, SIGNAL(unhover(QString)), legend, SLOT(unhover(QString)));
connect(selector, SIGNAL(unhoverx()), legend, SLOT(unhoverx()));
connect(legend, SIGNAL(clicked(QString,bool)), this, SLOT(setSeriesVisible(QString,bool)));
@@ -131,8 +131,11 @@ GenericPlot::eventHandler(int, void *, QEvent *e)
case QEvent::GraphicsSceneMouseMove:
spos = static_cast<QGraphicsSceneMouseEvent*>(e)->scenePos();
//case QEvent::MouseMove:
//fprintf(stderr,"POS: %f:%f\n", spos.x(), spos.y());
//fprintf(stderr,"%s: mouse MOVE for obj=%u\n", source ? "widget" : "scene", (void*)obj); fflush(stderr);
//fprintf(stderr,"POS: %f:%f SCENE: %d,%d to %d width %d height AREA: %f,%f %f width %f height\n",
//spos.x(), spos.y(),
//qchart->scene()->views()[0]->geometry().x(), qchart->scene()->views()[0]->geometry().y(), qchart->scene()->views()[0]->geometry().width(), qchart->scene()->views()[0]->geometry().height(),
//qchart->plotArea().x(), qchart->plotArea().y(), qchart->plotArea().width(), qchart->plotArea().height());
//fflush(stderr);
{
// see if selection tool cares about new mouse position
updatescene = selector->moved(spos);
@@ -159,7 +162,7 @@ GenericPlot::eventHandler(int, void *, QEvent *e)
case QEvent::GraphicsSceneHoverMove: {
// debug info
//fprintf(stderr,"%s: HOVER scene item for obj=%u\n", source ? "widget" : "scene", (void*)obj); fflush(stderr);
//fprintf(stderr,"HOVER scene item for obj=%u\n", (void*)obj); fflush(stderr);
}
break;
@@ -229,6 +232,15 @@ GenericPlot::setSeriesVisible(QString name, bool visible)
}
}
// handle hover on barset
void GenericPlot::barsetHover(bool status, int index, QBarSet *)
{
foreach(QBarSet *barset, barsets) {
if (status) legend->setValue(QPointF(0, barset->at(index)), barset->label());
else legend->unhover(barset->label());
}
}
bool
GenericPlot::initialiseChart(QString title, int type, bool animate)
{
@@ -345,6 +357,7 @@ GenericPlot::addCurve(QString name, QVector<double> xseries, QVector<double> yse
// hardware support?
chartview->setRenderHint(QPainter::Antialiasing);
add->setUseOpenGL(opengl); // for scatter or line only apparently
qchart->setDropShadowEnabled(false);
// chart
qchart->addSeries(add);
@@ -395,11 +408,10 @@ GenericPlot::addCurve(QString name, QVector<double> xseries, QVector<double> yse
// hardware support?
chartview->setRenderHint(QPainter::Antialiasing);
add->setUseOpenGL(opengl); // for scatter or line only apparently
qchart->setDropShadowEnabled(false);
// chart
qchart->addSeries(add);
qchart->legend()->setMarkerShape(QLegend::MarkerShapeRectangle);
qchart->setDropShadowEnabled(false);
// add to list of curves
curves.insert(name,add);
@@ -430,6 +442,9 @@ GenericPlot::addCurve(QString name, QVector<double> xseries, QVector<double> yse
yaxis->type = GenericAxisInfo::CONTINUOUS;
xaxis->type = GenericAxisInfo::CATEGORY;
// shadows on bar charts
qchart->setDropShadowEnabled(false);
// add to list of barsets
barsets << add;
}
@@ -461,6 +476,9 @@ GenericPlot::addCurve(QString name, QVector<double> xseries, QVector<double> yse
i++;
}
// shadows on pie
qchart->setDropShadowEnabled(false);
// set the pie chart
qchart->addSeries(add);
@@ -531,8 +549,14 @@ GenericPlot::finaliseChart()
add=caxis;
// add the bar series
if (!barseries) { barseries = new QBarSeries(); qchart->addSeries(barseries); }
else barseries->clear();
if (!barseries) {
barseries = new QBarSeries();
qchart->addSeries(barseries);
// connect hover events
connect(barseries, SIGNAL(hovered(bool,int,QBarSet*)), this, SLOT(barsetHover(bool,int,QBarSet*)));
} else barseries->clear();
// add the new barsets
foreach (QBarSet *bs, barsets)
@@ -605,16 +629,24 @@ GenericPlot::finaliseChart()
}
// add to the legend xxx might make some hidden?
legend->addSeries(series->name(), series);
legend->addSeries(series->name(), GenericPlot::seriesColor(series));
}
legend->show();
}
if (charttype ==GC_CHART_PIE || charttype== GC_CHART_BAR) { //XXX bar chart legend?
// pie, never want a legend
legend->hide();
if (charttype== GC_CHART_PIE) {
foreach(QAbstractSeries *series, qchart->series()) {
if (series->type()== QAbstractSeries::SeriesTypePie) {
foreach (QPieSlice *slice, static_cast<QPieSeries*>(series)->slices()) {
legend->addSeries(slice->label(), slice->color());
legend->setValue(QPointF(0,slice->value()), slice->label());
}
}
}
legend->setClickable(false);
legend->show();
}
// barseries special case
@@ -623,6 +655,13 @@ GenericPlot::finaliseChart()
// need to attach barseries to the value axes
foreach(QAbstractAxis *axis, qchart->axes(Qt::Vertical))
barseries->attachAxis(axis);
// and legend
foreach(QBarSet *set, barsets)
legend->addSeries(set->label(), set->color());
legend->setClickable(false);
legend->show();
}
// install event filters on thes scene objects for Pie and Bar

View File

@@ -128,6 +128,9 @@ class GenericPlot : public QWidget {
// do we want to see this series?
void setSeriesVisible(QString name, bool visible);
// bar hover, process and update legend
void barsetHover(bool status, int index, QBarSet *barset);
void configChanged(qint32);
// set chart settings