aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Fadel <samuelfadel@gmail.com>2016-01-20 00:59:05 +0100
committerSamuel Fadel <samuelfadel@gmail.com>2016-01-20 00:59:05 +0100
commitc99756c9a4a144530da0b20bb5fd75e64014b83a (patch)
tree38c238ccdcccd5fa0b2bae4b71dc60dda262a621
parenta319a857a633ab2fbcdbae5204eb5cfcdcc1b413 (diff)
BarChart: update() when values change and added hover hints.
-rw-r--r--barchart.cpp74
-rw-r--r--barchart.h10
2 files changed, 72 insertions, 12 deletions
diff --git a/barchart.cpp b/barchart.cpp
index c2f7255..7938c7a 100644
--- a/barchart.cpp
+++ b/barchart.cpp
@@ -2,23 +2,28 @@
#include <algorithm>
+#include <QSGGeometryNode>
+#include <QSGFlatColorMaterial>
+
#include "continuouscolorscale.h"
#include "geometry.h"
static const QColor OUTLINE_COLOR(0, 0, 0);
+static const QColor HINTS_COLOR(0, 0, 0);
static const QColor BAR_COLOR(128, 128, 128);
static const float DEFAULT_OPACITY = 0.8f;
BarChart::BarChart(QQuickItem *parent)
: QQuickItem(parent)
, m_shouldUpdateBars(false)
+ , m_hoverPos(-1.0f)
, m_colorScale(ContinuousColorScale::builtin(ContinuousColorScale::HEATED_OBJECTS))
- , m_scale(0, 1, 0, 1)
+ , m_scale(0.0f, 1.0f, 0.0f, 1.0f)
{
setClip(true);
setFlag(QQuickItem::ItemHasContents);
//setAcceptedMouseButtons(Qt::LeftButton);
- // setAcceptHoverEvents(true);
+ setAcceptHoverEvents(true);
}
BarChart::~BarChart()
@@ -44,6 +49,7 @@ void BarChart::setValues(const arma::vec &values)
emit valuesChanged(values);
m_shouldUpdateBars = true;
+ update();
}
void BarChart::setColorScale(const ColorScale &scale)
@@ -60,7 +66,26 @@ void BarChart::setColorScale(const ColorScale &scale)
QSGNode *BarChart::newSceneGraph() const
{
+ // NOTE: scene graph structure is as follows:
+ // root [ barsNode [ ... ] hoverHintsNode ]
QSGTransformNode *root = new QSGTransformNode;
+
+ // The node that has all bars as children
+ root->appendChildNode(new QSGNode);
+
+ // The node for drawing the hover hints
+ QSGGeometryNode *hintsGeomNode = new QSGGeometryNode;
+ QSGGeometry *hintsGeom = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2);
+ hintsGeom->setDrawingMode(GL_LINES);
+ hintsGeom->setVertexDataPattern(QSGGeometry::DynamicPattern);
+ hintsGeom->setLineWidth(1.0f);
+ QSGFlatColorMaterial *hintsMaterial = new QSGFlatColorMaterial;
+ hintsMaterial->setColor(HINTS_COLOR);
+ hintsGeomNode->setGeometry(hintsGeom);
+ hintsGeomNode->setMaterial(hintsMaterial);
+ hintsGeomNode->setFlags(QSGNode::OwnsGeometry | QSGNode::OwnsMaterial);
+ root->appendChildNode(hintsGeomNode);
+
return root;
}
@@ -149,36 +174,65 @@ void BarChart::updateBars(QSGNode *root)
}
}
+void BarChart::updateHoverHints(QSGNode *node)
+{
+ QSGGeometryNode *hintsGeomNode = static_cast<QSGGeometryNode *>(node);
+ QSGGeometry *hintsGeom = hintsGeomNode->geometry();
+
+ QSGGeometry::Point2D *vertexData = hintsGeom->vertexDataAsPoint2D();
+ vertexData[0].set(m_hoverPos, 0.0f);
+ vertexData[1].set(m_hoverPos, 1.0f);
+
+ hintsGeomNode->markDirty(QSGNode::DirtyGeometry);
+}
+
QSGNode *BarChart::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
QSGNode *root = oldNode ? oldNode : newSceneGraph();
updateViewport(root);
+ QSGNode *node = root->firstChild();
if (m_shouldUpdateBars) {
int numValues = (int) m_values.n_elem;
// First, make sure we have the same number of values & bars
- while (numValues > root->childCount()) {
+ while (numValues > node->childCount()) {
QSGNode *barNode = newBarNode();
- root->appendChildNode(barNode);
+ node->prependChildNode(barNode);
}
while (numValues < root->childCount()) {
// NOTE: as stated in docs, QSGNode's children are stored in a
// linked list. Hence, this operation should be as fast as expected
- root->removeChildNode(root->firstChild());
+ node->removeChildNode(node->firstChild());
}
// Then, update the bars to reflect the values
- updateBars(root);
+ updateBars(node);
m_shouldUpdateBars = false;
}
+ node = node->nextSibling();
+
+ updateHoverHints(node);
return root;
}
-// TODO
-//void BarChart::hoverMoveEvent(QHoverEvent *event)
-//{
-//}
+void BarChart::hoverEnterEvent(QHoverEvent *event)
+{
+ m_hoverPos = float(event->pos().x()) / width();
+ update();
+}
+
+void BarChart::hoverMoveEvent(QHoverEvent *event)
+{
+ m_hoverPos = float(event->pos().x()) / width();
+ update();
+}
+
+void BarChart::hoverLeaveEvent(QHoverEvent *event)
+{
+ m_hoverPos = -1.0f;
+ update();
+}
void BarChart::mousePressEvent(QMouseEvent *event)
{
diff --git a/barchart.h b/barchart.h
index 662499d..91cce78 100644
--- a/barchart.h
+++ b/barchart.h
@@ -28,7 +28,11 @@ public slots:
protected:
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
- // void hoverMoveEvent(QHoverEvent *event);
+
+ void hoverEnterEvent(QHoverEvent *event);
+ void hoverMoveEvent(QHoverEvent *event);
+ void hoverLeaveEvent(QHoverEvent *event);
+
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
@@ -40,8 +44,10 @@ private:
void updateViewport(QSGNode *root) const;
void updateBarNodeGeom(QSGNode *barNode, float x, float width, float height);
void updateBarNodeColor(QSGNode *barNode, const QColor &color);
- void updateBars(QSGNode *root);
+ void updateBars(QSGNode *node);
+ void updateHoverHints(QSGNode *node);
bool m_shouldUpdateBars;
+ float m_hoverPos;
arma::vec m_values;
ColorScale m_colorScale;