完成热力图部分,取消边框,背景透明
This commit is contained in:
@@ -13,25 +13,31 @@
|
|||||||
#include <qobject.h>
|
#include <qobject.h>
|
||||||
#include <qsize.h>
|
#include <qsize.h>
|
||||||
|
|
||||||
|
using namespace creeper::plot_widget::internal;
|
||||||
|
|
||||||
BasicPlot::BasicPlot() : pimpl{std::make_unique<Impl>(*this)} {
|
BasicPlot::BasicPlot() : pimpl{std::make_unique<Impl>(*this)} {
|
||||||
init_plot();
|
// setStyleSheet("background-color: rgb(255, 0, 0);");
|
||||||
|
// QColor lightBlue(230, 240, 250);
|
||||||
|
setBackground(Qt::transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicPlot::~BasicPlot() {}
|
BasicPlot::~BasicPlot() {}
|
||||||
|
|
||||||
void BasicPlot::set_matrix_size(const QSize& size) {
|
void BasicPlot::set_matrix_size(const QSize& size) {
|
||||||
qDebug() << "set matrix size" << size;
|
qDebug() << "set matrix size" << size;
|
||||||
matrix_size = size;
|
|
||||||
pimpl->set_matrix_size(size);
|
pimpl->set_matrix_size(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicPlot::set_matrix_size(const int& w, const int& h) {
|
void BasicPlot::set_matrix_size(const int& w, const int& h) {
|
||||||
QSize size(w, h);
|
QSize size(w, h);
|
||||||
qDebug() << "set matrix size" << size;
|
qDebug() << "set matrix size" << size;
|
||||||
matrix_size = size;
|
|
||||||
pimpl->set_matrix_size(size);
|
pimpl->set_matrix_size(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BasicPlot::set_color_gradient_range(const double& min, const double& max) {
|
||||||
|
pimpl->set_color_gradient_range(min, max);
|
||||||
|
}
|
||||||
|
|
||||||
void BasicPlot::set_xlabel_text(const QString& text) {
|
void BasicPlot::set_xlabel_text(const QString& text) {
|
||||||
pimpl->set_xlabel_text(text);
|
pimpl->set_xlabel_text(text);
|
||||||
}
|
}
|
||||||
@@ -41,94 +47,50 @@ void BasicPlot::set_ylabel_text(const QString& text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BasicPlot::load_theme_manager(ThemeManager& mgr) {
|
void BasicPlot::load_theme_manager(ThemeManager& mgr) {
|
||||||
|
pimpl->load_theme_manager(mgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize BasicPlot::get_matrix_size() {
|
QSize BasicPlot::get_matrix_size() const {
|
||||||
return matrix_size;
|
return pimpl->get_matrix_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BasicPlot::set_data(const QVector<PointData>& data) {
|
||||||
|
qDebug() << "set data" << data.size();
|
||||||
|
pimpl->set_data(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BasicPlot::is_initialized() const {
|
||||||
|
return pimpl->is_plot_initialized();
|
||||||
|
}
|
||||||
|
|
||||||
void BasicPlot::init_plot() {
|
void BasicPlot::init_plot() {
|
||||||
QVector<PointData> origin_data = {PointData{0, 0, 5}, PointData{0, 1, 3}, PointData{0, 2, 0},
|
pimpl->initialize_plot();
|
||||||
PointData{1, 0, 5}, PointData{1, 1, 3}, PointData{1, 2, 9},
|
|
||||||
PointData{2, 0, 5}, PointData{2, 1, 3}, PointData{2, 2, 3},
|
|
||||||
PointData{3, 0, 5}, PointData{3, 1, 3}, PointData{3, 2, 8}};
|
|
||||||
QCPColorMap* cpmp = new QCPColorMap(xAxis, yAxis);
|
|
||||||
qDebug() << "cpmp->data()->setSize():" << matrix_size;
|
|
||||||
cpmp->data()->setSize(matrix_size.width(), matrix_size.height());
|
|
||||||
cpmp->data()->setRange(QCPRange(0.5, matrix_size.width()), (QCPRange(0.5, matrix_size.height())));
|
|
||||||
// cpmp ->setSize(matrix_size.width(), matrix_size.height());
|
|
||||||
// cpmp ->setRange(QCPRange(0.5, matrix_size.width() - 0.5), QCPRange(0.5, matrix_size.height() - 0.5));
|
|
||||||
QSharedPointer<QCPAxisTickerText> xticker(new QCPAxisTickerText);
|
|
||||||
QSharedPointer<QCPAxisTickerText> yticker(new QCPAxisTickerText);
|
|
||||||
xticker->setSubTickCount(1);
|
|
||||||
xticker->setSubTickCount(1);
|
|
||||||
xAxis->setTicker(xticker);
|
|
||||||
yAxis->setTicker(yticker);
|
|
||||||
xAxis->grid()->setPen(Qt::NoPen);
|
|
||||||
yAxis->grid()->setPen(Qt::NoPen);
|
|
||||||
xAxis->grid()->setSubGridVisible(true);
|
|
||||||
yAxis->grid()->setSubGridVisible(true);
|
|
||||||
xAxis->setSubTicks(true);
|
|
||||||
yAxis->setSubTicks(true);
|
|
||||||
xAxis->setTickLength(0);
|
|
||||||
yAxis->setTickLength(0);
|
|
||||||
xAxis->setSubTickLength(6);
|
|
||||||
yAxis->setSubTickLength(6);
|
|
||||||
xAxis->setRange(0, matrix_size.width());
|
|
||||||
yAxis->setRange(0, matrix_size.height());
|
|
||||||
|
|
||||||
for (const auto& item : origin_data) {
|
|
||||||
cpmp->data()->setCell(item.x, item.y, item.z);
|
|
||||||
}
|
|
||||||
|
|
||||||
QCPColorScale* color_scale = new QCPColorScale(this);
|
|
||||||
color_scale->setType(QCPAxis::atBottom);
|
|
||||||
this->plotLayout()->addElement(1, 0, color_scale);
|
|
||||||
cpmp->setColorScale(color_scale);
|
|
||||||
QCPColorGradient gradient;
|
|
||||||
gradient.setColorStopAt(0.0, QColor("#F6EFA6"));
|
|
||||||
gradient.setColorStopAt(1.0, QColor("#BF444C"));
|
|
||||||
cpmp->setGradient(gradient);
|
|
||||||
|
|
||||||
cpmp->setDataRange(QCPRange(0, 10));
|
|
||||||
cpmp->setInterpolate(false);
|
|
||||||
|
|
||||||
QCPMarginGroup *margin_group = new QCPMarginGroup(this);
|
|
||||||
axisRect()->setMarginGroup(QCP::msLeft | QCP::msRight, margin_group);
|
|
||||||
color_scale->setMarginGroup(QCP::msLeft | QCP::msRight, margin_group);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicPlot::dataChanged(QVector<PointData>& map) {
|
void BasicPlot::paintEvent(QPaintEvent* event) {
|
||||||
auto *cpmp = static_cast<QCPColorMap*>(this->plottable(0));
|
// 确保在绘制前初始化
|
||||||
|
if (!is_initialized()) {
|
||||||
size_t key_size = cpmp->data()->keySize();
|
init_plot();
|
||||||
size_t value_size = cpmp->data()->valueSize();
|
|
||||||
for (auto& item : map) {
|
|
||||||
if (cpmp->data()->alpha(item.x, item.y)) {
|
|
||||||
if (cpmp->data()->alpha(item.x, item.y)) {
|
|
||||||
cpmp->data()->setCell(item.x, item.y, item.z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
QCustomPlot::paintEvent(event);
|
||||||
replot();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicPlot::update_dynamic_heatmap(QVector<PointData>& map) {
|
void BasicPlot::dataChanged(const QVector<PointData>& map) {
|
||||||
auto *cpmp = static_cast<QCPColorMap*>(this->plottable(0));
|
set_data(map);
|
||||||
|
// emit dataChanged(map);
|
||||||
|
}
|
||||||
|
|
||||||
size_t key_size = cpmp->data()->keySize();
|
void BasicPlot::dataRangeChanged(const double& min, const double& max) {
|
||||||
size_t value_size = cpmp->data()->valueSize();
|
set_color_gradient_range(min, max);
|
||||||
for (auto& item: map) {
|
// emit dataRangeChanged(min, max);
|
||||||
if (cpmp->data()->alpha(item.x, item.y)) {
|
}
|
||||||
cpmp->data()->setCell(item.x, item.y, item.z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
replot();
|
void BasicPlot::update_dynamic_heatmap(const QVector<PointData>& map) {
|
||||||
|
set_data(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace creeper;
|
using namespace creeper;
|
||||||
auto HeatMapPlot::paintEvent(QPaintEvent* event) -> void {
|
|
||||||
QCustomPlot::paintEvent(event);
|
void creeper::HeatMapPlot::paintEvent(QPaintEvent* event) {
|
||||||
}
|
BasicPlot::paintEvent(event);
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "modern-qt/utility/wrapper/widget.hh"
|
#include "modern-qt/utility/wrapper/widget.hh"
|
||||||
#include <concepts>
|
#include <concepts>
|
||||||
#include <qcontainerfwd.h>
|
#include <qcontainerfwd.h>
|
||||||
|
#include <qvector.h>
|
||||||
|
|
||||||
struct point_data {
|
struct point_data {
|
||||||
double x;
|
double x;
|
||||||
@@ -26,47 +27,49 @@ class HeatMapPlot;
|
|||||||
|
|
||||||
namespace plot_widget::internal {
|
namespace plot_widget::internal {
|
||||||
class BasicPlot : public QCustomPlot {
|
class BasicPlot : public QCustomPlot {
|
||||||
|
CREEPER_PIMPL_DEFINITION(BasicPlot)
|
||||||
|
friend class HeatMapPlot;
|
||||||
public:
|
public:
|
||||||
// CREEPER_PIMPL_DEFINITION(BasicPlot);
|
// BasicPlot();
|
||||||
BasicPlot();
|
// ~BasicPlot();
|
||||||
~BasicPlot();
|
// BasicPlot(const BasicPlot&) = delete;
|
||||||
BasicPlot(const BasicPlot&) = delete;
|
// BasicPlot& operator=(const BasicPlot&) = delete;
|
||||||
BasicPlot& operator=(const BasicPlot&) = delete; private: struct Impl;
|
|
||||||
std::unique_ptr<Impl> pimpl;
|
|
||||||
|
|
||||||
friend HeatMapPlot;
|
|
||||||
|
|
||||||
public:
|
|
||||||
struct ColorSpace {};
|
|
||||||
|
|
||||||
void init_plot();
|
void init_plot();
|
||||||
|
void load_theme_manager(ThemeManager&);
|
||||||
void load_theme_manager(ThemeManager&); void set_xlabel_text(const QString&);
|
void set_xlabel_text(const QString&);
|
||||||
void set_ylabel_text(const QString&);
|
void set_ylabel_text(const QString&);
|
||||||
|
|
||||||
void set_matrix_size(const QSize&);
|
void set_matrix_size(const QSize&);
|
||||||
|
|
||||||
void set_matrix_size(const int& w, const int& h);
|
void set_matrix_size(const int& w, const int& h);
|
||||||
|
void set_data(const QVector<PointData>& data);
|
||||||
|
void set_color_gradient_range(const double& min, const double& max);
|
||||||
|
QSize get_matrix_size() const;
|
||||||
|
bool is_initialized() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void update_dynamic_heatmap(QVector<PointData>& map);
|
void update_dynamic_heatmap(const QVector<PointData>& map);
|
||||||
void dataChanged(QVector<PointData>& map);
|
void dataChanged(const QVector<PointData>& map);
|
||||||
|
void dataRangeChanged(const double& min, const double& max);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent*) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSize get_matrix_size();
|
friend struct Impl;
|
||||||
private:
|
|
||||||
friend class Impl;
|
|
||||||
QSize matrix_size = {3, 4};
|
|
||||||
};
|
};
|
||||||
} // namespace plot_widget::internal
|
} // namespace plot_widget::internal
|
||||||
|
|
||||||
namespace plot_widget::pro {
|
namespace plot_widget::pro {
|
||||||
using Token = common::Token<internal::BasicPlot>;
|
using Token = common::Token<plot_widget::internal::BasicPlot>;
|
||||||
using XLabelText =
|
|
||||||
common::pro::String<Token, [](auto& self, const auto& string) {
|
using XLabelText = common::pro::String<Token,
|
||||||
|
[](auto& self, const auto& string) {
|
||||||
self.set_xlabel_text(string);
|
self.set_xlabel_text(string);
|
||||||
}>;
|
}>;
|
||||||
using YLabelText =
|
|
||||||
common::pro::String<Token, [](auto& self, const auto& string) {
|
using YLabelText = common::pro::String<Token,
|
||||||
|
[](auto& self, const auto& string) {
|
||||||
self.set_ylabel_text(string);
|
self.set_ylabel_text(string);
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
@@ -75,21 +78,48 @@ namespace plot_widget::pro {
|
|||||||
explicit MatrixSize(const int& w, const int& h) : size{w, h} {}
|
explicit MatrixSize(const int& w, const int& h) : size{w, h} {}
|
||||||
explicit MatrixSize(const QSize& s) : size{s} {}
|
explicit MatrixSize(const QSize& s) : size{s} {}
|
||||||
void apply(auto& self) const {
|
void apply(auto& self) const {
|
||||||
self.set_matrix_size(size.width(), size.height());
|
self.set_matrix_size(size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using Data = common::pro::Vector<Token, PointData,
|
||||||
|
[](auto& self, const auto& data) {
|
||||||
|
self.set_data(data);
|
||||||
|
}>;
|
||||||
|
|
||||||
|
struct ColorRange : Token {
|
||||||
|
double min;
|
||||||
|
double max;
|
||||||
|
explicit ColorRange(double min, double max) : min{min}, max{max} {}
|
||||||
|
void apply(auto& self) const {
|
||||||
|
self.set_color_gradient_range(min, max);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename F>
|
template <typename F>
|
||||||
using OnDataChanged =
|
using OnDataChanged =
|
||||||
common::pro::SignalInjection<F, Token, &internal::BasicPlot::dataChanged>;
|
common::pro::SignalInjection<F, Token, &internal::BasicPlot::dataChanged>;
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
using OnDataRangeChanged =
|
||||||
|
common::pro::SignalInjection<F, Token, &internal::BasicPlot::dataRangeChanged>;
|
||||||
|
|
||||||
template<class PlotWidget>
|
template<class PlotWidget>
|
||||||
concept trait = std::derived_from<PlotWidget, Token>;
|
concept trait = std::derived_from<PlotWidget, Token>;
|
||||||
|
|
||||||
|
using PlotData = common::pro::Vector<Token, PointData, [](auto& self, const auto& vec) {
|
||||||
|
self.set_data(vec);
|
||||||
|
}>;
|
||||||
|
|
||||||
|
using DataRange = common::pro::Array<Token, int, 2, [](auto& self, const auto& arr) {
|
||||||
|
self.set_color_gradient_range(arr[0], arr[1]);
|
||||||
|
}>;
|
||||||
|
|
||||||
CREEPER_DEFINE_CHECKER(trait);
|
CREEPER_DEFINE_CHECKER(trait);
|
||||||
using namespace widget::pro;
|
using namespace widget::pro;
|
||||||
using namespace theme::pro;
|
using namespace theme::pro;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct HeatMapPlot
|
struct HeatMapPlot
|
||||||
: public Declarative<plot_widget::internal::BasicPlot,
|
: public Declarative<plot_widget::internal::BasicPlot,
|
||||||
CheckerOr<plot_widget::pro::checker, widget::pro::checker, theme::pro::checker>> {
|
CheckerOr<plot_widget::pro::checker, widget::pro::checker, theme::pro::checker>> {
|
||||||
@@ -97,4 +127,5 @@ struct HeatMapPlot
|
|||||||
void paintEvent(QPaintEvent*) override;
|
void paintEvent(QPaintEvent*) override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TOUCHSENSOR_HEATMAP_H
|
#endif // TOUCHSENSOR_HEATMAP_H
|
||||||
|
|||||||
@@ -9,34 +9,182 @@
|
|||||||
#include "modern-qt/utility/theme/theme.hh"
|
#include "modern-qt/utility/theme/theme.hh"
|
||||||
#include "modern-qt/widget/sliders.hh"
|
#include "modern-qt/widget/sliders.hh"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <qcolor.h>
|
||||||
|
#include <qdebug.h>
|
||||||
using namespace creeper::plot_widget::internal;
|
using namespace creeper::plot_widget::internal;
|
||||||
|
|
||||||
struct BasicPlot::Impl {
|
struct BasicPlot::Impl {
|
||||||
explicit Impl(BasicPlot& self) noexcept : self{self} {}
|
explicit Impl(BasicPlot& self) noexcept : self{self}, initialized(false), matrix_size(QSize{3, 4}) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
auto set_xlabel_text(const QString& text) -> void { xlabel = text; }
|
auto set_xlabel_text(const QString& text) -> void {
|
||||||
|
xlabel = text;
|
||||||
auto set_ylabel_text(const QString& text) -> void { ylabel = text; }
|
if (initialized) {
|
||||||
|
self.xAxis->setLabel(text);
|
||||||
auto set_matrix_size(const QSize& size) {
|
self.replot();
|
||||||
matrix_size.setWidth(size.width());
|
}
|
||||||
matrix_size.setHeight(size.height());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto load_theme_manager(ThemeManager& mgr) {
|
auto set_ylabel_text(const QString& text) -> void {
|
||||||
// mgr.append_handler(&self, [this](const ThemeManager& mgr){
|
ylabel = text;
|
||||||
// set_color_scheme(mgr.color_scheme());
|
if (initialized) {
|
||||||
// });
|
self.yAxis->setLabel(text);
|
||||||
|
self.replot();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// auto set_color_scheme(slider::pro::Measurements measurements) {
|
auto set_matrix_size(const QSize& size) -> void {
|
||||||
//
|
matrix_size = size;
|
||||||
// }
|
if (initialized) {
|
||||||
private:
|
// 重新初始化热力图以适应新的矩阵大小
|
||||||
|
reset_plot();
|
||||||
|
if (!data_points.isEmpty()) {
|
||||||
|
set_data(data_points);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto load_theme_manager(ThemeManager& mgr) -> void {
|
||||||
|
mgr.append_handler(&self, [this](const ThemeManager& mgr) {
|
||||||
|
// 可以根据主题更新颜色渐变等
|
||||||
|
if (initialized) {
|
||||||
|
self.replot();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto set_color_gradient_range(const double& min, const double& max) -> void {
|
||||||
|
if (initialized && self.plottableCount() > 0) {
|
||||||
|
auto* cpmp = static_cast<QCPColorMap*>(self.plottable(0));
|
||||||
|
cpmp->setDataRange(QCPRange(min, max));
|
||||||
|
self.replot();
|
||||||
|
}
|
||||||
|
color_min = min;
|
||||||
|
color_max = max;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto set_data(const QVector<PointData>& data) -> void {
|
||||||
|
data_points = data;
|
||||||
|
if (initialized) {
|
||||||
|
update_plot_data();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto initialize_plot() -> void {
|
||||||
|
if (initialized) return;
|
||||||
|
|
||||||
|
// 创建颜色映射
|
||||||
|
QCPColorMap* cpmp = new QCPColorMap(self.xAxis, self.yAxis);
|
||||||
|
qDebug() << "initialize_plot() size:" << matrix_size;
|
||||||
|
cpmp->data()->setSize(matrix_size.width(), matrix_size.height());
|
||||||
|
cpmp->data()->setRange(QCPRange(0.5, matrix_size.width() - 0.5),
|
||||||
|
QCPRange(0.5, matrix_size.height() - 0.5));
|
||||||
|
|
||||||
|
// 配置坐标轴
|
||||||
|
QSharedPointer<QCPAxisTickerText> xticker(new QCPAxisTickerText);
|
||||||
|
QSharedPointer<QCPAxisTickerText> yticker(new QCPAxisTickerText);
|
||||||
|
xticker->setSubTickCount(1);
|
||||||
|
yticker->setSubTickCount(1);
|
||||||
|
self.xAxis->setVisible(false);
|
||||||
|
self.yAxis->setVisible(false);
|
||||||
|
self.xAxis->setTicker(xticker);
|
||||||
|
self.yAxis->setTicker(yticker);
|
||||||
|
|
||||||
|
// 设置网格
|
||||||
|
self.xAxis->grid()->setPen(Qt::NoPen);
|
||||||
|
self.yAxis->grid()->setPen(Qt::NoPen);
|
||||||
|
self.xAxis->grid()->setSubGridVisible(true);
|
||||||
|
self.yAxis->grid()->setSubGridVisible(true);
|
||||||
|
self.xAxis->setSubTicks(true);
|
||||||
|
self.yAxis->setSubTicks(true);
|
||||||
|
self.xAxis->setTickLength(0);
|
||||||
|
self.yAxis->setTickLength(0);
|
||||||
|
self.xAxis->setSubTickLength(6);
|
||||||
|
self.yAxis->setSubTickLength(6);
|
||||||
|
|
||||||
|
// 设置范围
|
||||||
|
self.xAxis->setRange(0, matrix_size.width());
|
||||||
|
self.yAxis->setRange(0, matrix_size.height());
|
||||||
|
|
||||||
|
// 设置标签
|
||||||
|
if (!xlabel.isEmpty()) self.xAxis->setLabel(xlabel);
|
||||||
|
if (!ylabel.isEmpty()) self.yAxis->setLabel(ylabel);
|
||||||
|
|
||||||
|
// 添加颜色刻度
|
||||||
|
QCPColorScale* color_scale = new QCPColorScale(&self);
|
||||||
|
color_scale->setType(QCPAxis::atBottom);
|
||||||
|
self.plotLayout()->addElement(1, 0, color_scale);
|
||||||
|
cpmp->setColorScale(color_scale);
|
||||||
|
|
||||||
|
// 设置颜色渐变
|
||||||
|
QCPColorGradient gradient;
|
||||||
|
gradient.setColorStopAt(0.0, QColor(246, 239, 166)); // F6EFA6
|
||||||
|
gradient.setColorStopAt(1.0, QColor(191, 68, 76)); // BF444C
|
||||||
|
cpmp->setGradient(gradient);
|
||||||
|
|
||||||
|
// 设置数据范围
|
||||||
|
cpmp->setDataRange(QCPRange(color_min, color_max));
|
||||||
|
cpmp->setInterpolate(false);
|
||||||
|
|
||||||
|
// 配置边距
|
||||||
|
QCPMarginGroup *margin_group = new QCPMarginGroup(&self);
|
||||||
|
self.axisRect()->setMarginGroup(QCP::msLeft | QCP::msRight, margin_group);
|
||||||
|
color_scale->setMarginGroup(QCP::msLeft | QCP::msRight, margin_group);
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
|
||||||
|
// 如果已有数据,更新图表
|
||||||
|
if (!data_points.isEmpty()) {
|
||||||
|
update_plot_data();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto reset_plot() -> void {
|
||||||
|
// 清除所有绘图元素
|
||||||
|
self.clearPlottables();
|
||||||
|
self.clearGraphs();
|
||||||
|
self.clearItems();
|
||||||
|
self.clearFocus();
|
||||||
|
|
||||||
|
// 重新初始化
|
||||||
|
initialized = false;
|
||||||
|
initialize_plot();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto update_plot_data() -> void {
|
||||||
|
if (!initialized || self.plottableCount() == 0) return;
|
||||||
|
|
||||||
|
auto* cpmp = static_cast<QCPColorMap*>(self.plottable(0));
|
||||||
|
|
||||||
|
|
||||||
|
// 设置新数据
|
||||||
|
for (const auto& item : data_points) {
|
||||||
|
if (item.x >= 0 && item.x < matrix_size.width() &&
|
||||||
|
item.y >= 0 && item.y < matrix_size.height()) {
|
||||||
|
cpmp->data()->setCell(item.x, item.y, item.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重绘
|
||||||
|
self.replot();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto is_plot_initialized() const -> bool {
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto get_matrix_size() const -> QSize {
|
||||||
|
return matrix_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
QString xlabel;
|
QString xlabel;
|
||||||
QString ylabel;
|
QString ylabel;
|
||||||
QSize matrix_size;
|
QSize matrix_size;
|
||||||
|
QVector<PointData> data_points;
|
||||||
|
double color_min = 0.0;
|
||||||
|
double color_max = 15.0;
|
||||||
|
bool initialized;
|
||||||
BasicPlot& self;
|
BasicPlot& self;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ static auto ComConfigComponent(ThemeManager& manager, auto&& callback) {
|
|||||||
auto select_baud_context = std::make_shared<MutableValue<QStringList>>();
|
auto select_baud_context = std::make_shared<MutableValue<QStringList>>();
|
||||||
select_baud_context->set_silent(QStringList {"9600", "115200"});
|
select_baud_context->set_silent(QStringList {"9600", "115200"});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const auto row = new Row {
|
const auto row = new Row {
|
||||||
// lnpro::Item<FilledTextField> {
|
// lnpro::Item<FilledTextField> {
|
||||||
// text_field::pro::ThemeManager {manager},
|
// text_field::pro::ThemeManager {manager},
|
||||||
@@ -148,11 +150,22 @@ static auto ComConfigComponent(ThemeManager& manager, auto&& callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static auto DisplayComponent(ThemeManager& manager, int index = 0) noexcept {
|
static auto DisplayComponent(ThemeManager& manager, int index = 0) noexcept {
|
||||||
|
auto heatmap_context = std::make_shared<MutableValue<QVector<PointData>>>();
|
||||||
|
heatmap_context->set_silent(QVector<PointData>{
|
||||||
|
PointData{0, 0, 1}, PointData{1, 0, 2}, PointData{2, 0, 3},
|
||||||
|
PointData{0, 1, 3}, PointData{1, 1, 4}, PointData{2, 1, 5},
|
||||||
|
PointData{0, 2, 6}, PointData{1, 2, 7}, PointData{2, 2, 8},
|
||||||
|
PointData{0, 3, 9}, PointData{1, 3, 10}, PointData{2, 3, 11},
|
||||||
|
});
|
||||||
const auto row = new Row{
|
const auto row = new Row{
|
||||||
lnpro::Item<HeatMapPlot> {
|
lnpro::Item<HeatMapPlot> {
|
||||||
plot_widget::pro::SizePolicy {
|
plot_widget::pro::SizePolicy {
|
||||||
QSizePolicy::Expanding,
|
QSizePolicy::Expanding,
|
||||||
},
|
},
|
||||||
|
MutableForward {
|
||||||
|
plot_widget::pro::PlotData {},
|
||||||
|
heatmap_context,
|
||||||
|
},
|
||||||
pwpro::MatrixSize {
|
pwpro::MatrixSize {
|
||||||
QSize{3, 4}
|
QSize{3, 4}
|
||||||
},
|
},
|
||||||
|
|||||||
6
main.cc
6
main.cc
@@ -46,7 +46,11 @@ auto main(int argc, char *argv[]) -> int {
|
|||||||
[&](MainWindow& window) noexcept {
|
[&](MainWindow& window) noexcept {
|
||||||
|
|
||||||
},
|
},
|
||||||
mwpro::FixedSize {1080, 720},
|
// mwpro::FixedSize {1080, 720},
|
||||||
|
mwpro::MinimumSize {
|
||||||
|
1080,
|
||||||
|
720
|
||||||
|
},
|
||||||
mwpro::Central<FilledCard> {
|
mwpro::Central<FilledCard> {
|
||||||
capro::ThemeManager {manager},
|
capro::ThemeManager {manager},
|
||||||
capro::Radius {0},
|
capro::Radius {0},
|
||||||
|
|||||||
@@ -131,6 +131,25 @@ namespace pro {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class Token, typename T, std::size_t N, auto setter>
|
||||||
|
struct Array : public std::array<T, N>, Token {
|
||||||
|
using std::array<T, N>::array;
|
||||||
|
explicit Array(const std::array<T, N>& arr) noexcept
|
||||||
|
: std::array<T, N> { arr } { }
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
requires (sizeof...(Args) == N)
|
||||||
|
explicit Array(Args&&... args) noexcept
|
||||||
|
: std::array<T, N> {
|
||||||
|
std::forward<Args>(args)...} {}
|
||||||
|
|
||||||
|
void apply(auto& self) const
|
||||||
|
requires requires {setter(self, *this);}
|
||||||
|
{
|
||||||
|
setter(self, *this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// template<class Token, typename T, auto setter>
|
// template<class Token, typename T, auto setter>
|
||||||
// Vector<Token, T, setter>::Vector(const QVector<T> &vec) noexcept:QVector { vec } { }
|
// Vector<Token, T, setter>::Vector(const QVector<T> &vec) noexcept:QVector { vec } { }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user