aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Fadel <samuelfadel@gmail.com>2015-09-01 20:45:02 -0300
committerSamuel Fadel <samuelfadel@gmail.com>2015-09-01 20:45:02 -0300
commita1956a4ff879eb2d34c7a0ca448f48ee6e64ce99 (patch)
treeb958291afa29268517633a8490920ae38dfcf2d8
parentf405ac30db93ed9f2adb739c3c09b2ce9369fee6 (diff)
Improvements related to visual representation of distortions.
- New continuous color scale class; - Improvements in signal handler for calculating distortions; - Implementation of the NP(k) measure.
-rw-r--r--colorscale.h6
-rw-r--r--continuouscolorscale.cpp285
-rw-r--r--continuouscolorscale.h14
-rw-r--r--distortionmeasure.h12
-rw-r--r--distortionobserver.cpp10
-rw-r--r--distortionobserver.h8
-rw-r--r--main.cpp19
-rw-r--r--main_view.qml57
-rw-r--r--measures.cpp56
-rw-r--r--mp.h8
-rw-r--r--npdistortion.cpp7
-rw-r--r--npdistortion.h10
-rw-r--r--pm.pro3
-rw-r--r--scatterplot.cpp20
-rw-r--r--scatterplot.h4
15 files changed, 475 insertions, 44 deletions
diff --git a/colorscale.h b/colorscale.h
index 6e1212d..6e65012 100644
--- a/colorscale.h
+++ b/colorscale.h
@@ -11,12 +11,12 @@ public:
ColorScale(const QColor &firstColor, const QColor &lastColor);
ColorScale(std::initializer_list<QColor> colors);
ColorScale(const QList<QColor> &colors);
- ~ColorScale();
+ virtual ~ColorScale();
+ virtual QColor color(qreal t) const;
void setExtents(qreal min, qreal max);
- QColor color(qreal t) const;
-private:
+protected:
qreal m_min, m_max;
QList<QColor> m_colors;
};
diff --git a/continuouscolorscale.cpp b/continuouscolorscale.cpp
new file mode 100644
index 0000000..c12db80
--- /dev/null
+++ b/continuouscolorscale.cpp
@@ -0,0 +1,285 @@
+#include "continuouscolorscale.h"
+
+#include <cmath>
+
+ContinuousColorScale::ContinuousColorScale()
+ : ColorScale{
+ QColor( 0, 0, 0),
+ QColor( 35, 0, 0),
+ QColor( 52, 0, 0),
+ QColor( 60, 0, 0),
+ QColor( 63, 1, 0),
+ QColor( 64, 2, 0),
+ QColor( 68, 5, 0),
+ QColor( 69, 6, 0),
+ QColor( 72, 8, 0),
+ QColor( 74, 10, 0),
+ QColor( 77, 12, 0),
+ QColor( 78, 14, 0),
+ QColor( 81, 16, 0),
+ QColor( 83, 17, 0),
+ QColor( 85, 19, 0),
+ QColor( 86, 20, 0),
+ QColor( 89, 22, 0),
+ QColor( 91, 24, 0),
+ QColor( 92, 25, 0),
+ QColor( 94, 26, 0),
+ QColor( 95, 28, 0),
+ QColor( 98, 30, 0),
+ QColor(100, 31, 0),
+ QColor(102, 33, 0),
+ QColor(103, 34, 0),
+ QColor(105, 35, 0),
+ QColor(106, 36, 0),
+ QColor(108, 38, 0),
+ QColor(109, 39, 0),
+ QColor(111, 40, 0),
+ QColor(112, 42, 0),
+ QColor(114, 43, 0),
+ QColor(115, 44, 0),
+ QColor(117, 45, 0),
+ QColor(119, 47, 0),
+ QColor(119, 47, 0),
+ QColor(120, 48, 0),
+ QColor(122, 49, 0),
+ QColor(123, 51, 0),
+ QColor(125, 52, 0),
+ QColor(125, 52, 0),
+ QColor(126, 53, 0),
+ QColor(128, 54, 0),
+ QColor(129, 56, 0),
+ QColor(129, 56, 0),
+ QColor(131, 57, 0),
+ QColor(132, 58, 0),
+ QColor(134, 59, 0),
+ QColor(134, 59, 0),
+ QColor(136, 61, 0),
+ QColor(137, 62, 0),
+ QColor(137, 62, 0),
+ QColor(139, 63, 0),
+ QColor(139, 63, 0),
+ QColor(140, 65, 0),
+ QColor(142, 66, 0),
+ QColor(142, 66, 0),
+ QColor(143, 67, 0),
+ QColor(143, 67, 0),
+ QColor(145, 68, 0),
+ QColor(145, 68, 0),
+ QColor(146, 70, 0),
+ QColor(146, 70, 0),
+ QColor(148, 71, 0),
+ QColor(148, 71, 0),
+ QColor(149, 72, 0),
+ QColor(149, 72, 0),
+ QColor(151, 73, 0),
+ QColor(151, 73, 0),
+ QColor(153, 75, 0),
+ QColor(153, 75, 0),
+ QColor(154, 76, 0),
+ QColor(154, 76, 0),
+ QColor(154, 76, 0),
+ QColor(156, 77, 0),
+ QColor(156, 77, 0),
+ QColor(157, 79, 0),
+ QColor(157, 79, 0),
+ QColor(159, 80, 0),
+ QColor(159, 80, 0),
+ QColor(159, 80, 0),
+ QColor(160, 81, 0),
+ QColor(160, 81, 0),
+ QColor(162, 82, 0),
+ QColor(162, 82, 0),
+ QColor(163, 84, 0),
+ QColor(163, 84, 0),
+ QColor(165, 85, 0),
+ QColor(165, 85, 0),
+ QColor(166, 86, 0),
+ QColor(166, 86, 0),
+ QColor(166, 86, 0),
+ QColor(168, 87, 0),
+ QColor(168, 87, 0),
+ QColor(170, 89, 0),
+ QColor(170, 89, 0),
+ QColor(171, 90, 0),
+ QColor(171, 90, 0),
+ QColor(173, 91, 0),
+ QColor(173, 91, 0),
+ QColor(174, 93, 0),
+ QColor(174, 93, 0),
+ QColor(176, 94, 0),
+ QColor(176, 94, 0),
+ QColor(177, 95, 0),
+ QColor(177, 95, 0),
+ QColor(179, 96, 0),
+ QColor(179, 96, 0),
+ QColor(180, 98, 0),
+ QColor(182, 99, 0),
+ QColor(182, 99, 0),
+ QColor(183, 100, 0),
+ QColor(183, 100, 0),
+ QColor(185, 102, 0),
+ QColor(185, 102, 0),
+ QColor(187, 103, 0),
+ QColor(187, 103, 0),
+ QColor(188, 104, 0),
+ QColor(188, 104, 0),
+ QColor(190, 105, 0),
+ QColor(191, 107, 0),
+ QColor(191, 107, 0),
+ QColor(193, 108, 0),
+ QColor(193, 108, 0),
+ QColor(194, 109, 0),
+ QColor(196, 110, 0),
+ QColor(196, 110, 0),
+ QColor(197, 112, 0),
+ QColor(197, 112, 0),
+ QColor(199, 113, 0),
+ QColor(200, 114, 0),
+ QColor(200, 114, 0),
+ QColor(202, 116, 0),
+ QColor(202, 116, 0),
+ QColor(204, 117, 0),
+ QColor(205, 118, 0),
+ QColor(205, 118, 0),
+ QColor(207, 119, 0),
+ QColor(208, 121, 0),
+ QColor(208, 121, 0),
+ QColor(210, 122, 0),
+ QColor(211, 123, 0),
+ QColor(211, 123, 0),
+ QColor(213, 124, 0),
+ QColor(214, 126, 0),
+ QColor(214, 126, 0),
+ QColor(216, 127, 0),
+ QColor(217, 128, 0),
+ QColor(217, 128, 0),
+ QColor(219, 130, 0),
+ QColor(221, 131, 0),
+ QColor(221, 131, 0),
+ QColor(222, 132, 0),
+ QColor(224, 133, 0),
+ QColor(224, 133, 0),
+ QColor(225, 135, 0),
+ QColor(227, 136, 0),
+ QColor(227, 136, 0),
+ QColor(228, 137, 0),
+ QColor(230, 138, 0),
+ QColor(230, 138, 0),
+ QColor(231, 140, 0),
+ QColor(233, 141, 0),
+ QColor(233, 141, 0),
+ QColor(234, 142, 0),
+ QColor(236, 144, 0),
+ QColor(236, 144, 0),
+ QColor(238, 145, 0),
+ QColor(239, 146, 0),
+ QColor(241, 147, 0),
+ QColor(241, 147, 0),
+ QColor(242, 149, 0),
+ QColor(244, 150, 0),
+ QColor(244, 150, 0),
+ QColor(245, 151, 0),
+ QColor(247, 153, 0),
+ QColor(247, 153, 0),
+ QColor(248, 154, 0),
+ QColor(250, 155, 0),
+ QColor(251, 156, 0),
+ QColor(251, 156, 0),
+ QColor(253, 158, 0),
+ QColor(255, 159, 0),
+ QColor(255, 159, 0),
+ QColor(255, 160, 0),
+ QColor(255, 161, 0),
+ QColor(255, 163, 0),
+ QColor(255, 163, 0),
+ QColor(255, 164, 0),
+ QColor(255, 165, 0),
+ QColor(255, 167, 0),
+ QColor(255, 167, 0),
+ QColor(255, 168, 0),
+ QColor(255, 169, 0),
+ QColor(255, 169, 0),
+ QColor(255, 170, 0),
+ QColor(255, 172, 0),
+ QColor(255, 173, 0),
+ QColor(255, 173, 0),
+ QColor(255, 174, 0),
+ QColor(255, 175, 0),
+ QColor(255, 177, 0),
+ QColor(255, 178, 0),
+ QColor(255, 179, 0),
+ QColor(255, 181, 0),
+ QColor(255, 181, 0),
+ QColor(255, 182, 0),
+ QColor(255, 183, 0),
+ QColor(255, 184, 0),
+ QColor(255, 187, 7),
+ QColor(255, 188, 10),
+ QColor(255, 189, 14),
+ QColor(255, 191, 18),
+ QColor(255, 192, 21),
+ QColor(255, 193, 25),
+ QColor(255, 195, 29),
+ QColor(255, 197, 36),
+ QColor(255, 198, 40),
+ QColor(255, 200, 43),
+ QColor(255, 202, 51),
+ QColor(255, 204, 54),
+ QColor(255, 206, 61),
+ QColor(255, 207, 65),
+ QColor(255, 210, 72),
+ QColor(255, 211, 76),
+ QColor(255, 214, 83),
+ QColor(255, 216, 91),
+ QColor(255, 219, 98),
+ QColor(255, 221, 105),
+ QColor(255, 223, 109),
+ QColor(255, 225, 116),
+ QColor(255, 228, 123),
+ QColor(255, 232, 134),
+ QColor(255, 234, 142),
+ QColor(255, 237, 149),
+ QColor(255, 239, 156),
+ QColor(255, 240, 160),
+ QColor(255, 243, 167),
+ QColor(255, 246, 174),
+ QColor(255, 248, 182),
+ QColor(255, 249, 185),
+ QColor(255, 252, 193),
+ QColor(255, 253, 196),
+ QColor(255, 255, 204),
+ QColor(255, 255, 207),
+ QColor(255, 255, 211),
+ QColor(255, 255, 218),
+ QColor(255, 255, 222),
+ QColor(255, 255, 225),
+ QColor(255, 255, 229),
+ QColor(255, 255, 233),
+ QColor(255, 255, 236),
+ QColor(255, 255, 240),
+ QColor(255, 255, 244),
+ QColor(255, 255, 247),
+ QColor(255, 255, 255)}
+{
+}
+
+QColor ContinuousColorScale::color(qreal t) const
+{
+ if (t < m_min || t > m_max)
+ return QColor();
+
+ // normalize t
+ t = (t - m_min) / (m_max - m_min);
+
+ // find which colors in the scale are adjacent to ours
+ qreal step = 1.0 / m_colors.size();
+ int i = (int) (t / step);
+
+ if (i >= m_colors.size() - 1)
+ return m_colors.last();
+
+ // normalize t between the two colors
+ int j = i + 1;
+ t = (t - i*step) / (j*step - i*step);
+ return m_colors[i + round(t)];
+}
diff --git a/continuouscolorscale.h b/continuouscolorscale.h
new file mode 100644
index 0000000..1ca2092
--- /dev/null
+++ b/continuouscolorscale.h
@@ -0,0 +1,14 @@
+#ifndef CONTINUOUSCOLORSCALE_H
+#define CONTINUOUSCOLORSCALE_H
+
+#include "colorscale.h"
+
+class ContinuousColorScale : public ColorScale
+{
+public:
+ ContinuousColorScale();
+
+ QColor color(qreal t) const;
+};
+
+#endif // CONTINUOUSCOLORSCALE_H
diff --git a/distortionmeasure.h b/distortionmeasure.h
new file mode 100644
index 0000000..523f62b
--- /dev/null
+++ b/distortionmeasure.h
@@ -0,0 +1,12 @@
+#ifndef DISTORTIONMEASURE_H
+#define DISTORTIONMEASURE_H
+
+#include <armadillo>
+
+class DistortionMeasure
+{
+public:
+ virtual arma::vec measure(const arma::mat &distA, const arma::mat &distB) = 0;
+};
+
+#endif // DISTORTIONMEASURE_H
diff --git a/distortionobserver.cpp b/distortionobserver.cpp
index a6c5ba4..29d7e6f 100644
--- a/distortionobserver.cpp
+++ b/distortionobserver.cpp
@@ -6,17 +6,23 @@ 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);
}
-DistortionObserver::~DistortionObserver()
+void DistortionObserver::setMeasure(DistortionMeasure *measure)
{
+ m_distortionMeasure = measure;
}
void DistortionObserver::setMap(const arma::mat &Y)
{
- arma::vec measures = measureFunc(m_distX, mp::dist(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);
diff --git a/distortionobserver.h b/distortionobserver.h
index 9141d25..101c53d 100644
--- a/distortionobserver.h
+++ b/distortionobserver.h
@@ -4,12 +4,14 @@
#include <QObject>
#include <armadillo>
+#include "distortionmeasure.h"
+
class DistortionObserver : public QObject
{
Q_OBJECT
public:
DistortionObserver(const arma::mat &X, const arma::uvec &sampleIndices);
- virtual ~DistortionObserver();
+ void setMeasure(DistortionMeasure *measure);
signals:
void mapChanged(const arma::vec &distortion);
@@ -17,12 +19,10 @@ signals:
public slots:
void setMap(const arma::mat &Y);
-protected:
- virtual arma::vec measureFunc(const arma::mat &distA, const arma::mat &distB) = 0;
-
private:
arma::mat m_X, m_Y, m_distX;
arma::uvec m_sampleIndices;
+ DistortionMeasure *m_distortionMeasure;
arma::vec m_measures;
};
diff --git a/main.cpp b/main.cpp
index a67ad33..233d22b 100644
--- a/main.cpp
+++ b/main.cpp
@@ -6,6 +6,7 @@
#include <QQmlApplicationEngine>
#include "mp.h"
+#include "continuouscolorscale.h"
#include "scatterplot.h"
#include "interactionhandler.h"
#include "distortionobserver.h"
@@ -51,17 +52,21 @@ int main(int argc, char **argv)
QObject::connect(&interactionHandler, SIGNAL(subsampleChanged(const arma::mat &)),
plot, SLOT(setXY(const arma::mat &)));
- // TODO: works; though it needs measures implementation
- // std::unique_ptr<DistortionObserver> distortionObs(new NPDistortion(X, sampleIndices));
- // QObject::connect(&interactionHandler, SIGNAL(subsampleChanged(const arma::mat &)),
- // distortionObs.get(), SLOT(setMap(const arma::mat &)));
- // QObject::connect(distortionObs.get(), SIGNAL(mapChanged(const arma::vec &)),
- // plot, SLOT(setColorData(const arma::vec &)));
+ DistortionObserver distortionObs(X, sampleIndices);
+ std::unique_ptr<DistortionMeasure> distortionMeasure(new NPDistortion());
+ distortionObs.setMeasure(distortionMeasure.get());
+ QObject::connect(&interactionHandler, SIGNAL(subsampleChanged(const arma::mat &)),
+ &distortionObs, SLOT(setMap(const arma::mat &)));
+ QObject::connect(&distortionObs, SIGNAL(mapChanged(const arma::vec &)),
+ plot, SLOT(setColorData(const arma::vec &)));
+ ContinuousColorScale colorScale;
+ colorScale.setExtents(-1, 1);
+ plot->setColorScale(&colorScale);
interactionHandler.setSubsample(Ys);
// TODO: remove when proper measure coloring is done
- plot->setColorData(labels);
+ // plot->setColorData(labels);
return app.exec();
}
diff --git a/main_view.qml b/main_view.qml
index 5afe270..19b4efc 100644
--- a/main_view.qml
+++ b/main_view.qml
@@ -17,6 +17,26 @@ ApplicationWindow {
MenuItem { action: saveDataAction }
MenuItem { action: quitAction }
}
+
+ Menu {
+ title: "View"
+ MenuItem {
+ action: noneColorAction
+ exclusiveGroup: coloringGroup
+ }
+ MenuItem {
+ action: npColorAction
+ exclusiveGroup: coloringGroup
+ }
+ MenuItem {
+ action: stressColorAction
+ exclusiveGroup: coloringGroup
+ }
+ MenuItem {
+ action: silhouetteColorAction
+ exclusiveGroup: coloringGroup
+ }
+ }
}
Item {
@@ -92,4 +112,41 @@ ApplicationWindow {
shortcut: "Ctrl+D"
onTriggered: console.log("Save data")
}
+
+ ExclusiveGroup {
+ id: coloringGroup
+
+ Action {
+ id: noneColorAction
+ text: "None"
+ shortcut: "Shift+O"
+ checked: true
+ checkable: true
+ onTriggered: console.log("None")
+ }
+
+ Action {
+ id: npColorAction
+ text: "Neighborhood Preservation"
+ shortcut: "Shift+N"
+ checkable: true
+ onTriggered: console.log("NP")
+ }
+
+ Action {
+ id: stressColorAction
+ text: "Stress"
+ shortcut: "Shift+S"
+ checkable: true
+ onTriggered: console.log("Stress")
+ }
+
+ Action {
+ id: silhouetteColorAction
+ text: "Silhouette"
+ shortcut: "Shift+T"
+ checkable: true
+ onTriggered: console.log("Silhouette")
+ }
+ }
}
diff --git a/measures.cpp b/measures.cpp
index fe4077a..bee3515 100644
--- a/measures.cpp
+++ b/measures.cpp
@@ -1,11 +1,61 @@
#include "mp.h"
+#include <algorithm>
+
+static
+void knn(const arma::mat &dmat, arma::uword i, arma::uword k, arma::uvec &nn, arma::vec &dist)
+{
+ arma::uword n = dist.n_rows;
+ if (k > n) {
+ return;
+ }
+
+ double dmax = arma::datum::inf;
+ nn.fill(i);
+ dist.fill(dmax);
+ for (arma::uword j = 0; j < n; j++) {
+ if (j == i) {
+ continue;
+ }
+
+ if (dmat(i, j) < dmax) {
+ arma::uword l;
+ for (l = 0; dmat(i, j) > dist[l] && l < k; l++);
+ for (arma::uword m = l + 1; m < k; m++) {
+ nn[m] = nn[m - 1];
+ dist[m] = dist[m - 1];
+ }
+
+ nn[l] = j;
+ dist[l] = dmat(i, j);
+ }
+ }
+}
+
arma::vec mp::neighborhoodPreservation(const arma::mat &distA,
const arma::mat &distB,
- int k)
+ arma::uword k)
{
- // TODO
- return arma::vec(distA.n_rows, arma::fill::zeros);
+ arma::uword n = distA.n_rows;
+ arma::vec np(n);
+
+ for (arma::uword i = 0; i < n; i++) {
+ arma::uvec nnA(k);
+ arma::uvec nnB(k);
+ arma::vec dist(k);
+
+ knn(distA, i, k, nnA, dist);
+ knn(distB, i, k, nnB, dist);
+
+ std::sort(nnA.begin(), nnA.end());
+ std::sort(nnB.begin(), nnB.end());
+
+ arma::uword l;
+ for (l = 0; nnA[l] == nnB[l] && l < k; l++);
+ np[i] = ((double) l) / k;
+ }
+
+ return np;
}
arma::vec mp::silhouette(const arma::mat &distA,
diff --git a/mp.h b/mp.h
index a9ddd38..192f106 100644
--- a/mp.h
+++ b/mp.h
@@ -5,17 +5,17 @@
namespace mp {
-// --- Distance-related
+// Distance-related
typedef double (*DistFunc)(const arma::rowvec &, const arma::rowvec &);
double euclidean(const arma::rowvec &x1, const arma::rowvec &x2);
arma::mat dist(const arma::mat &X, DistFunc dfunc = euclidean);
-// --- Evaluation measures
+// Evaluation measures
typedef arma::vec (*MeasureFunc)(const arma::mat &distA, const arma::mat &distB);
-arma::vec neighborhoodPreservation(const arma::mat &distA, const arma::mat &distB, int k = 10);
+arma::vec neighborhoodPreservation(const arma::mat &distA, const arma::mat &distB, arma::uword k = 10);
arma::vec silhouette(const arma::mat &distA, const arma::mat &distB, const arma::vec &labels);
-// --- Techniques
+// Techniques
arma::mat lamp(const arma::mat &X, const arma::uvec &sampleIndices, const arma::mat &Ys);
void lamp(const arma::mat &X, const arma::uvec &sampleIndices, const arma::mat &Ys, arma::mat &Y);
diff --git a/npdistortion.cpp b/npdistortion.cpp
index 71db85b..1994c74 100644
--- a/npdistortion.cpp
+++ b/npdistortion.cpp
@@ -2,13 +2,12 @@
#include "mp.h"
-NPDistortion::NPDistortion(const arma::mat &X, const arma::uvec &sampleIndices, int k)
- : DistortionObserver(X, sampleIndices)
- , m_k(k)
+NPDistortion::NPDistortion(int k)
+ : m_k(k)
{
}
-arma::vec NPDistortion::measureFunc(const arma::mat &distA, const arma::mat &distB)
+arma::vec NPDistortion::measure(const arma::mat &distA, const arma::mat &distB)
{
return mp::neighborhoodPreservation(distA, distB, m_k);
}
diff --git a/npdistortion.h b/npdistortion.h
index a84f63a..a70616d 100644
--- a/npdistortion.h
+++ b/npdistortion.h
@@ -1,15 +1,13 @@
#ifndef NPDISTORTION_H
#define NPDISTORTION_H
-#include "distortionobserver.h"
+#include "distortionmeasure.h"
-class NPDistortion : public DistortionObserver
+class NPDistortion : public DistortionMeasure
{
public:
- NPDistortion(const arma::mat &X, const arma::uvec &sampleIndices, int k = 10);
-
-protected:
- arma::vec measureFunc(const arma::mat &distA, const arma::mat &distB);
+ NPDistortion(int k = 10);
+ arma::vec measure(const arma::mat &distA, const arma::mat &distB);
private:
int m_k;
diff --git a/pm.pro b/pm.pro
index 8856347..de669cd 100644
--- a/pm.pro
+++ b/pm.pro
@@ -3,13 +3,16 @@ QT += qml quick widgets
QMAKE_CXXFLAGS += -std=c++11 -fopenmp
QMAKE_LIBS += -larmadillo -fopenmp
HEADERS += colorscale.h \
+ continuouscolorscale.h \
scatterplot.h \
interactionhandler.h \
distortionobserver.h \
+ distortionmeasure.h \
npdistortion.h \
mp.h
SOURCES += main.cpp \
colorscale.cpp \
+ continuouscolorscale.cpp \
scatterplot.cpp \
interactionhandler.cpp \
distortionobserver.cpp \
diff --git a/scatterplot.cpp b/scatterplot.cpp
index c43b625..0a252e1 100644
--- a/scatterplot.cpp
+++ b/scatterplot.cpp
@@ -2,7 +2,7 @@
#include <cmath>
-static const qreal GLYPH_OPACITY = 0.3;
+static const qreal GLYPH_OPACITY = 0.4;
static const qreal GLYPH_OPACITY_SELECTED = 1.0;
static const QColor SELECTION_COLOR(QColor(128, 128, 128, 96));
static const int GLYPH_SIZE = 8;
@@ -14,7 +14,8 @@ Scatterplot::Scatterplot(QQuickItem *parent)
, m_currentInteractionState(INTERACTION_NONE)
, m_shouldUpdateGeometry(false)
, m_shouldUpdateMaterials(false)
- , m_colorScale{
+{
+ m_colorScale = new ColorScale{
QColor("#1f77b4"),
QColor("#ff7f0e"),
QColor("#2ca02c"),
@@ -24,18 +25,20 @@ Scatterplot::Scatterplot(QQuickItem *parent)
QColor("#e377c2"),
QColor("#17becf"),
QColor("#7f7f7f"),
- }
-{
+ };
+
setClip(true);
setFlag(QQuickItem::ItemHasContents);
}
-void Scatterplot::setColorScale(const ColorScale &colorScale)
+void Scatterplot::setColorScale(ColorScale *colorScale)
{
- m_colorScale = colorScale;
+ if (!colorScale) {
+ return;
+ }
+ m_colorScale = colorScale;
if (m_colorData.n_elem > 0) {
- m_colorScale.setExtents(m_colorData.min(), m_colorData.max());
updateMaterials();
}
}
@@ -62,7 +65,6 @@ void Scatterplot::setColorData(const arma::vec &colorData)
return;
m_colorData = colorData;
- m_colorScale.setExtents(m_colorData.min(), m_colorData.max());
emit colorDataChanged(m_colorData);
updateMaterials();
@@ -182,7 +184,7 @@ QSGNode *Scatterplot::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
}
if (m_shouldUpdateMaterials) {
QSGFlatColorMaterial *material = static_cast<QSGFlatColorMaterial *>(glyphNode->material());
- material->setColor(m_colorScale.color(m_colorData[i]));
+ material->setColor(m_colorScale->color(m_colorData[i]));
glyphNode->setMaterial(material);
glyphNode->markDirty(QSGNode::DirtyMaterial);
}
diff --git a/scatterplot.h b/scatterplot.h
index a115755..7ed58c8 100644
--- a/scatterplot.h
+++ b/scatterplot.h
@@ -12,7 +12,7 @@ class Scatterplot : public QQuickItem
public:
Scatterplot(QQuickItem *parent = 0);
- void setColorScale(const ColorScale &colorScale);
+ void setColorScale(ColorScale *colorScale);
signals:
void xyChanged(const arma::mat &XY);
@@ -58,7 +58,7 @@ private:
arma::vec m_colorData;
- ColorScale m_colorScale;
+ ColorScale *m_colorScale;
};
#endif // SCATTERPLOT_H