aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Fadel <samuelfadel@gmail.com>2015-09-29 16:01:00 -0300
committerSamuel Fadel <samuelfadel@gmail.com>2015-09-29 16:01:00 -0300
commit75c5affd4d7919a969ab65a4a28b6306686e5f9c (patch)
treea2f7da22e641dfaba352da42e066e8e659cf72f8
parent30f327b2fd25104916bffe6fe76823f0dbe35a72 (diff)
HistoryGraph now notifies when the active item changes. Scatterplot now differentiates between interactive and programatic changes in x/y data.
-rw-r--r--historygraph.cpp61
-rw-r--r--historygraph.h8
-rw-r--r--main.cpp5
-rw-r--r--scatterplot.cpp2
-rw-r--r--scatterplot.h1
5 files changed, 71 insertions, 6 deletions
diff --git a/historygraph.cpp b/historygraph.cpp
index 997d079..0aeec20 100644
--- a/historygraph.cpp
+++ b/historygraph.cpp
@@ -10,9 +10,11 @@
static const float ASPECT = 4.f / 3.f;
static const float MARGIN = 0.1f;
-static const float GLYPH_SIZE = 4.0f;
static const float PADDING = 0.05f;
+static const float GLYPH_SIZE = 4.0f;
+static const float GLYPH_OPACITY = 0.6f;
+
class HistoryGraph::HistoryItemNode
{
public:
@@ -21,9 +23,14 @@ public:
void append(HistoryItemNode *node);
const QList<HistoryItemNode *> &children() const { return m_next; }
+
const arma::mat &item() const;
int depth() const { return m_depth; }
int breadth() const { return m_breadth; }
+ const QRectF &rect() const { return m_rect; }
+
+ void setRect(const QRectF &rect) { m_rect = rect; }
+
void updateDepth();
void updateBreadth();
@@ -34,6 +41,7 @@ private:
HistoryItemNode *m_prev;
QList<HistoryItemNode *> m_next;
int m_depth, m_breadth;
+ QRectF m_rect;
};
HistoryGraph::HistoryItemNode::HistoryItemNode(const arma::mat &item)
@@ -122,6 +130,7 @@ HistoryGraph::HistoryGraph(QQuickItem *parent)
{
setClip(true);
setFlag(QQuickItem::ItemHasContents);
+ setAcceptedMouseButtons(Qt::LeftButton);
}
HistoryGraph::~HistoryGraph()
@@ -169,7 +178,7 @@ void HistoryGraph::addScatterplot(QSGNode *node, const HistoryGraph::HistoryItem
// Place the glyph geometry node under an opacity node
QSGOpacityNode *glyphOpacityNode = new QSGOpacityNode;
- //glyphOpacityNode->appendChildNode(glyphOutlineNode);
+ glyphOpacityNode->setOpacity(GLYPH_OPACITY);
glyphOpacityNode->appendChildNode(glyphNode);
node->appendChildNode(glyphOpacityNode);
}
@@ -197,6 +206,7 @@ QSGNode *HistoryGraph::createNodeTree()
QSGOpacityNode *opacityNode = new QSGOpacityNode;
opacityNode->setOpacity(histNode == m_currentNode ? 1.0f : 0.4f);
+ histNode->setRect(QRectF(x, margin, w, h));
QSGGeometryNode *histItemGeomNode = new QSGGeometryNode;
QSGGeometry *histItemGeom = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
updateRectGeometry(histItemGeom, x, margin, w, h);
@@ -266,3 +276,50 @@ QSGNode *HistoryGraph::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
return root;
}
+
+HistoryGraph::HistoryItemNode *HistoryGraph::nodeAt(const QPointF &pos) const
+{
+ return nodeAt(pos, m_firstNode);
+}
+
+HistoryGraph::HistoryItemNode *HistoryGraph::nodeAt(const QPointF &pos, HistoryGraph::HistoryItemNode *node) const
+{
+ if (!node) {
+ return 0;
+ }
+
+ const QRectF &rect = node->rect();
+
+ if (pos.x() < rect.x()) {
+ return 0;
+ }
+
+ if (rect.contains(pos)) {
+ return node;
+ }
+
+ QList<HistoryGraph::HistoryItemNode *> children = node->children();
+ for (auto it = children.begin(); it != children.end(); it++) {
+ HistoryGraph::HistoryItemNode *tmp = nodeAt(pos, *it);
+ if (tmp) {
+ return tmp;
+ }
+ }
+
+ return 0;
+}
+
+void HistoryGraph::mousePressEvent(QMouseEvent *event)
+{
+ HistoryGraph::HistoryItemNode *node = nodeAt(event->localPos());
+ if (!node || node == m_currentNode) {
+ event->ignore();
+ return;
+ }
+
+ m_currentNode = node;
+ m_needsUpdate = true;
+ update();
+
+ emit currentItemChanged(m_currentNode->item());
+}
diff --git a/historygraph.h b/historygraph.h
index 564845c..60cce94 100644
--- a/historygraph.h
+++ b/historygraph.h
@@ -11,20 +11,26 @@ public:
HistoryGraph(QQuickItem *parent = 0);
~HistoryGraph();
+signals:
+ void currentItemChanged(const arma::mat &item);
+
public slots:
void addHistoryItem(const arma::mat &item);
protected:
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
+ void mousePressEvent(QMouseEvent *event);
private:
class HistoryItemNode;
+ HistoryItemNode *nodeAt(const QPointF &pos) const;
+ HistoryItemNode *nodeAt(const QPointF &pos, HistoryItemNode *node) const;
+
QSGNode *createNodeTree();
void updateNodeTree(QSGNode *root);
void addScatterplot(QSGNode *node, const HistoryItemNode *historyItemNode, float x, float y, float w, float h);
-
HistoryItemNode *m_firstNode, *m_currentNode;
bool m_needsUpdate;
};
diff --git a/main.cpp b/main.cpp
index e8a826e..7027be8 100644
--- a/main.cpp
+++ b/main.cpp
@@ -72,8 +72,10 @@ int main(int argc, char **argv)
&interactionHandler, SLOT(setSubsample(const arma::mat &)));
QObject::connect(&interactionHandler, SIGNAL(subsampleChanged(const arma::mat &)),
plot, SLOT(setXY(const arma::mat &)));
- QObject::connect(subsamplePlot, SIGNAL(xyChanged(const arma::mat &)),
+ QObject::connect(subsamplePlot, SIGNAL(xyInteractivelyChanged(const arma::mat &)),
history, SLOT(addHistoryItem(const arma::mat &)));
+ QObject::connect(history, SIGNAL(currentItemChanged(const arma::mat &)),
+ subsamplePlot, SLOT(setXY(const arma::mat &)));
SelectionHandler selectionHandler(sampleIndices);
QObject::connect(subsamplePlot, SIGNAL(selectionChanged(const QSet<int> &)),
@@ -107,7 +109,6 @@ int main(int argc, char **argv)
plot->setColorScale(&colorScale);
plot->setColorData(labels);
- //interactionHandler.setSubsample(Ys);
subsamplePlot->setXY(Ys);
subsamplePlot->setColorData(labels(sampleIndices));
diff --git a/scatterplot.cpp b/scatterplot.cpp
index 81a55b9..e22eafd 100644
--- a/scatterplot.cpp
+++ b/scatterplot.cpp
@@ -359,5 +359,5 @@ void Scatterplot::applyManipulation()
m_xy.row(*it) = row;
}
- emit xyChanged(m_xy);
+ emit xyInteractivelyChanged(m_xy);
}
diff --git a/scatterplot.h b/scatterplot.h
index 43bfc57..2dc031a 100644
--- a/scatterplot.h
+++ b/scatterplot.h
@@ -20,6 +20,7 @@ public:
signals:
void xyChanged(const arma::mat &XY) const;
+ void xyInteractivelyChanged(const arma::mat &XY) const;
void colorDataChanged(const arma::vec &colorData) const;
void selectionChanged(const QSet<int> &selection) const;