From a319a857a633ab2fbcdbae5204eb5cfcdcc1b413 Mon Sep 17 00:00:00 2001 From: Samuel Fadel Date: Tue, 19 Jan 2016 02:30:50 +0100 Subject: Updated options & hacks to change color scales. --- main.cpp | 80 +++++------- main.h | 149 +++++++++++++++++++-- main_view.qml | 410 ++++++++++++++++++++++++++++++++++------------------------ 3 files changed, 408 insertions(+), 231 deletions(-) diff --git a/main.cpp b/main.cpp index c58d216..3add8e7 100644 --- a/main.cpp +++ b/main.cpp @@ -117,47 +117,33 @@ int main(int argc, char **argv) QQmlApplicationEngine engine(QUrl("qrc:///main_view.qml")); - //ColorScale colorScale{ - // QColor("#1f77b4"), - // QColor("#ff7f0e"), - // QColor("#2ca02c"), - // QColor("#d62728"), - // QColor("#9467bd"), - // QColor("#8c564b"), - // QColor("#e377c2"), - // QColor("#17becf"), - // QColor("#7f7f7f"), - //}; - //colorScale.setExtents(labels.min(), labels.max()); - - ContinuousColorScale colorScale = ContinuousColorScale::builtin(ContinuousColorScale::HEATED_OBJECTS); - - Scatterplot *cpPlot = engine.rootObjects()[0]->findChild("cpPlot"); - Scatterplot *rpPlot = engine.rootObjects()[0]->findChild("rpPlot"); - cpPlot->setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton); - // cpPlot->setColorData(arma::zeros(cpSize)); - VoronoiSplat *splat = engine.rootObjects()[0]->findChild("splat"); - skelft2DInitialization(splat->width()); - Colormap *colormap = engine.rootObjects()[0]->findChild("colormap"); + m->cpPlot = engine.rootObjects()[0]->findChild("cpPlot"); + m->cpPlot->setAcceptedMouseButtons(Qt::LeftButton | Qt::MiddleButton | Qt::RightButton); + + m->rpPlot = engine.rootObjects()[0]->findChild("rpPlot"); + + m->splat = engine.rootObjects()[0]->findChild("splat"); + skelft2DInitialization(m->splat->width()); + + m->colormap = engine.rootObjects()[0]->findChild("colormap"); // Keep track of the current cp (in order to save them later, if requested) - QObject::connect(cpPlot, SIGNAL(xyChanged(const arma::mat &)), + QObject::connect(m->cpPlot, SIGNAL(xyChanged(const arma::mat &)), m, SLOT(setCP(const arma::mat &))); - QObject::connect(cpPlot, SIGNAL(xyInteractivelyChanged(const arma::mat &)), + QObject::connect(m->cpPlot, SIGNAL(xyInteractivelyChanged(const arma::mat &)), m, SLOT(setCP(const arma::mat &))); // 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.setTechnique(InteractionHandler::TECHNIQUE_LAMP); + QObject::connect(m->cpPlot, SIGNAL(xyChanged(const arma::mat &)), &interactionHandler, SLOT(setCP(const arma::mat &))); - QObject::connect(cpPlot, SIGNAL(xyInteractivelyChanged(const arma::mat &)), + QObject::connect(m->cpPlot, SIGNAL(xyInteractivelyChanged(const arma::mat &)), &interactionHandler, SLOT(setCP(const arma::mat &))); QObject::connect(&interactionHandler, SIGNAL(cpChanged(const arma::mat &)), - rpPlot, SLOT(setXY(const arma::mat &))); + m->rpPlot, SLOT(setXY(const arma::mat &))); QObject::connect(&interactionHandler, SIGNAL(cpChanged(const arma::mat &)), - splat, SLOT(setSites(const arma::mat &))); + m->splat, SLOT(setSites(const arma::mat &))); // Linking between selections in cp plot and rp plot //SelectionHandler selectionHandler(cpIndices); @@ -173,33 +159,33 @@ int main(int argc, char **argv) //QObject::connect(history, SIGNAL(currentItemChanged(const arma::mat &)), // cpPlot, SLOT(setXY(const arma::mat &))); - QObject::connect(rpPlot, SIGNAL(scaleChanged(const LinearScale &, const LinearScale &)), - cpPlot, SLOT(setScale(const LinearScale &, const LinearScale &))); + QObject::connect(m->rpPlot, SIGNAL(scaleChanged(const LinearScale &, const LinearScale &)), + m->cpPlot, SLOT(setScale(const LinearScale &, const LinearScale &))); - BarChart *barChart = engine.rootObjects()[0]->findChild("barChart"); - barChart->setAcceptedMouseButtons(Qt::LeftButton); - barChart->setColorScale(colorScale); + m->barChart = engine.rootObjects()[0]->findChild("barChart"); + m->barChart->setAcceptedMouseButtons(Qt::LeftButton); + m->setBarChartColorScale(Main::ColorScaleContinuous); 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 &))); + m->rpPlot, SLOT(setColorData(const arma::vec &))); QObject::connect(&projectionObserver, SIGNAL(mapChanged(const arma::vec &)), - splat, SLOT(setValues(const arma::vec &))); + m->splat, SLOT(setValues(const arma::vec &))); QObject::connect(&projectionObserver, SIGNAL(mapChanged(const arma::vec &)), - barChart, SLOT(setValues(const arma::vec &))); + m->barChart, SLOT(setValues(const arma::vec &))); //history->addHistoryItem(Ys); - colormap->setColorScale(colorScale); - rpPlot->setColorScale(colorScale); - splat->setColorScale(colorScale); - - cpPlot->setColorScale(colorScale); - cpPlot->setAutoScale(false); - cpPlot->setColorData(labels(cpIndices), false); - cpPlot->setXY(Ys, false); - cpPlot->update(); + m->setColormapColorScale(Main::ColorScaleContinuous); + m->setCPPlotColorScale(Main::ColorScaleContinuous); + m->setRPPlotColorScale(Main::ColorScaleContinuous); + m->setSplatColorScale(Main::ColorScaleContinuous); + + m->cpPlot->setAutoScale(false); + m->cpPlot->setColorData(labels(cpIndices), false); + m->cpPlot->setXY(Ys, false); + m->cpPlot->update(); auto ret = app.exec(); diff --git a/main.h b/main.h index 86024b9..69c58f0 100644 --- a/main.h +++ b/main.h @@ -4,11 +4,18 @@ #include #include -#include "interactionhandler.h" +#include "colorscale.h" +#include "continuouscolorscale.h" + +#include "barchart.h" +#include "colormap.h" +#include "scatterplot.h" +#include "voronoisplat.h" class Main : public QObject { Q_OBJECT + Q_ENUMS(ColorScaleType) public: static Main *instance() { // FIXME: Possibly dangerous @@ -47,18 +54,110 @@ public: setCPSavePath(path.toStdString()); } - void setInteractionHandler(InteractionHandler *interactionHandler) { - m_interactionHandler = interactionHandler; + arma::mat X() const { return m_dataset.cols(0, m_dataset.n_cols - 2); } + arma::vec labels() const { return m_dataset.col(m_dataset.n_cols - 1); } + + enum ColorScaleType { + ColorScaleCategorical, + ColorScaleContinuous, + ColorScaleDivergent, + ColorScaleRainbow + }; + + ColorScale *COLOR_SCALE_CATEGORICAL; + ColorScale *COLOR_SCALE_CONTINUOUS; + ColorScale *COLOR_SCALE_DIVERGENT; + ColorScale *COLOR_SCALE_RAINBOW; + + Q_INVOKABLE void setCPPlotColorScale(ColorScaleType colorScaleType) { + switch (colorScaleType) { + case ColorScaleCategorical: + cpPlot->setColorScale(*COLOR_SCALE_CATEGORICAL); + break; + case ColorScaleContinuous: + cpPlot->setColorScale(*COLOR_SCALE_CONTINUOUS); + break; + case ColorScaleDivergent: + cpPlot->setColorScale(*COLOR_SCALE_DIVERGENT); + break; + case ColorScaleRainbow: + cpPlot->setColorScale(*COLOR_SCALE_RAINBOW); + break; + } } - Q_INVOKABLE void setTechnique(int technique) { - if (m_interactionHandler) { - m_interactionHandler->setTechnique((InteractionHandler::Technique) technique); + Q_INVOKABLE void setRPPlotColorScale(ColorScaleType colorScaleType) { + switch (colorScaleType) { + case ColorScaleCategorical: + rpPlot->setColorScale(*COLOR_SCALE_CATEGORICAL); + break; + case ColorScaleContinuous: + rpPlot->setColorScale(*COLOR_SCALE_CONTINUOUS); + break; + case ColorScaleDivergent: + rpPlot->setColorScale(*COLOR_SCALE_DIVERGENT); + break; + case ColorScaleRainbow: + rpPlot->setColorScale(*COLOR_SCALE_RAINBOW); + break; } } - arma::mat X() const { return m_dataset.cols(0, m_dataset.n_cols - 2); } - arma::vec labels() const { return m_dataset.col(m_dataset.n_cols - 1); } + Q_INVOKABLE void setColormapColorScale(ColorScaleType colorScaleType) { + switch (colorScaleType) { + case ColorScaleCategorical: + colormap->setColorScale(*COLOR_SCALE_CATEGORICAL); + break; + case ColorScaleContinuous: + colormap->setColorScale(*COLOR_SCALE_CONTINUOUS); + break; + case ColorScaleDivergent: + colormap->setColorScale(*COLOR_SCALE_DIVERGENT); + break; + case ColorScaleRainbow: + colormap->setColorScale(*COLOR_SCALE_RAINBOW); + break; + } + } + + Q_INVOKABLE void setBarChartColorScale(ColorScaleType colorScaleType) { + switch (colorScaleType) { + case ColorScaleCategorical: + barChart->setColorScale(*COLOR_SCALE_CATEGORICAL); + break; + case ColorScaleContinuous: + barChart->setColorScale(*COLOR_SCALE_CONTINUOUS); + break; + case ColorScaleDivergent: + barChart->setColorScale(*COLOR_SCALE_DIVERGENT); + break; + case ColorScaleRainbow: + barChart->setColorScale(*COLOR_SCALE_RAINBOW); + break; + } + } + + Q_INVOKABLE void setSplatColorScale(ColorScaleType colorScaleType) { + switch (colorScaleType) { + case ColorScaleCategorical: + splat->setColorScale(*COLOR_SCALE_CATEGORICAL); + break; + case ColorScaleContinuous: + splat->setColorScale(*COLOR_SCALE_CONTINUOUS); + break; + case ColorScaleDivergent: + splat->setColorScale(*COLOR_SCALE_DIVERGENT); + break; + case ColorScaleRainbow: + splat->setColorScale(*COLOR_SCALE_RAINBOW); + break; + } + } + + BarChart *barChart; + Colormap *colormap; + Scatterplot *cpPlot, *rpPlot; + VoronoiSplat *splat; public slots: void setCPIndices(const arma::uvec &indices) { m_cpIndices = indices; } @@ -74,15 +173,39 @@ public slots: private: Main(QObject *parent = 0) : QObject(parent) - , m_interactionHandler(0) - {} - ~Main() {} - Q_DISABLE_COPY(Main) + , barChart(0) + , cpPlot(0) + , rpPlot(0) + , splat(0) + { + COLOR_SCALE_CATEGORICAL = new ColorScale{ + QColor("#1f77b4"), + QColor("#ff7f0e"), + QColor("#2ca02c"), + QColor("#d62728"), + QColor("#9467bd"), + QColor("#8c564b"), + QColor("#e377c2"), + QColor("#17becf"), + QColor("#7f7f7f"), + }; + COLOR_SCALE_CONTINUOUS = + new ColorScale{ContinuousColorScale::builtin(ContinuousColorScale::HEATED_OBJECTS)}; + COLOR_SCALE_DIVERGENT = + new ColorScale{ContinuousColorScale::builtin(ContinuousColorScale::RED_GRAY_BLUE)}; + COLOR_SCALE_RAINBOW = + new ColorScale{ContinuousColorScale::builtin(ContinuousColorScale::RAINBOW)}; + } + ~Main() { + delete COLOR_SCALE_CATEGORICAL; + delete COLOR_SCALE_CONTINUOUS; + delete COLOR_SCALE_DIVERGENT; + delete COLOR_SCALE_RAINBOW; + } arma::mat m_dataset, m_cp; arma::uvec m_cpIndices; std::string m_indicesSavePath, m_cpSavePath; - InteractionHandler *m_interactionHandler; }; #endif // MAIN_H diff --git a/main_view.qml b/main_view.qml index 9e02c32..e2f27d9 100644 --- a/main_view.qml +++ b/main_view.qml @@ -10,6 +10,7 @@ ApplicationWindow { id: mainWindow title: "Projection" visible: true + onClosing: Qt.quit() Component.onCompleted: { setX(Screen.width / 2 - width / 2); setY(Screen.height / 2 - height / 2); @@ -143,212 +144,256 @@ ApplicationWindow { } // Options panel - ColumnLayout { + RowLayout { Layout.alignment: Qt.AlignTop | Qt.AlignLeft - GroupBox { - Layout.fillWidth: true - title: "Projection metrics" + ColumnLayout { + Layout.alignment: Qt.AlignTop | Qt.AlignLeft + + GroupBox { + title: "Control points" + checkable: true + __checkbox.onClicked: { + cpPlot.visible = this.checked; + + if (this.checked) { + cpPlot.z = 0; + rpPlot.z = 0; + } else { + cpPlot.z = 0; + rpPlot.z = 1; + } + } - Column { - ExclusiveGroup { id: wrtMetricsGroup } + GridLayout { + columns: 2 + + GroupBox { + Layout.columnSpan: 2 + flat: true + title: "Colors" + + GridLayout { + columns: 2 + + Label { text: "Map to:" } + ComboBox { + id: cpPlotMetricComboBox + model: metricsModel + } + + Label { text: "Color map:" } + ComboBox { + id: cpPlotColormapCombo + model: colormapModel + onActivated: { + Main.setCPPlotColorScale(model.get(index).value); + } + } + } + } - RadioButton { - text: "Current" - exclusiveGroup: wrtMetricsGroup - checked: true - } - RadioButton { - text: "Diff. to previous" - exclusiveGroup: wrtMetricsGroup - } - RadioButton { - text: "Diff. to original" - exclusiveGroup: wrtMetricsGroup - } - } - } + Label { text: "Glyph size:" } + SpinBox { + id: cpGlyphSizeSpinBox + maximumValue: 100 + minimumValue: 6 + value: cpPlot.glyphSize() + decimals: 1 + stepSize: 1 + onValueChanged: cpPlot.setGlyphSize(this.value) + } - GroupBox { - title: "Control points" - checkable: true - __checkbox.onClicked: { - cpPlot.visible = this.checked; - - if (this.checked) { - cpPlot.z = 0; - rpPlot.z = 0; - } else { - cpPlot.z = 0; - rpPlot.z = 1; + Label { text: "Opacity:" } + Slider { + id: cpPlotOpacitySlider + tickmarksEnabled: true + stepSize: 0.1 + maximumValue: 1 + minimumValue: 0 + value: cpPlot.opacity + onValueChanged: cpPlot.opacity = this.value + } } } - GridLayout { - columns: 2 - - GroupBox { - Layout.columnSpan: 2 - flat: true - title: "Colors" - - GridLayout { - columns: 2 - - Label { text: "Map to:" } - ComboBox { - id: cpPlotMetricComboBox - model: metricsModel - } + GroupBox { + title: "Regular points" + checked: false + checkable: true + __checkbox.onClicked: { + rpPlot.visible = this.checked; + } - Label { text: "Color map:" } - ComboBox { - id: cpPlotColormapCombo - model: [ "Categorical", "Continuous", "Divergent", "Rainbow" ] + GridLayout { + columns: 2 + + GroupBox { + Layout.columnSpan: 2 + flat: true + title: "Colors" + + GridLayout { + columns: 2 + + Label { text: "Map to:" } + ComboBox { + id: rpPlotMetricComboBox + model: metricsModel + } + + Label { text: "Color map:" } + ComboBox { + id: rpPlotColormapCombo + model: colormapModel + onActivated: { + Main.setRPPlotColorScale(model.get(index).value); + } + } } } - } - Label { text: "Glyph size:" } - SpinBox { - id: cpGlyphSizeSpinBox - maximumValue: 100 - minimumValue: 6 - value: cpPlot.glyphSize() - decimals: 1 - stepSize: 1 - onValueChanged: cpPlot.setGlyphSize(this.value) - } + Label { text: "Glyph size:" } + SpinBox { + id: rpGlyphSizeSpinBox + maximumValue: 100 + minimumValue: 6 + value: rpPlot.glyphSize() + decimals: 1 + stepSize: 1 + onValueChanged: rpPlot.setGlyphSize(this.value) + } - Label { text: "Opacity:" } - Slider { - id: cpPlotOpacitySlider - tickmarksEnabled: true - stepSize: 0.1 - maximumValue: 1 - minimumValue: 0 - value: cpPlot.opacity - onValueChanged: cpPlot.opacity = this.value + Label { text: "Opacity:" } + Slider { + id: rpPlotOpacitySlider + tickmarksEnabled: true + stepSize: 0.1 + maximumValue: 1 + minimumValue: 0 + value: rpPlot.opacity + onValueChanged: rpPlot.opacity = this.value + } } } } - GroupBox { - title: "Regular points" - checked: false - checkable: true - __checkbox.onClicked: { - rpPlot.visible = this.checked; - } - - GridLayout { - columns: 2 - - GroupBox { - Layout.columnSpan: 2 - flat: true - title: "Colors" + ColumnLayout { + Layout.alignment: Qt.AlignTop | Qt.AlignLeft - GridLayout { - columns: 2 + GroupBox { + title: "Splat" + checkable: true + __checkbox.onClicked: { + splat.visible = this.checked; + colormap.visible = this.checked; + } - Label { text: "Map to:" } - ComboBox { - id: rpPlotMetricComboBox - model: metricsModel + GridLayout { + columns: 2 + + GroupBox { + Layout.columnSpan: 2 + flat: true + title: "Colors" + + GridLayout { + columns: 2 + + Label { text: "Map to:" } + ComboBox { + id: splatMetricComboBox + model: metricsModel + } + + Label { text: "Color map:" } + ComboBox { + id: splatColormapCombo + model: colormapModel + onActivated: { + Main.setColormapColorScale(model.get(index).value); + Main.setSplatColorScale(model.get(index).value); + } + } } + } - Label { text: "Color map:" } - ComboBox { - id: lotColormapCombo - model: [ "Categorical", "Continuous", "Divergent", "Rainbow" ] - } + Label { text: "Alpha:" } + SpinBox { + id: alphaSpinBox + maximumValue: 100 + minimumValue: 1 + value: splat.alpha() + decimals: 2 + stepSize: 1 + onValueChanged: splat.setAlpha(this.value) } - } - Label { text: "Glyph size:" } - SpinBox { - id: rpGlyphSizeSpinBox - maximumValue: 100 - minimumValue: 6 - value: rpPlot.glyphSize() - decimals: 1 - stepSize: 1 - onValueChanged: rpPlot.setGlyphSize(this.value) - } + Label { text: "Beta:" } + SpinBox { + id: betaSpinBox + maximumValue: 100 + minimumValue: 1 + value: splat.beta() + decimals: 2 + stepSize: 1 + onValueChanged: splat.setBeta(this.value) + } - Label { text: "Opacity:" } - Slider { - id: rpPlotOpacitySlider - tickmarksEnabled: true - stepSize: 0.1 - maximumValue: 1 - minimumValue: 0 - value: rpPlot.opacity - onValueChanged: rpPlot.opacity = this.value + Label { text: "Opacity:" } + Slider { + id: splatOpacitySlider + tickmarksEnabled: true + stepSize: 0.1 + maximumValue: 1 + minimumValue: 0 + value: splat.opacity + onValueChanged: splat.opacity = this.value + } } } - } - GroupBox { - title: "Splat" - checkable: true - __checkbox.onClicked: { - splat.visible = this.checked - } - - GridLayout { - columns: 2 - - Label { text: "Alpha:" } - SpinBox { - id: alphaSpinBox - maximumValue: 100 - minimumValue: 1 - value: splat.alpha() - decimals: 2 - stepSize: 1 - onValueChanged: splat.setAlpha(this.value) + GroupBox { + title: "Bar chart" + checkable: true + __checkbox.onClicked: { + bottomView.visible = this.checked } - Label { text: "Beta:" } - SpinBox { - id: betaSpinBox - maximumValue: 100 - minimumValue: 1 - value: splat.beta() - decimals: 2 - stepSize: 1 - onValueChanged: splat.setBeta(this.value) - } + GridLayout { + columns: 2 - Label { text: "Opacity:" } - Slider { - id: splatOpacitySlider - tickmarksEnabled: true - stepSize: 0.1 - maximumValue: 1 - minimumValue: 0 - value: splat.opacity - onValueChanged: splat.opacity = this.value + Label { text: "Color map:" } + ComboBox { + id: barChartColormapCombo + model: colormapModel + onActivated: { + Main.setBarChartColorScale(model.get(index).value); + } + } } } - } - GroupBox { - title: "Bar chart" - checkable: true - __checkbox.onClicked: { - bottomView.visible = this.checked - } + GroupBox { + Layout.fillWidth: true + title: "Projection metrics" - GridLayout { - columns: 2 + Column { + ExclusiveGroup { id: wrtMetricsGroup } - Label { text: "Color map:" } - ComboBox { - id: barChartColormapCombo - model: [ "Categorical", "Continuous", "Divergent", "Rainbow" ] + RadioButton { + text: "Current" + exclusiveGroup: wrtMetricsGroup + checked: true + } + RadioButton { + text: "Diff. to previous" + exclusiveGroup: wrtMetricsGroup + } + RadioButton { + text: "Diff. to original" + exclusiveGroup: wrtMetricsGroup + } } } } @@ -394,4 +439,27 @@ ApplicationWindow { ListElement { text: "CP influence" } ListElement { text: "Stress" } } + + ListModel { + id: colormapModel + + Component.onCompleted: { + this.append({ + "value": Main.ColorScaleContinuous, + "text": "Continuous" + }); + this.append({ + "value": Main.ColorScaleCategorical, + "text": "Categorical" + }); + this.append({ + "value": Main.ColorScaleDivergent, + "text": "Divergent" + }); + this.append({ + "value": Main.ColorScaleRainbow, + "text": "Rainbow" + }); + } + } } -- cgit v1.2.3