aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Fadel <samuelfadel@gmail.com>2016-01-18 15:46:05 +0100
committerSamuel Fadel <samuelfadel@gmail.com>2016-01-18 15:46:05 +0100
commit8cc4c24249600392871cc802f3ac4dd27368d335 (patch)
tree9bfde6414953828b379ee3728f5d92bbb772558d
parentd0ba4bbd9eb7b550cf71bb421e2a6f8b83018b48 (diff)
Added observer to update values displayed based on some metric.
* Modified main() function to connect signals/slots to display calculated values * Color scales are no longer shared; they are also normalized to each component's own data * Stub mouse handling in BarChart (changes cursor shape)
-rw-r--r--barchart.cpp21
-rw-r--r--barchart.h7
-rw-r--r--distortionobserver.cpp33
-rw-r--r--distortionobserver.h29
-rw-r--r--main.cpp40
-rw-r--r--pm.pro12
-rw-r--r--projectionobserver.cpp52
-rw-r--r--projectionobserver.h30
-rw-r--r--scatterplot.cpp18
-rw-r--r--scatterplot.h4
10 files changed, 138 insertions, 108 deletions
diff --git a/barchart.cpp b/barchart.cpp
index 941d9e8..f21f874 100644
--- a/barchart.cpp
+++ b/barchart.cpp
@@ -2,6 +2,7 @@
#include <algorithm>
+#include "continuouscolorscale.h"
#include "geometry.h"
static const QColor OUTLINE_COLOR(0, 0, 0);
@@ -11,12 +12,12 @@ static const float DEFAULT_OPACITY = 0.8f;
BarChart::BarChart(QQuickItem *parent)
: QQuickItem(parent)
, m_shouldUpdateBars(false)
- , m_colorScale(0)
+ , m_colorScale(ContinuousColorScale::builtin(ContinuousColorScale::HEATED_OBJECTS))
, m_scale(0, 1, 0, 1)
{
setClip(true);
setFlag(QQuickItem::ItemHasContents);
- // setAcceptedMouseButtons(Qt::LeftButton);
+ //setAcceptedMouseButtons(Qt::LeftButton);
// setAcceptHoverEvents(true);
}
@@ -31,6 +32,7 @@ void BarChart::setValues(const arma::vec &values)
m_originalIndices.resize(m_values.n_elem);
if (m_values.n_elem > 0) {
m_scale.setDomain(m_values.min(), m_values.max());
+ m_colorScale.setExtents(m_values.min(), m_values.max());
for (int i = 0; i < m_originalIndices.size(); i++) {
m_originalIndices[i] = i;
@@ -44,9 +46,12 @@ void BarChart::setValues(const arma::vec &values)
m_shouldUpdateBars = true;
}
-void BarChart::setColorScale(const ColorScale *scale)
+void BarChart::setColorScale(const ColorScale &scale)
{
m_colorScale = scale;
+ if (m_values.n_elem > 0) {
+ m_colorScale.setExtents(m_values.min(), m_values.max());
+ }
emit colorScaleChanged(m_colorScale);
m_shouldUpdateBars = true;
@@ -136,7 +141,7 @@ void BarChart::updateBars(QSGNode *root)
float x = 0;
for (auto it = m_originalIndices.cbegin(); it != m_originalIndices.cend(); it++) {
updateBarNodeGeom(node, x, barWidth, m_scale(m_values[*it]));
- updateBarNodeColor(node, m_colorScale->color(m_values[*it]));
+ updateBarNodeColor(node, m_colorScale.color(m_values[*it]));
x += barWidth;
node = node->nextSibling();
}
@@ -175,5 +180,11 @@ void BarChart::hoverMoveEvent(QHoverEvent *event)
void BarChart::mousePressEvent(QMouseEvent *event)
{
- // TODO
+ QCursor dragCursor(Qt::SizeHorCursor);
+ setCursor(dragCursor);
+}
+
+void BarChart::mouseReleaseEvent(QMouseEvent *event)
+{
+ unsetCursor();
}
diff --git a/barchart.h b/barchart.h
index e0edc0a..176f3b2 100644
--- a/barchart.h
+++ b/barchart.h
@@ -20,16 +20,17 @@ public:
signals:
void valuesChanged(const arma::vec &values) const;
- void colorScaleChanged(const ColorScale *scale) const;
+ void colorScaleChanged(const ColorScale &scale) const;
public slots:
void setValues(const arma::vec &values);
- void setColorScale(const ColorScale *scale);
+ void setColorScale(const ColorScale &scale);
protected:
QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
void hoverMoveEvent(QHoverEvent *event);
void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
private:
QSGNode *newSceneGraph() const;
@@ -42,7 +43,7 @@ private:
bool m_shouldUpdateBars;
arma::vec m_values;
- const ColorScale *m_colorScale;
+ ColorScale m_colorScale;
std::vector<int> m_originalIndices;
LinearScale<float> m_scale;
};
diff --git a/distortionobserver.cpp b/distortionobserver.cpp
deleted file mode 100644
index 29d7e6f..0000000
--- a/distortionobserver.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "distortionobserver.h"
-
-#include "mp.h"
-
-DistortionObserver::DistortionObserver(const arma::mat &X,
- const arma::uvec &sampleIndices)
- : m_X(X)
- , m_sampleIndices(sampleIndices)
- , m_distortionMeasure(0)
-{
- m_distX = mp::dist(m_X);
-}
-
-void DistortionObserver::setMeasure(DistortionMeasure *measure)
-{
- m_distortionMeasure = measure;
-}
-
-void DistortionObserver::setMap(const arma::mat &Y)
-{
- if (!m_distortionMeasure) {
- return;
- }
-
- arma::vec measures = m_distortionMeasure->measure(m_distX, mp::dist(Y));
-
- if (m_Y.n_elem != 0) {
- emit mapChanged(measures - m_measures);
- } else {
- m_Y = Y;
- m_measures = measures;
- }
-}
diff --git a/distortionobserver.h b/distortionobserver.h
deleted file mode 100644
index 101c53d..0000000
--- a/distortionobserver.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef DISTORTIONOBSERVER_H
-#define DISTORTIONOBSERVER_H
-
-#include <QObject>
-#include <armadillo>
-
-#include "distortionmeasure.h"
-
-class DistortionObserver : public QObject
-{
- Q_OBJECT
-public:
- DistortionObserver(const arma::mat &X, const arma::uvec &sampleIndices);
- void setMeasure(DistortionMeasure *measure);
-
-signals:
- void mapChanged(const arma::vec &distortion);
-
-public slots:
- void setMap(const arma::mat &Y);
-
-private:
- arma::mat m_X, m_Y, m_distX;
- arma::uvec m_sampleIndices;
- DistortionMeasure *m_distortionMeasure;
- arma::vec m_measures;
-};
-
-#endif // DISTORTIONOBSERVER_H
diff --git a/main.cpp b/main.cpp
index d2eb5f6..c58d216 100644
--- a/main.cpp
+++ b/main.cpp
@@ -17,7 +17,7 @@
#include "barchart.h"
#include "colormap.h"
#include "interactionhandler.h"
-#include "selectionhandler.h"
+#include "projectionobserver.h"
#include "skelft.h"
static QObject *mainProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
@@ -130,14 +130,12 @@ int main(int argc, char **argv)
//};
//colorScale.setExtents(labels.min(), labels.max());
- ContinuousColorScale colorScale = ContinuousColorScale::builtin(ContinuousColorScale::RAINBOW);
- colorScale.setExtents(labels.min(), labels.max());
+ ContinuousColorScale colorScale = ContinuousColorScale::builtin(ContinuousColorScale::HEATED_OBJECTS);
Scatterplot *cpPlot = engine.rootObjects()[0]->findChild<Scatterplot *>("cpPlot");
+ Scatterplot *rpPlot = engine.rootObjects()[0]->findChild<Scatterplot *>("rpPlot");
cpPlot->setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton);
// cpPlot->setColorData(arma::zeros<arma::vec>(cpSize));
- cpPlot->setColorScale(&colorScale);
- Scatterplot *plot = engine.rootObjects()[0]->findChild<Scatterplot *>("plot");
VoronoiSplat *splat = engine.rootObjects()[0]->findChild<VoronoiSplat *>("splat");
skelft2DInitialization(splat->width());
Colormap *colormap = engine.rootObjects()[0]->findChild<Colormap *>("colormap");
@@ -151,17 +149,17 @@ int main(int argc, char **argv)
// Update projection as the cp are modified
InteractionHandler interactionHandler(X, cpIndices);
m->setInteractionHandler(&interactionHandler);
+ m->setTechnique(InteractionHandler::TECHNIQUE_LAMP);
QObject::connect(cpPlot, SIGNAL(xyChanged(const arma::mat &)),
&interactionHandler, SLOT(setCP(const arma::mat &)));
QObject::connect(cpPlot, SIGNAL(xyInteractivelyChanged(const arma::mat &)),
&interactionHandler, SLOT(setCP(const arma::mat &)));
QObject::connect(&interactionHandler, SIGNAL(cpChanged(const arma::mat &)),
- plot, SLOT(setXY(const arma::mat &)));
+ rpPlot, SLOT(setXY(const arma::mat &)));
QObject::connect(&interactionHandler, SIGNAL(cpChanged(const arma::mat &)),
splat, SLOT(setSites(const arma::mat &)));
- m->setTechnique(InteractionHandler::TECHNIQUE_LAMP);
- // Linking between selections in cp plot and full dataset plot
+ // Linking between selections in cp plot and rp plot
//SelectionHandler selectionHandler(cpIndices);
//QObject::connect(cpPlot, SIGNAL(selectionChanged(const QSet<int> &)),
// &selectionHandler, SLOT(setSelection(const QSet<int> &)));
@@ -175,30 +173,34 @@ int main(int argc, char **argv)
//QObject::connect(history, SIGNAL(currentItemChanged(const arma::mat &)),
// cpPlot, SLOT(setXY(const arma::mat &)));
- QObject::connect(plot, SIGNAL(scaleChanged(const LinearScale<float> &, const LinearScale<float> &)),
+ QObject::connect(rpPlot, SIGNAL(scaleChanged(const LinearScale<float> &, const LinearScale<float> &)),
cpPlot, SLOT(setScale(const LinearScale<float> &, const LinearScale<float> &)));
BarChart *barChart = engine.rootObjects()[0]->findChild<BarChart *>("barChart");
- barChart->setColorScale(&colorScale);
- barChart->setValues(labels);
+ barChart->setAcceptedMouseButtons(Qt::LeftButton);
+ barChart->setColorScale(colorScale);
+
+ ProjectionObserver projectionObserver(X, cpIndices);
+ QObject::connect(&interactionHandler, SIGNAL(cpChanged(const arma::mat &)),
+ &projectionObserver, SLOT(setMap(const arma::mat &)));
+ QObject::connect(&projectionObserver, SIGNAL(mapChanged(const arma::vec &)),
+ rpPlot, SLOT(setColorData(const arma::vec &)));
+ QObject::connect(&projectionObserver, SIGNAL(mapChanged(const arma::vec &)),
+ splat, SLOT(setValues(const arma::vec &)));
+ QObject::connect(&projectionObserver, SIGNAL(mapChanged(const arma::vec &)),
+ barChart, SLOT(setValues(const arma::vec &)));
//history->addHistoryItem(Ys);
colormap->setColorScale(colorScale);
- plot->setColorScale(&colorScale);
- plot->setColorData(labels, false);
+ rpPlot->setColorScale(colorScale);
splat->setColorScale(colorScale);
- splat->setValues(labels);
+ cpPlot->setColorScale(colorScale);
cpPlot->setAutoScale(false);
cpPlot->setColorData(labels(cpIndices), false);
cpPlot->setXY(Ys, false);
cpPlot->update();
- arma::vec plotOpacities(X.n_rows);
- plotOpacities.fill(0.0f);
- plotOpacities(cpIndices).fill(0.0f);
- plot->setOpacityData(plotOpacities);
-
auto ret = app.exec();
skelft2DDeinitialization();
diff --git a/pm.pro b/pm.pro
index 53ac0a5..3f3332b 100644
--- a/pm.pro
+++ b/pm.pro
@@ -15,11 +15,7 @@ HEADERS += main.h \
historygraph.h \
barchart.h \
interactionhandler.h \
- selectionhandler.h \
- effectivenessobserver.h \
- distortionobserver.h \
- distortionmeasure.h \
- npdistortion.h \
+ projectionobserver.h \
skelft.h \
skelftkernel.h \
mp.h
@@ -33,16 +29,12 @@ SOURCES += main.cpp \
historygraph.cpp \
barchart.cpp \
interactionhandler.cpp \
- selectionhandler.cpp \
- effectivenessobserver.cpp \
- distortionobserver.cpp \
- npdistortion.cpp \
+ projectionobserver.cpp \
skelft_core.cpp \
lamp.cpp \
plmp.cpp \
knn.cpp \
forceScheme.cpp \
- tsne.cpp \
measures.cpp \
dist.cpp
diff --git a/projectionobserver.cpp b/projectionobserver.cpp
new file mode 100644
index 0000000..33869a8
--- /dev/null
+++ b/projectionobserver.cpp
@@ -0,0 +1,52 @@
+#include "projectionobserver.h"
+
+#include <cmath>
+
+#include "mp.h"
+
+static void aggregatedError(const arma::mat &distX, const arma::mat &distY, arma::vec &v)
+{
+ double maxX = distX.max();
+ double maxY = distY.max();
+
+ for (arma::uword i = 0; i < v.n_elem; i++) {
+ v[i] = 0;
+ for (arma::uword j = 0; j < v.n_elem; j++) {
+ if (i == j) {
+ continue;
+ }
+
+ v[i] += fabs(distY(i, j) / maxY - distX(i, j) / maxX);
+ }
+ }
+}
+
+ProjectionObserver::ProjectionObserver(const arma::mat &X,
+ const arma::uvec &cpIndices)
+ : m_X(X)
+ , m_cpIndices(cpIndices)
+{
+ m_distX = mp::dist(m_X);
+ m_values.set_size(m_X.n_rows);
+}
+
+void ProjectionObserver::setMap(const arma::mat &Y)
+{
+ // update previous map
+ if (m_prevY.n_elem == 0 && m_Y.n_elem > 0) {
+ m_prevY = m_Y;
+ m_distPrevY = m_distY;
+ }
+
+ m_Y = Y;
+ m_distY = mp::dist(Y);
+
+ // method called for the first time; set original Y
+ if (m_origY.n_elem == 0) {
+ m_origY = m_Y;
+ m_distOrigY = m_distY;
+ }
+
+ aggregatedError(m_distX, m_distY, m_values);
+ emit mapChanged(m_values);
+}
diff --git a/projectionobserver.h b/projectionobserver.h
new file mode 100644
index 0000000..5ac6988
--- /dev/null
+++ b/projectionobserver.h
@@ -0,0 +1,30 @@
+#ifndef PROJECTIONOBSERVER_H
+#define PROJECTIONOBSERVER_H
+
+#include <QObject>
+#include <armadillo>
+
+#include "distortionmeasure.h"
+
+class ProjectionObserver : public QObject
+{
+ Q_OBJECT
+public:
+ ProjectionObserver(const arma::mat &X, const arma::uvec &cpIndices);
+
+signals:
+ void mapChanged(const arma::vec &values) const;
+
+public slots:
+ void setMap(const arma::mat &Y);
+
+private:
+ arma::mat m_X, m_Y, m_origY, m_prevY;
+ arma::mat m_distX, m_distY, m_distOrigY, m_distPrevY;
+ arma::uvec m_cpIndices;
+
+ // TODO: one per implemented measure
+ arma::vec m_values;
+};
+
+#endif // PROJECTIONOBSERVER_H
diff --git a/scatterplot.cpp b/scatterplot.cpp
index 0433af4..366583b 100644
--- a/scatterplot.cpp
+++ b/scatterplot.cpp
@@ -1,8 +1,13 @@
#include "scatterplot.h"
-#include "geometry.h"
#include <cmath>
+#include <QSGGeometryNode>
+#include <QSGSimpleRectNode>
+
+#include "continuouscolorscale.h"
+#include "geometry.h"
+
static const qreal GLYPH_OPACITY = 1.0;
static const qreal GLYPH_OPACITY_SELECTED = 1.0;
@@ -16,6 +21,7 @@ static const float GLYPH_OUTLINE_WIDTH = 2.0f;
Scatterplot::Scatterplot(QQuickItem *parent)
: QQuickItem(parent)
, m_glyphSize(DEFAULT_GLYPH_SIZE)
+ , m_colorScale(ContinuousColorScale::builtin(ContinuousColorScale::HEATED_OBJECTS))
, m_autoScale(true)
, m_sx(0, 1, 0, 1)
, m_sy(0, 1, 0, 1)
@@ -27,14 +33,11 @@ Scatterplot::Scatterplot(QQuickItem *parent)
setFlag(QQuickItem::ItemHasContents);
}
-void Scatterplot::setColorScale(const ColorScale *colorScale)
+void Scatterplot::setColorScale(const ColorScale &colorScale)
{
- if (!colorScale) {
- return;
- }
-
m_colorScale = colorScale;
if (m_colorData.n_elem > 0) {
+ m_colorScale.setExtents(m_colorData.min(), m_colorData.max());
m_shouldUpdateMaterials = true;
}
}
@@ -96,6 +99,7 @@ void Scatterplot::setColorData(const arma::vec &colorData, bool updateView)
m_colorData = colorData;
emit colorDataChanged(m_colorData);
+ m_colorScale.setExtents(m_colorData.min(), m_colorData.max());
m_shouldUpdateMaterials = true;
if (updateView) {
update();
@@ -320,7 +324,7 @@ void Scatterplot::updateGlyphs(QSGNode *glyphsNode)
glyphOutlineNode->markDirty(QSGNode::DirtyMaterial);
material = static_cast<QSGFlatColorMaterial *>(glyphNode->material());
- material->setColor(m_colorScale->color(m_colorData[i]));
+ material->setColor(m_colorScale.color(m_colorData[i]));
glyphNode->markDirty(QSGNode::DirtyMaterial);
}
diff --git a/scatterplot.h b/scatterplot.h
index 3c2d50b..d17341e 100644
--- a/scatterplot.h
+++ b/scatterplot.h
@@ -17,7 +17,7 @@ public:
Scatterplot(QQuickItem *parent = 0);
arma::mat XY() const;
- void setColorScale(const ColorScale *colorScale);
+ void setColorScale(const ColorScale &colorScale);
void setXY(const arma::mat &xy, bool updateView);
void setColorData(const arma::vec &colorData, bool updateView);
void setOpacityData(const arma::vec &opacityData, bool updateView);
@@ -67,7 +67,7 @@ private:
// Visuals
float m_glyphSize;
- const ColorScale *m_colorScale;
+ ColorScale m_colorScale;
void autoScale();
bool m_autoScale;