From 3ce49858c6859fccc2e4d35839c34685348790d1 Mon Sep 17 00:00:00 2001 From: Samuel Fadel Date: Wed, 2 Mar 2016 15:47:24 -0300 Subject: Improvements related to ColorScale and screenshots. * ColorScale: now a pointer whenever needed. main() takes care of updating extents * New class DivergentColorScale: works specifically for divergent scales, always has 3 colors as input: negative values, 0, positive values * ManipulationHandler: ProjectionHistory no longer needed --- barchart.cpp | 10 +- barchart.h | 6 +- colormap.cpp | 6 +- colormap.h | 4 +- colorscale.cpp | 2 +- colorscale.h | 2 + continuouscolorscale.cpp | 790 +++++++++++++++++++++++++++++++---------------- continuouscolorscale.h | 6 +- divergentcolorscale.cpp | 313 +++++++++++++++++++ divergentcolorscale.h | 24 ++ main.cpp | 29 +- main.h | 69 +++-- main_view.qml | 38 ++- manipulationhandler.cpp | 5 +- manipulationhandler.h | 6 +- numericrange.h | 5 +- pm.pro | 2 + projectionhistory.cpp | 21 +- projectionhistory.h | 6 +- scatterplot.cpp | 28 +- scatterplot.h | 7 +- voronoisplat.cpp | 6 +- voronoisplat.h | 6 +- 23 files changed, 1022 insertions(+), 369 deletions(-) create mode 100644 divergentcolorscale.cpp create mode 100644 divergentcolorscale.h diff --git a/barchart.cpp b/barchart.cpp index cfa82aa..e651ccd 100644 --- a/barchart.cpp +++ b/barchart.cpp @@ -35,7 +35,7 @@ BarChart::BarChart(QQuickItem *parent) , m_dragLastPos(-1.0f) , m_shouldUpdateSelection(false) , m_brushedItem(-1) - , m_colorScale(ContinuousColorScale::builtin(ContinuousColorScale::HeatedObjects)) + , m_colorScale(0) , m_scale(0.0f, 1.0f, 0.0f, 1.0f) { setClip(true); @@ -61,7 +61,6 @@ void BarChart::setValues(const arma::vec &values) setAcceptHoverEvents(m_values.n_elem > 0); if (m_values.n_elem > 0) { m_scale.setDomain(m_values.min(), m_values.max()); - m_colorScale.setExtents(m_values.min(), m_values.max()); std::iota(m_originalIndices.begin(), m_originalIndices.end(), 0); std::sort(m_originalIndices.begin(), m_originalIndices.end(), @@ -79,12 +78,9 @@ void BarChart::setValues(const arma::vec &values) update(); } -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; @@ -265,7 +261,7 @@ void BarChart::updateBars(QSGNode *node) const 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(); } diff --git a/barchart.h b/barchart.h index 98e3521..28a9fa9 100644 --- a/barchart.h +++ b/barchart.h @@ -20,7 +20,7 @@ public: signals: void valuesChanged(const arma::vec &values) const; - void colorScaleChanged(const ColorScale &scale) const; + void colorScaleChanged(const ColorScale *scale) const; void selectionChanged(const std::vector &selection) const; void selectionInteractivelyChanged(const std::vector &selection) const; void itemBrushed(int item) const; @@ -28,7 +28,7 @@ signals: public slots: void setValues(const arma::vec &values); - void setColorScale(const ColorScale &scale); + void setColorScale(const ColorScale *scale); void setSelection(const std::vector &selection); void brushItem(int item); @@ -71,7 +71,7 @@ private: int itemAt(float x, bool includeSelectorWidth = false) const; arma::vec m_values; - ColorScale m_colorScale; + const ColorScale *m_colorScale; std::vector m_originalIndices, m_currentIndices; LinearScale m_scale; }; diff --git a/colormap.cpp b/colormap.cpp index 3ebf5c8..961f475 100644 --- a/colormap.cpp +++ b/colormap.cpp @@ -129,10 +129,10 @@ void Colormap::setOrientation(Colormap::Orientation orientation) update(); } -void Colormap::setColorScale(const ColorScale &scale) +void Colormap::setColorScale(const ColorScale *scale) { - m_cmap.resize(scale.numColors() * 3); - scale.sample(scale.numColors(), m_cmap.data()); + m_cmap.resize(SAMPLES * 3); + scale->sample(SAMPLES, m_cmap.data()); if (m_orientation == Colormap::Vertical) { reverseCMap(m_cmap); } diff --git a/colormap.h b/colormap.h index eda4492..1039cfd 100644 --- a/colormap.h +++ b/colormap.h @@ -31,11 +31,11 @@ public: Orientation orientation() const { return m_orientation; } signals: - void colorScaleChanged(const ColorScale &scale) const; + void colorScaleChanged(const ColorScale *scale) const; void orientationChanged(Orientation orientation) const; public slots: - void setColorScale(const ColorScale &scale); + void setColorScale(const ColorScale *scale); protected: QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *); diff --git a/colorscale.cpp b/colorscale.cpp index 06852d4..f41e7d9 100644 --- a/colorscale.cpp +++ b/colorscale.cpp @@ -32,7 +32,7 @@ void ColorScale::setExtents(float min, float max) m_max = max; } -static QColor lerp(const QColor &c1, const QColor &c2, float _t) +QColor ColorScale::lerp(const QColor &c1, const QColor &c2, float _t) { qreal r1, g1, b1, a1; qreal r2, g2, b2, a2; diff --git a/colorscale.h b/colorscale.h index 1eb8c47..ffc3439 100644 --- a/colorscale.h +++ b/colorscale.h @@ -25,6 +25,8 @@ public: template void sample(int samples, OutputIterator it) const; + static QColor lerp(const QColor &c1, const QColor &c2, float _t); + protected: float m_min, m_max; QList m_colors; diff --git a/continuouscolorscale.cpp b/continuouscolorscale.cpp index 392dd47..3b41b81 100644 --- a/continuouscolorscale.cpp +++ b/continuouscolorscale.cpp @@ -7,10 +7,11 @@ ContinuousColorScale::ContinuousColorScale(std::initializer_list colors) { } -QColor ContinuousColorScale::color(qreal t) const +QColor ContinuousColorScale::color(float t) const { - if (t < m_min || t > m_max) + if (t < m_min || t > m_max) { return QColor(); + } // normalize t t = (t - m_min) / (m_max - m_min); @@ -291,265 +292,6 @@ ContinuousColorScale ContinuousColorScale::builtin(BuiltinContinuousColorScale s QColor(255, 255, 247), QColor(255, 255, 255) }; - case RedGrayBlue: - return ContinuousColorScale{ - QColor(221, 68, 68), - QColor(220, 69, 68), - QColor(220, 70, 69), - QColor(220, 71, 70), - QColor(220, 73, 71), - QColor(220, 74, 72), - QColor(220, 75, 73), - QColor(220, 77, 74), - QColor(220, 78, 75), - QColor(220, 79, 76), - QColor(220, 80, 76), - QColor(220, 81, 77), - QColor(220, 83, 78), - QColor(220, 84, 79), - QColor(220, 85, 80), - QColor(220, 86, 81), - QColor(220, 87, 82), - QColor(220, 88, 83), - QColor(220, 89, 84), - QColor(220, 91, 85), - QColor(220, 92, 85), - QColor(220, 93, 86), - QColor(220, 94, 87), - QColor(220, 95, 88), - QColor(220, 96, 89), - QColor(220, 97, 90), - QColor(220, 98, 91), - QColor(219, 99, 92), - QColor(219, 100, 93), - QColor(219, 101, 94), - QColor(219, 102, 95), - QColor(219, 103, 95), - QColor(219, 104, 96), - QColor(219, 105, 97), - QColor(219, 106, 98), - QColor(219, 107, 99), - QColor(219, 108, 100), - QColor(218, 109, 101), - QColor(218, 110, 102), - QColor(218, 111, 103), - QColor(218, 112, 104), - QColor(218, 113, 105), - QColor(218, 114, 106), - QColor(218, 115, 107), - QColor(218, 116, 108), - QColor(217, 117, 108), - QColor(217, 118, 109), - QColor(217, 119, 110), - QColor(217, 120, 111), - QColor(217, 121, 112), - QColor(217, 122, 113), - QColor(217, 123, 114), - QColor(216, 124, 115), - QColor(216, 125, 116), - QColor(216, 126, 117), - QColor(216, 127, 118), - QColor(216, 127, 119), - QColor(215, 128, 120), - QColor(215, 129, 121), - QColor(215, 130, 122), - QColor(215, 131, 123), - QColor(215, 132, 124), - QColor(214, 133, 125), - QColor(214, 134, 126), - QColor(214, 135, 127), - QColor(214, 136, 127), - QColor(214, 137, 128), - QColor(213, 138, 129), - QColor(213, 138, 130), - QColor(213, 139, 131), - QColor(213, 140, 132), - QColor(212, 141, 133), - QColor(212, 142, 134), - QColor(212, 143, 135), - QColor(212, 144, 136), - QColor(211, 145, 137), - QColor(211, 146, 138), - QColor(211, 146, 139), - QColor(211, 147, 140), - QColor(210, 148, 141), - QColor(210, 149, 142), - QColor(210, 150, 143), - QColor(209, 151, 144), - QColor(209, 152, 145), - QColor(209, 153, 146), - QColor(208, 153, 147), - QColor(208, 154, 148), - QColor(208, 155, 149), - QColor(207, 156, 150), - QColor(207, 157, 151), - QColor(207, 158, 152), - QColor(206, 159, 153), - QColor(206, 160, 154), - QColor(206, 160, 155), - QColor(205, 161, 156), - QColor(205, 162, 157), - QColor(205, 163, 158), - QColor(204, 164, 159), - QColor(204, 165, 160), - QColor(203, 166, 161), - QColor(203, 166, 162), - QColor(203, 167, 163), - QColor(202, 168, 164), - QColor(202, 169, 165), - QColor(201, 170, 166), - QColor(201, 171, 167), - QColor(201, 171, 168), - QColor(200, 172, 169), - QColor(200, 173, 170), - QColor(199, 174, 171), - QColor(199, 175, 172), - QColor(198, 176, 173), - QColor(198, 177, 174), - QColor(197, 177, 175), - QColor(197, 178, 176), - QColor(196, 179, 177), - QColor(196, 180, 178), - QColor(195, 181, 179), - QColor(195, 182, 180), - QColor(194, 182, 181), - QColor(194, 183, 182), - QColor(193, 184, 183), - QColor(193, 185, 184), - QColor(192, 186, 185), - QColor(192, 187, 186), - QColor(191, 187, 187), - QColor(190, 188, 188), - QColor(190, 189, 189), - QColor(189, 189, 190), - QColor(189, 188, 190), - QColor(188, 187, 190), - QColor(187, 186, 191), - QColor(187, 185, 191), - QColor(186, 184, 191), - QColor(185, 183, 191), - QColor(185, 182, 192), - QColor(184, 181, 192), - QColor(184, 180, 192), - QColor(183, 179, 193), - QColor(182, 178, 193), - QColor(182, 177, 193), - QColor(181, 176, 194), - QColor(180, 175, 194), - QColor(180, 174, 194), - QColor(179, 173, 194), - QColor(178, 172, 195), - QColor(178, 171, 195), - QColor(177, 170, 195), - QColor(176, 169, 196), - QColor(176, 168, 196), - QColor(175, 167, 196), - QColor(174, 166, 196), - QColor(174, 165, 197), - QColor(173, 164, 197), - QColor(172, 163, 197), - QColor(172, 162, 197), - QColor(171, 161, 198), - QColor(170, 160, 198), - QColor(170, 159, 198), - QColor(169, 158, 199), - QColor(168, 157, 199), - QColor(167, 156, 199), - QColor(167, 155, 199), - QColor(166, 155, 200), - QColor(165, 154, 200), - QColor(165, 153, 200), - QColor(164, 152, 200), - QColor(163, 151, 201), - QColor(162, 150, 201), - QColor(162, 149, 201), - QColor(161, 148, 201), - QColor(160, 147, 202), - QColor(159, 146, 202), - QColor(159, 145, 202), - QColor(158, 144, 202), - QColor(157, 143, 203), - QColor(156, 142, 203), - QColor(155, 141, 203), - QColor(155, 140, 203), - QColor(154, 139, 204), - QColor(153, 138, 204), - QColor(152, 137, 204), - QColor(152, 136, 204), - QColor(151, 135, 205), - QColor(150, 134, 205), - QColor(149, 133, 205), - QColor(148, 132, 205), - QColor(147, 131, 206), - QColor(147, 130, 206), - QColor(146, 129, 206), - QColor(145, 128, 206), - QColor(144, 128, 207), - QColor(143, 127, 207), - QColor(142, 126, 207), - QColor(142, 125, 207), - QColor(141, 124, 208), - QColor(140, 123, 208), - QColor(139, 122, 208), - QColor(138, 121, 208), - QColor(137, 120, 209), - QColor(136, 119, 209), - QColor(135, 118, 209), - QColor(134, 117, 209), - QColor(133, 116, 209), - QColor(133, 115, 210), - QColor(132, 114, 210), - QColor(131, 113, 210), - QColor(130, 112, 210), - QColor(129, 111, 211), - QColor(128, 110, 211), - QColor(127, 109, 211), - QColor(126, 109, 211), - QColor(125, 108, 212), - QColor(124, 107, 212), - QColor(123, 106, 212), - QColor(122, 105, 212), - QColor(121, 104, 212), - QColor(120, 103, 213), - QColor(119, 102, 213), - QColor(118, 101, 213), - QColor(117, 100, 213), - QColor(115, 99, 213), - QColor(114, 98, 214), - QColor(113, 97, 214), - QColor(112, 96, 214), - QColor(111, 95, 214), - QColor(110, 94, 215), - QColor(109, 94, 215), - QColor(108, 93, 215), - QColor(106, 92, 215), - QColor(105, 91, 215), - QColor(104, 90, 216), - QColor(103, 89, 216), - QColor(101, 88, 216), - QColor(100, 87, 216), - QColor( 99, 86, 216), - QColor( 98, 85, 217), - QColor( 96, 84, 217), - QColor( 95, 83, 217), - QColor( 94, 82, 217), - QColor( 92, 81, 217), - QColor( 91, 80, 218), - QColor( 89, 80, 218), - QColor( 88, 79, 218), - QColor( 86, 78, 218), - QColor( 85, 77, 219), - QColor( 83, 76, 219), - QColor( 82, 75, 219), - QColor( 80, 74, 219), - QColor( 78, 73, 219), - QColor( 77, 72, 220), - QColor( 75, 71, 220), - QColor( 73, 70, 220), - QColor( 71, 69, 220), - QColor( 69, 68, 220), - QColor( 68, 68, 221) - }; case Rainbow: return ContinuousColorScale{ QColor( 0, 0, 0), @@ -813,3 +555,529 @@ ContinuousColorScale ContinuousColorScale::builtin(BuiltinContinuousColorScale s return ContinuousColorScale::builtin(ContinuousColorScale::HeatedObjects); } } + +ContinuousColorScale *ContinuousColorScale::builtin(BuiltinContinuousColorScale scale, void *) +{ + switch (scale) { + case HeatedObjects: + return new ContinuousColorScale{ + 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) + }; + case Rainbow: + return new ContinuousColorScale{ + QColor( 0, 0, 0), + QColor( 45, 0, 36), + QColor( 56, 0, 46), + QColor( 60, 0, 49), + QColor( 67, 0, 54), + QColor( 70, 0, 59), + QColor( 71, 0, 61), + QColor( 75, 0, 68), + QColor( 74, 0, 73), + QColor( 74, 0, 77), + QColor( 73, 0, 81), + QColor( 71, 0, 87), + QColor( 69, 1, 90), + QColor( 68, 2, 94), + QColor( 66, 3, 97), + QColor( 63, 6, 102), + QColor( 61, 7, 106), + QColor( 58, 10, 109), + QColor( 56, 12, 113), + QColor( 53, 15, 116), + QColor( 48, 18, 119), + QColor( 47, 20, 121), + QColor( 44, 23, 124), + QColor( 41, 27, 128), + QColor( 40, 28, 129), + QColor( 37, 32, 132), + QColor( 34, 36, 134), + QColor( 29, 43, 137), + QColor( 25, 52, 138), + QColor( 24, 57, 139), + QColor( 24, 62, 141), + QColor( 24, 64, 142), + QColor( 23, 65, 142), + QColor( 23, 69, 143), + QColor( 23, 71, 142), + QColor( 23, 71, 142), + QColor( 23, 73, 142), + QColor( 23, 75, 142), + QColor( 23, 75, 142), + QColor( 23, 78, 142), + QColor( 23, 80, 142), + QColor( 23, 80, 142), + QColor( 23, 82, 141), + QColor( 23, 85, 141), + QColor( 23, 85, 141), + QColor( 23, 87, 140), + QColor( 23, 87, 140), + QColor( 24, 90, 140), + QColor( 24, 90, 140), + QColor( 24, 93, 139), + QColor( 24, 93, 139), + QColor( 24, 93, 139), + QColor( 24, 93, 139), + QColor( 24, 97, 139), + QColor( 24, 97, 139), + QColor( 25, 101, 138), + QColor( 25, 101, 138), + QColor( 25, 104, 137), + QColor( 25, 104, 137), + QColor( 25, 104, 137), + QColor( 26, 108, 137), + QColor( 26, 108, 137), + QColor( 27, 111, 136), + QColor( 27, 111, 136), + QColor( 27, 111, 136), + QColor( 27, 115, 135), + QColor( 27, 115, 135), + QColor( 28, 118, 134), + QColor( 28, 118, 134), + QColor( 29, 122, 133), + QColor( 29, 122, 133), + QColor( 29, 122, 133), + QColor( 29, 122, 133), + QColor( 29, 125, 132), + QColor( 29, 125, 132), + QColor( 30, 128, 131), + QColor( 30, 128, 131), + QColor( 31, 131, 130), + QColor( 31, 131, 130), + QColor( 31, 131, 130), + QColor( 32, 134, 128), + QColor( 32, 134, 128), + QColor( 33, 137, 127), + QColor( 33, 137, 127), + QColor( 33, 137, 127), + QColor( 34, 140, 125), + QColor( 34, 140, 125), + QColor( 35, 142, 123), + QColor( 35, 142, 123), + QColor( 36, 145, 121), + QColor( 36, 145, 121), + QColor( 36, 145, 121), + QColor( 37, 147, 118), + QColor( 37, 147, 118), + QColor( 38, 150, 116), + QColor( 38, 150, 116), + QColor( 40, 152, 113), + QColor( 40, 152, 113), + QColor( 41, 154, 111), + QColor( 41, 154, 111), + QColor( 42, 156, 108), + QColor( 42, 156, 108), + QColor( 43, 158, 106), + QColor( 43, 158, 106), + QColor( 43, 158, 106), + QColor( 45, 160, 104), + QColor( 45, 160, 104), + QColor( 46, 162, 101), + QColor( 46, 162, 101), + QColor( 48, 164, 99), + QColor( 48, 164, 99), + QColor( 50, 166, 97), + QColor( 50, 166, 97), + QColor( 51, 168, 95), + QColor( 53, 170, 93), + QColor( 53, 170, 93), + QColor( 53, 170, 93), + QColor( 55, 172, 91), + QColor( 55, 172, 91), + QColor( 57, 174, 88), + QColor( 57, 174, 88), + QColor( 59, 175, 86), + QColor( 62, 177, 84), + QColor( 64, 178, 82), + QColor( 64, 178, 82), + QColor( 67, 180, 80), + QColor( 67, 180, 80), + QColor( 69, 181, 79), + QColor( 72, 183, 77), + QColor( 72, 183, 77), + QColor( 72, 183, 77), + QColor( 75, 184, 76), + QColor( 77, 186, 74), + QColor( 80, 187, 73), + QColor( 83, 189, 72), + QColor( 87, 190, 72), + QColor( 91, 191, 71), + QColor( 95, 192, 70), + QColor( 99, 193, 70), + QColor(103, 194, 70), + QColor(107, 195, 70), + QColor(111, 196, 70), + QColor(111, 196, 70), + QColor(115, 196, 70), + QColor(119, 197, 70), + QColor(123, 197, 70), + QColor(130, 198, 71), + QColor(133, 199, 71), + QColor(137, 199, 72), + QColor(140, 199, 72), + QColor(143, 199, 73), + QColor(143, 199, 73), + QColor(147, 199, 73), + QColor(150, 199, 74), + QColor(153, 199, 74), + QColor(156, 199, 75), + QColor(160, 200, 76), + QColor(167, 200, 78), + QColor(170, 200, 79), + QColor(173, 200, 79), + QColor(173, 200, 79), + QColor(177, 200, 80), + QColor(180, 200, 81), + QColor(183, 199, 82), + QColor(186, 199, 82), + QColor(190, 199, 83), + QColor(196, 199, 85), + QColor(199, 198, 85), + QColor(199, 198, 85), + QColor(203, 198, 86), + QColor(206, 197, 87), + QColor(212, 197, 89), + QColor(215, 196, 90), + QColor(218, 195, 91), + QColor(224, 194, 94), + QColor(224, 194, 94), + QColor(230, 193, 96), + QColor(233, 192, 98), + QColor(236, 190, 100), + QColor(238, 189, 104), + QColor(240, 188, 106), + QColor(240, 188, 106), + QColor(242, 187, 110), + QColor(244, 185, 114), + QColor(245, 184, 116), + QColor(247, 183, 120), + QColor(248, 182, 123), + QColor(248, 182, 123), + QColor(250, 181, 125), + QColor(251, 180, 128), + QColor(252, 180, 130), + QColor(253, 180, 133), + QColor(253, 180, 133), + QColor(254, 180, 134), + QColor(254, 179, 138), + QColor(255, 179, 142), + QColor(255, 179, 145), + QColor(255, 179, 145), + QColor(255, 179, 152), + QColor(255, 180, 161), + QColor(255, 180, 164), + QColor(255, 180, 167), + QColor(255, 180, 167), + QColor(255, 181, 169), + QColor(255, 181, 170), + QColor(255, 182, 173), + QColor(255, 183, 176), + QColor(255, 183, 176), + QColor(255, 184, 179), + QColor(255, 185, 179), + QColor(255, 185, 182), + QColor(255, 186, 182), + QColor(255, 186, 182), + QColor(255, 187, 185), + QColor(255, 188, 185), + QColor(255, 189, 188), + QColor(255, 189, 188), + QColor(255, 190, 188), + QColor(255, 191, 191), + QColor(255, 192, 191), + QColor(255, 194, 194), + QColor(255, 194, 194), + QColor(255, 197, 197), + QColor(255, 198, 198), + QColor(255, 200, 200), + QColor(255, 201, 201), + QColor(255, 201, 201), + QColor(255, 202, 202), + QColor(255, 203, 203), + QColor(255, 205, 205), + QColor(255, 206, 206), + QColor(255, 206, 206), + QColor(255, 208, 208), + QColor(255, 209, 209), + QColor(255, 211, 211), + QColor(255, 215, 215), + QColor(255, 216, 216), + QColor(255, 216, 216), + QColor(255, 218, 218), + QColor(255, 219, 219), + QColor(255, 221, 221), + QColor(255, 223, 223), + QColor(255, 226, 226), + QColor(255, 228, 228), + QColor(255, 230, 230), + QColor(255, 230, 230), + QColor(255, 232, 232), + QColor(255, 235, 235), + QColor(255, 237, 237), + QColor(255, 240, 240), + QColor(255, 243, 243), + QColor(255, 246, 246), + QColor(255, 249, 249), + QColor(255, 251, 251), + QColor(255, 253, 253), + QColor(255, 255, 255) + }; + default: + return ContinuousColorScale::builtin(ContinuousColorScale::HeatedObjects, nullptr); + } +} diff --git a/continuouscolorscale.h b/continuouscolorscale.h index fee17ed..f15abc6 100644 --- a/continuouscolorscale.h +++ b/continuouscolorscale.h @@ -11,13 +11,13 @@ public: enum BuiltinContinuousColorScale { HeatedObjects, - RedGrayBlue, Rainbow, }; - QColor color(qreal t) const; + QColor color(float t) const; - static ContinuousColorScale builtin(enum BuiltinContinuousColorScale); + static ContinuousColorScale builtin(BuiltinContinuousColorScale); + static ContinuousColorScale *builtin(BuiltinContinuousColorScale, void *); }; #endif // CONTINUOUSCOLORSCALE_H diff --git a/divergentcolorscale.cpp b/divergentcolorscale.cpp new file mode 100644 index 0000000..8396d72 --- /dev/null +++ b/divergentcolorscale.cpp @@ -0,0 +1,313 @@ +#include "divergentcolorscale.h" + +#include + +#include + +DivergentColorScale::DivergentColorScale(const QColor &color1, + const QColor &colorMiddle, + const QColor &color2) + : ColorScale{{color1, colorMiddle, color2}} +{ +} + +QColor DivergentColorScale::color(float t) const +{ + if (t < m_min || t > m_max) { + return QColor(); + } + + // normalize t + t /= std::max(fabs(m_max), fabs(m_min)); + + if (t > 0.0f) { + return ColorScale::lerp(m_colors[1], m_colors[2], t); + } + if (t < 0.0f) { + return ColorScale::lerp(m_colors[1], m_colors[0], -t); + } + return m_colors[1]; +} + +DivergentColorScale DivergentColorScale::builtin(BuiltinDivergentColorScale scale) +{ + switch (scale) { + case RedGrayBlue: + return DivergentColorScale(QColor(68, 68, 221), + QColor(189, 189, 189), + QColor(221, 68, 68)); + /*return ContinuousColorScale{ + QColor(221, 68, 68), + QColor(220, 69, 68), + QColor(220, 70, 69), + QColor(220, 71, 70), + QColor(220, 73, 71), + QColor(220, 74, 72), + QColor(220, 75, 73), + QColor(220, 77, 74), + QColor(220, 78, 75), + QColor(220, 79, 76), + QColor(220, 80, 76), + QColor(220, 81, 77), + QColor(220, 83, 78), + QColor(220, 84, 79), + QColor(220, 85, 80), + QColor(220, 86, 81), + QColor(220, 87, 82), + QColor(220, 88, 83), + QColor(220, 89, 84), + QColor(220, 91, 85), + QColor(220, 92, 85), + QColor(220, 93, 86), + QColor(220, 94, 87), + QColor(220, 95, 88), + QColor(220, 96, 89), + QColor(220, 97, 90), + QColor(220, 98, 91), + QColor(219, 99, 92), + QColor(219, 100, 93), + QColor(219, 101, 94), + QColor(219, 102, 95), + QColor(219, 103, 95), + QColor(219, 104, 96), + QColor(219, 105, 97), + QColor(219, 106, 98), + QColor(219, 107, 99), + QColor(219, 108, 100), + QColor(218, 109, 101), + QColor(218, 110, 102), + QColor(218, 111, 103), + QColor(218, 112, 104), + QColor(218, 113, 105), + QColor(218, 114, 106), + QColor(218, 115, 107), + QColor(218, 116, 108), + QColor(217, 117, 108), + QColor(217, 118, 109), + QColor(217, 119, 110), + QColor(217, 120, 111), + QColor(217, 121, 112), + QColor(217, 122, 113), + QColor(217, 123, 114), + QColor(216, 124, 115), + QColor(216, 125, 116), + QColor(216, 126, 117), + QColor(216, 127, 118), + QColor(216, 127, 119), + QColor(215, 128, 120), + QColor(215, 129, 121), + QColor(215, 130, 122), + QColor(215, 131, 123), + QColor(215, 132, 124), + QColor(214, 133, 125), + QColor(214, 134, 126), + QColor(214, 135, 127), + QColor(214, 136, 127), + QColor(214, 137, 128), + QColor(213, 138, 129), + QColor(213, 138, 130), + QColor(213, 139, 131), + QColor(213, 140, 132), + QColor(212, 141, 133), + QColor(212, 142, 134), + QColor(212, 143, 135), + QColor(212, 144, 136), + QColor(211, 145, 137), + QColor(211, 146, 138), + QColor(211, 146, 139), + QColor(211, 147, 140), + QColor(210, 148, 141), + QColor(210, 149, 142), + QColor(210, 150, 143), + QColor(209, 151, 144), + QColor(209, 152, 145), + QColor(209, 153, 146), + QColor(208, 153, 147), + QColor(208, 154, 148), + QColor(208, 155, 149), + QColor(207, 156, 150), + QColor(207, 157, 151), + QColor(207, 158, 152), + QColor(206, 159, 153), + QColor(206, 160, 154), + QColor(206, 160, 155), + QColor(205, 161, 156), + QColor(205, 162, 157), + QColor(205, 163, 158), + QColor(204, 164, 159), + QColor(204, 165, 160), + QColor(203, 166, 161), + QColor(203, 166, 162), + QColor(203, 167, 163), + QColor(202, 168, 164), + QColor(202, 169, 165), + QColor(201, 170, 166), + QColor(201, 171, 167), + QColor(201, 171, 168), + QColor(200, 172, 169), + QColor(200, 173, 170), + QColor(199, 174, 171), + QColor(199, 175, 172), + QColor(198, 176, 173), + QColor(198, 177, 174), + QColor(197, 177, 175), + QColor(197, 178, 176), + QColor(196, 179, 177), + QColor(196, 180, 178), + QColor(195, 181, 179), + QColor(195, 182, 180), + QColor(194, 182, 181), + QColor(194, 183, 182), + QColor(193, 184, 183), + QColor(193, 185, 184), + QColor(192, 186, 185), + QColor(192, 187, 186), + QColor(191, 187, 187), + QColor(190, 188, 188), + QColor(190, 189, 189), + QColor(189, 189, 190), + QColor(189, 188, 190), + QColor(188, 187, 190), + QColor(187, 186, 191), + QColor(187, 185, 191), + QColor(186, 184, 191), + QColor(185, 183, 191), + QColor(185, 182, 192), + QColor(184, 181, 192), + QColor(184, 180, 192), + QColor(183, 179, 193), + QColor(182, 178, 193), + QColor(182, 177, 193), + QColor(181, 176, 194), + QColor(180, 175, 194), + QColor(180, 174, 194), + QColor(179, 173, 194), + QColor(178, 172, 195), + QColor(178, 171, 195), + QColor(177, 170, 195), + QColor(176, 169, 196), + QColor(176, 168, 196), + QColor(175, 167, 196), + QColor(174, 166, 196), + QColor(174, 165, 197), + QColor(173, 164, 197), + QColor(172, 163, 197), + QColor(172, 162, 197), + QColor(171, 161, 198), + QColor(170, 160, 198), + QColor(170, 159, 198), + QColor(169, 158, 199), + QColor(168, 157, 199), + QColor(167, 156, 199), + QColor(167, 155, 199), + QColor(166, 155, 200), + QColor(165, 154, 200), + QColor(165, 153, 200), + QColor(164, 152, 200), + QColor(163, 151, 201), + QColor(162, 150, 201), + QColor(162, 149, 201), + QColor(161, 148, 201), + QColor(160, 147, 202), + QColor(159, 146, 202), + QColor(159, 145, 202), + QColor(158, 144, 202), + QColor(157, 143, 203), + QColor(156, 142, 203), + QColor(155, 141, 203), + QColor(155, 140, 203), + QColor(154, 139, 204), + QColor(153, 138, 204), + QColor(152, 137, 204), + QColor(152, 136, 204), + QColor(151, 135, 205), + QColor(150, 134, 205), + QColor(149, 133, 205), + QColor(148, 132, 205), + QColor(147, 131, 206), + QColor(147, 130, 206), + QColor(146, 129, 206), + QColor(145, 128, 206), + QColor(144, 128, 207), + QColor(143, 127, 207), + QColor(142, 126, 207), + QColor(142, 125, 207), + QColor(141, 124, 208), + QColor(140, 123, 208), + QColor(139, 122, 208), + QColor(138, 121, 208), + QColor(137, 120, 209), + QColor(136, 119, 209), + QColor(135, 118, 209), + QColor(134, 117, 209), + QColor(133, 116, 209), + QColor(133, 115, 210), + QColor(132, 114, 210), + QColor(131, 113, 210), + QColor(130, 112, 210), + QColor(129, 111, 211), + QColor(128, 110, 211), + QColor(127, 109, 211), + QColor(126, 109, 211), + QColor(125, 108, 212), + QColor(124, 107, 212), + QColor(123, 106, 212), + QColor(122, 105, 212), + QColor(121, 104, 212), + QColor(120, 103, 213), + QColor(119, 102, 213), + QColor(118, 101, 213), + QColor(117, 100, 213), + QColor(115, 99, 213), + QColor(114, 98, 214), + QColor(113, 97, 214), + QColor(112, 96, 214), + QColor(111, 95, 214), + QColor(110, 94, 215), + QColor(109, 94, 215), + QColor(108, 93, 215), + QColor(106, 92, 215), + QColor(105, 91, 215), + QColor(104, 90, 216), + QColor(103, 89, 216), + QColor(101, 88, 216), + QColor(100, 87, 216), + QColor( 99, 86, 216), + QColor( 98, 85, 217), + QColor( 96, 84, 217), + QColor( 95, 83, 217), + QColor( 94, 82, 217), + QColor( 92, 81, 217), + QColor( 91, 80, 218), + QColor( 89, 80, 218), + QColor( 88, 79, 218), + QColor( 86, 78, 218), + QColor( 85, 77, 219), + QColor( 83, 76, 219), + QColor( 82, 75, 219), + QColor( 80, 74, 219), + QColor( 78, 73, 219), + QColor( 77, 72, 220), + QColor( 75, 71, 220), + QColor( 73, 70, 220), + QColor( 71, 69, 220), + QColor( 69, 68, 220), + QColor( 68, 68, 221) + };*/ + default: + return DivergentColorScale::builtin(DivergentColorScale::RedGrayBlue); + } +} + + +DivergentColorScale *DivergentColorScale::builtin(BuiltinDivergentColorScale scale, void *) +{ + switch (scale) { + case RedGrayBlue: + return new DivergentColorScale(QColor(68, 68, 221), + QColor(189, 189, 189), + QColor(221, 68, 68)); + default: + return DivergentColorScale::builtin(DivergentColorScale::RedGrayBlue, nullptr); + } +} diff --git a/divergentcolorscale.h b/divergentcolorscale.h new file mode 100644 index 0000000..9ab3be6 --- /dev/null +++ b/divergentcolorscale.h @@ -0,0 +1,24 @@ +#ifndef DIVERGENTCOLORSCALE_H +#define DIVERGENTCOLORSCALE_H + +#include "colorscale.h" + +class DivergentColorScale + : public ColorScale +{ +public: + DivergentColorScale(const QColor &color1, + const QColor &colorMiddle, + const QColor &color2); + + enum BuiltinDivergentColorScale { + RedGrayBlue + }; + + QColor color(float t) const; + + static DivergentColorScale builtin(BuiltinDivergentColorScale); + static DivergentColorScale *builtin(BuiltinDivergentColorScale, void *); +}; + +#endif // DIVERGENTCOLORSCALE_H diff --git a/main.cpp b/main.cpp index 235f036..3417534 100644 --- a/main.cpp +++ b/main.cpp @@ -170,7 +170,7 @@ int main(int argc, char **argv) // Update projection as the cp are modified (either directly in the // manipulationHandler object or interactively in cpPlot - ManipulationHandler manipulationHandler(X, cpIndices, m->projectionHistory); + ManipulationHandler manipulationHandler(X, cpIndices); QObject::connect(m->cpPlot, &Scatterplot::xyInteractivelyChanged, &manipulationHandler, &ManipulationHandler::setCP); @@ -237,6 +237,33 @@ int main(int argc, char **argv) m->rpBarChart, &BarChart::brushItem); // Update visual components whenever values change + QObject::connect(m->projectionHistory, &ProjectionHistory::rpValuesChanged, + [m](const arma::vec &v, bool rescale) { + ColorScale *ptr = m->colorScaleRPs.get(); + if (!ptr || v.n_elem == 0) { + return; + } + + if (rescale) { + ptr->setExtents(v.min(), v.max()); + } else { + ptr->setExtents(std::min(ptr->min(), (float) v.min()), + std::max(ptr->max(), (float) v.max())); + } + + m->splat->setColorScale(ptr); + m->rpColormap->setColorScale(ptr); + }); + QObject::connect(m->projectionHistory, &ProjectionHistory::cpValuesChanged, + [m](const arma::vec &v) { + ColorScale *ptr = m->colorScaleCPs.get(); + if (!ptr || v.n_elem == 0) { + return; + } + + ptr->setExtents(v.min(), v.max()); + m->cpColormap->setColorScale(ptr); + }); QObject::connect(m->projectionHistory, &ProjectionHistory::cpValuesChanged, m->cpPlot, &Scatterplot::setColorData); QObject::connect(m->projectionHistory, &ProjectionHistory::rpValuesChanged, diff --git a/main.h b/main.h index b09b3b0..830c742 100644 --- a/main.h +++ b/main.h @@ -3,9 +3,11 @@ #include #include +#include #include "colorscale.h" #include "continuouscolorscale.h" +#include "divergentcolorscale.h" #include "projectionhistory.h" #include "numericrange.h" #include "barchart.h" @@ -82,27 +84,36 @@ public: ColorScaleRainbow }; - // No need to be static: this class is a singleton - ColorScale COLOR_SCALE_CATEGORICAL; - ColorScale COLOR_SCALE_CONTINUOUS; - ColorScale COLOR_SCALE_DIVERGENT; - ColorScale COLOR_SCALE_RAINBOW; - Q_INVOKABLE void setCPColorScale(ColorScaleType colorScaleType) { - ColorScale &scale = getColorScale(colorScaleType); + ColorScale *ptr = colorScaleCPs.get(); + float min = ptr != nullptr ? ptr->min() : 0.0f; + float max = ptr != nullptr ? ptr->max() : 1.0f; + + ptr = getColorScale(colorScaleType); + ptr->setExtents(min, max); + colorScaleCPs.reset(ptr); - cpPlot->setColorScale(scale); - cpBarChart->setColorScale(scale); - cpColormap->setColorScale(scale); + cpPlot->setColorScale(colorScaleCPs.get()); + cpBarChart->setColorScale(colorScaleCPs.get()); + cpColormap->setColorScale(colorScaleCPs.get()); } Q_INVOKABLE void setRPColorScale(ColorScaleType colorScaleType) { - ColorScale &scale = getColorScale(colorScaleType); + ColorScale *ptr = colorScaleCPs.get(); + float min = 0.0f; + float max = 1.0f; + if (ptr) { + min = ptr->min(); + max = ptr->max(); + } + ptr = getColorScale(colorScaleType); + ptr->setExtents(min, max); + colorScaleRPs.reset(ptr); - rpPlot->setColorScale(scale); - splat->setColorScale(scale); - rpBarChart->setColorScale(scale); - rpColormap->setColorScale(scale); + rpPlot->setColorScale(colorScaleRPs.get()); + splat->setColorScale(colorScaleRPs.get()); + rpBarChart->setColorScale(colorScaleRPs.get()); + rpColormap->setColorScale(colorScaleRPs.get()); } // Pointers to visual components whose values are set in the main() function @@ -112,6 +123,9 @@ public: Scatterplot *cpPlot, *rpPlot; VoronoiSplat *splat; + // Color scales in use + std::unique_ptr colorScaleCPs, colorScaleRPs; + // Object that controls manipulation history ProjectionHistory *projectionHistory; @@ -167,14 +181,6 @@ public slots: private: Main(QObject *parent = 0) : QObject(parent) - , COLOR_SCALE_CATEGORICAL{{ - QColor("#1f77b4"), QColor("#ff7f0e"), QColor("#2ca02c"), - QColor("#d62728"), QColor("#9467bd"), QColor("#8c564b"), - QColor("#e377c2"), QColor("#17becf"), QColor("#7f7f7f"), - }} - , COLOR_SCALE_CONTINUOUS{ContinuousColorScale::builtin(ContinuousColorScale::HeatedObjects)} - , COLOR_SCALE_DIVERGENT{ContinuousColorScale::builtin(ContinuousColorScale::RedGrayBlue)} - , COLOR_SCALE_RAINBOW{ContinuousColorScale::builtin(ContinuousColorScale::Rainbow)} , cpBarChart(0) , rpBarChart(0) , cpColormap(0) @@ -188,18 +194,25 @@ private: ~Main() {} - ColorScale &getColorScale(ColorScaleType colorScaleType) { + ColorScale *getColorScale(ColorScaleType colorScaleType) { switch (colorScaleType) { case ColorScaleCategorical: - return COLOR_SCALE_CATEGORICAL; + return new ColorScale{ + QColor("#1f77b4"), QColor("#ff7f0e"), QColor("#2ca02c"), + QColor("#d62728"), QColor("#9467bd"), QColor("#8c564b"), + QColor("#e377c2"), QColor("#17becf"), QColor("#7f7f7f"), + }; case ColorScaleContinuous: - return COLOR_SCALE_CONTINUOUS; + return ContinuousColorScale::builtin( + ContinuousColorScale::HeatedObjects, nullptr); case ColorScaleDivergent: - return COLOR_SCALE_DIVERGENT; + return DivergentColorScale::builtin( + DivergentColorScale::RedGrayBlue, nullptr); case ColorScaleRainbow: // fall-through default: - return COLOR_SCALE_RAINBOW; + return ContinuousColorScale::builtin( + ContinuousColorScale::Rainbow, nullptr); } } diff --git a/main_view.qml b/main_view.qml index 6cd54ae..900969e 100644 --- a/main_view.qml +++ b/main_view.qml @@ -474,26 +474,34 @@ ApplicationWindow { placeholderText: "Enter prefix" } - onAccepted: { - var prefix = prefixTextField.text; - if (prefix.length == 0) { - prefix = "screenshot"; - } + Timer { + id: screenshotTimer + interval: 500 + running: false + repeat: false + onTriggered: { + var prefix = prefixTextField.text; + if (prefix.length == 0) { + prefix = "screenshot"; + } - mainView.grabToImage(function(result) { - result.saveToFile(prefix + "-main.png"); - }); + mainView.grabToImage(function(result) { + result.saveToFile(prefix + "-main.png"); + }); - bottomViewCP.grabToImage(function(result) { - result.saveToFile(prefix + "-bottom-cp.png"); - }); + bottomViewCP.grabToImage(function(result) { + result.saveToFile(prefix + "-bottom-cp.png"); + }); - bottomViewRP.grabToImage(function(result) { - result.saveToFile(prefix + "-bottom-rp.png"); - }); + bottomViewRP.grabToImage(function(result) { + result.saveToFile(prefix + "-bottom-rp.png"); + }); - prefixTextField.text = ""; + prefixTextField.text = ""; + } } + + onAccepted: screenshotTimer.start() } Action { diff --git a/manipulationhandler.cpp b/manipulationhandler.cpp index daaba01..89aa968 100644 --- a/manipulationhandler.cpp +++ b/manipulationhandler.cpp @@ -5,14 +5,11 @@ #include "mp.h" ManipulationHandler::ManipulationHandler(const arma::mat &X, - const arma::uvec &cpIndices, - ProjectionHistory *history) + const arma::uvec &cpIndices) : m_X(X) , m_cpIndices(cpIndices) - , m_history(history) , m_technique(TECHNIQUE_LAMP) { - Q_ASSERT(history); } void ManipulationHandler::setCP(const arma::mat &Ys) diff --git a/manipulationhandler.h b/manipulationhandler.h index 9199c93..c208460 100644 --- a/manipulationhandler.h +++ b/manipulationhandler.h @@ -4,8 +4,6 @@ #include #include -#include "projectionhistory.h" - class ManipulationHandler : public QObject { @@ -20,8 +18,7 @@ public: }; ManipulationHandler(const arma::mat &X, - const arma::uvec &cpIndices, - ProjectionHistory *history); + const arma::uvec &cpIndices); void setTechnique(Technique technique) { m_technique = technique; } @@ -34,7 +31,6 @@ public slots: private: arma::mat m_X; arma::uvec m_cpIndices; - ProjectionHistory *m_history; Technique m_technique; }; diff --git a/numericrange.h b/numericrange.h index 0b69d0e..ebb20ef 100644 --- a/numericrange.h +++ b/numericrange.h @@ -5,7 +5,7 @@ #include /* - * A range in [first, last) in steps of 1. + * A (low memory usage) generator of ranges in steps of 1. */ template class NumericRange @@ -55,6 +55,9 @@ public: T m_value; }; + /* + * The range [first, last). + */ NumericRange(const T &first, const T &last) : m_begin(first) , m_end(last) diff --git a/pm.pro b/pm.pro index c6e0cb0..98b1f89 100644 --- a/pm.pro +++ b/pm.pro @@ -21,6 +21,7 @@ unix { HEADERS += main.h \ colorscale.h \ continuouscolorscale.h \ + divergentcolorscale.h \ geometry.h \ scale.h \ scatterplot.h \ @@ -43,6 +44,7 @@ HEADERS += main.h \ SOURCES += main.cpp \ colorscale.cpp \ continuouscolorscale.cpp \ + divergentcolorscale.cpp \ geometry.cpp \ scatterplot.cpp \ voronoisplat.cpp \ diff --git a/projectionhistory.cpp b/projectionhistory.cpp index e58d227..30c6b76 100644 --- a/projectionhistory.cpp +++ b/projectionhistory.cpp @@ -3,6 +3,8 @@ #include #include +#include + #include "mp.h" #include "numericrange.h" @@ -93,6 +95,7 @@ void ProjectionHistory::addMap(const arma::mat &Y) m_distY = mp::dist(Y); mp::aggregatedError(m_distX, m_distY, m_values); + qDebug("Aggr. error: min: %f, max: %f", m_values.min(), m_values.max()); if (!m_hasFirst) { m_hasFirst = true; @@ -147,7 +150,7 @@ void ProjectionHistory::setCPSelection(const std::vector &cpSelection) } } - emit rpValuesChanged(m_influences(m_rpIndices)); + emit rpValuesChanged(m_influences(m_rpIndices), true); } else { emitValuesChanged(); } @@ -172,9 +175,9 @@ void ProjectionHistory::setRPSelection(const std::vector &rpSelection) } } - emit cpValuesChanged(m_influences(m_cpIndices)); + emit cpValuesChanged(m_influences(m_cpIndices), true); } else { - emit cpValuesChanged(arma::vec()); + emit cpValuesChanged(arma::vec(), false); } } @@ -182,22 +185,22 @@ bool ProjectionHistory::emitValuesChanged() const { switch (m_type) { case ObserverCurrent: - emit rpValuesChanged(m_values(m_rpIndices)); - emit valuesChanged(m_values); + emit rpValuesChanged(m_values(m_rpIndices), false); + emit valuesChanged(m_values, false); return true; case ObserverDiffPrevious: if (m_hasPrev) { arma::vec diff = m_values - m_prevValues; - emit rpValuesChanged(diff(m_rpIndices)); - emit valuesChanged(diff); + emit rpValuesChanged(diff(m_rpIndices), true); + emit valuesChanged(diff, false); return true; } return false; case ObserverDiffFirst: if (m_hasFirst) { arma::vec diff = m_values - m_firstValues; - emit rpValuesChanged(diff(m_rpIndices)); - emit valuesChanged(diff); + emit rpValuesChanged(diff(m_rpIndices), true); + emit valuesChanged(diff, true); return true; } return false; diff --git a/projectionhistory.h b/projectionhistory.h index a18af0c..79519f9 100644 --- a/projectionhistory.h +++ b/projectionhistory.h @@ -33,9 +33,9 @@ signals: void resetPerformed() const; void currentMapChanged(const arma::mat &Y) const; - void valuesChanged(const arma::vec &values) const; - void cpValuesChanged(const arma::vec &values) const; - void rpValuesChanged(const arma::vec &values) const; + void valuesChanged(const arma::vec &values, bool rescale) const; + void cpValuesChanged(const arma::vec &values, bool rescale) const; + void rpValuesChanged(const arma::vec &values, bool rescale) const; void mapRewound(const arma::mat &Y) const; void valuesRewound(const arma::vec &values) const; diff --git a/scatterplot.cpp b/scatterplot.cpp index 2d9af7a..9a1835b 100644 --- a/scatterplot.cpp +++ b/scatterplot.cpp @@ -208,10 +208,11 @@ void QuadTree::query(const QRectF &rect, std::vector &result) const Scatterplot::Scatterplot(QQuickItem *parent) : QQuickItem(parent) , m_glyphSize(DEFAULT_GLYPH_SIZE) - , m_colorScale(ContinuousColorScale::builtin(ContinuousColorScale::HeatedObjects)) + , m_colorScale(0) , m_autoScale(true) , m_sx(0, 1, 0, 1) , m_sy(0, 1, 0, 1) + , m_anySelected(false) , m_brushedItem(-1) , m_interactionState(StateNone) , m_dragEnabled(false) @@ -223,11 +224,10 @@ Scatterplot::Scatterplot(QQuickItem *parent) setFlag(QQuickItem::ItemHasContents); } -void Scatterplot::setColorScale(const ColorScale &colorScale) +void Scatterplot::setColorScale(const ColorScale *colorScale) { m_colorScale = colorScale; if (m_colorData.n_elem > 0) { - m_colorScale.setExtents(m_colorData.min(), m_colorData.max()); m_shouldUpdateMaterials = true; update(); } @@ -277,10 +277,6 @@ void Scatterplot::setColorData(const arma::vec &colorData) m_colorData = colorData; emit colorDataChanged(m_colorData); - if (m_colorData.n_elem > 0) { - m_colorScale.setExtents(m_colorData.min(), m_colorData.max()); - } - m_shouldUpdateMaterials = true; update(); } @@ -517,7 +513,7 @@ void Scatterplot::updateGlyphs(QSGNode *glyphsNode) material = static_cast(glyphNode->material()); if (m_colorData.n_elem > 0) { - material->setColor(m_colorScale.color(m_colorData[i])); + material->setColor(m_colorScale->color(m_colorData[i])); } else { material->setColor(DEFAULT_GLYPH_COLOR); } @@ -613,6 +609,9 @@ void Scatterplot::mouseReleaseEvent(QMouseEvent *event) } else { m_interactionState = StateSelected; m_selection[m_brushedItem] = !m_selection[m_brushedItem]; + if (m_selection[m_brushedItem]) { + m_anySelected = true; + } } emit selectionInteractivelyChanged(m_selection); @@ -623,9 +622,9 @@ void Scatterplot::mouseReleaseEvent(QMouseEvent *event) { // Selecting points and mouse is now released; update selection and // brush - bool anySelected = interactiveSelection(mergeSelection); - m_interactionState = anySelected ? StateSelected - : StateNone; + interactiveSelection(mergeSelection); + m_interactionState = m_anySelected ? StateSelected + : StateNone; QPoint pos = event->pos(); m_brushedItem = m_quadtree->nearestTo(pos.x(), pos.y()); @@ -676,27 +675,26 @@ void Scatterplot::hoverLeaveEvent(QHoverEvent *event) update(); } -bool Scatterplot::interactiveSelection(bool mergeSelection) +void Scatterplot::interactiveSelection(bool mergeSelection) { if (!mergeSelection) { m_selection.assign(m_selection.size(), false); } - bool anySelected = false; std::vector selected; m_quadtree->query(QRectF(m_dragOriginPos, m_dragCurrentPos), selected); for (auto i: selected) { m_selection[i] = true; } + for (auto isSelected: m_selection) { if (isSelected) { - anySelected = true; + m_anySelected = true; break; } } emit selectionInteractivelyChanged(m_selection); - return anySelected; } void Scatterplot::setSelection(const std::vector &selection) diff --git a/scatterplot.h b/scatterplot.h index 33c1ba9..7228498 100644 --- a/scatterplot.h +++ b/scatterplot.h @@ -23,7 +23,7 @@ public: Scatterplot(QQuickItem *parent = 0); arma::mat XY() const; - void setColorScale(const ColorScale &colorScale); + void setColorScale(const ColorScale *colorScale); void setAutoScale(bool autoScale); float glyphSize() const { return m_glyphSize; } void setGlyphSize(float glyphSize); @@ -76,15 +76,16 @@ private: // Visuals float m_glyphSize; - ColorScale m_colorScale; + const ColorScale *m_colorScale; void autoScale(); bool m_autoScale; LinearScale m_sx, m_sy; // Internal state - bool interactiveSelection(bool mergeSelection); + void interactiveSelection(bool mergeSelection); std::vector m_selection; + bool m_anySelected; int m_brushedItem; enum State { diff --git a/voronoisplat.cpp b/voronoisplat.cpp index ad553ba..2ae5a1b 100644 --- a/voronoisplat.cpp +++ b/voronoisplat.cpp @@ -79,10 +79,10 @@ void VoronoiSplat::setValues(const arma::vec &values) update(); } -void VoronoiSplat::setColorScale(const ColorScale &scale) +void VoronoiSplat::setColorScale(const ColorScale *scale) { - m_cmap.resize(scale.numColors() * 3); - scale.sample(scale.numColors(), m_cmap.begin()); + m_cmap.resize(SAMPLES * 3); + scale->sample(SAMPLES, m_cmap.begin()); emit colorScaleChanged(scale); setColormapChanged(true); diff --git a/voronoisplat.h b/voronoisplat.h index 021e88b..b27f690 100644 --- a/voronoisplat.h +++ b/voronoisplat.h @@ -15,6 +15,8 @@ class VoronoiSplat Q_PROPERTY(float alpha READ alpha WRITE setAlpha NOTIFY alphaChanged) Q_PROPERTY(float beta READ beta WRITE setBeta NOTIFY betaChanged) public: + static const int SAMPLES = 128; + VoronoiSplat(QQuickItem *parent = 0); Renderer *createRenderer() const; @@ -44,7 +46,7 @@ public: signals: void sitesChanged(const arma::mat &sites) const; void valuesChanged(const arma::vec &values) const; - void colorScaleChanged(const ColorScale &scale) const; + void colorScaleChanged(const ColorScale *scale) const; void scaleChanged(const LinearScale &sx, const LinearScale &sy) const; void alphaChanged(float alpha) const; void betaChanged(float alpha) const; @@ -57,7 +59,7 @@ public slots: void setValues(const arma::vec &values); // Set colorScale data based on the given color scale - void setColorScale(const ColorScale &scale); + void setColorScale(const ColorScale *scale); void setScale(const LinearScale &sx, const LinearScale &sy); -- cgit v1.2.3