From 9f06269aa41773d99fee5f7bd8ced4acdd01863a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Du=C5=A1an=20Poizl?= Date: Sun, 27 Apr 2025 17:43:32 +0200 Subject: [PATCH] Improve chart graph --- chartgraph.cpp | 89 +++++++++++++++++++++++++++++++++++++++++--------- chartgraph.h | 5 ++- 2 files changed, 75 insertions(+), 19 deletions(-) diff --git a/chartgraph.cpp b/chartgraph.cpp index 9f30f12..cda713e 100644 --- a/chartgraph.cpp +++ b/chartgraph.cpp @@ -4,12 +4,15 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include class ChartView : public QChartView { @@ -22,6 +25,7 @@ public: protected: void keyPressEvent(QKeyEvent *event) override { + if(!chart()->isZoomed())chart()->zoom(0.999999);//workaround so zoomReset() reset scroll switch(event->key()) { case Qt::Key_Plus: @@ -52,6 +56,7 @@ protected: if(event->button() == Qt::LeftButton) { _scroll = true; + if(!chart()->isZoomed())chart()->zoom(0.999999);//workaround so zoomReset() reset scroll _mousePos = event->position(); } @@ -72,25 +77,29 @@ protected: _scroll = false; QChartView::mouseReleaseEvent(event); } + void wheelEvent(QWheelEvent *event) override + { + if(event->angleDelta().y() > 0) + chart()->zoomIn(); + if(event->angleDelta().y() < 0) + chart()->zoomOut(); + } }; -ChartGraph::ChartGraph(QWidget *parent) : QDialog(parent) +ChartGraph::ChartGraph(QWidget *parent) : QMainWindow(parent) { setAttribute(Qt::WA_DeleteOnClose); - setModal(false); _chartView = new ChartView(this); - setLayout(new QVBoxLayout); - layout()->addWidget(_chartView); + setCentralWidget(_chartView); _chart = new QChart; _chartView->setChart(_chart); _chartView->setRenderHint(QPainter::Antialiasing); resize(1024, 768); - QMenuBar *menuBar = new QMenuBar(this); - menuBar->addAction(tr("Save"), this, &ChartGraph::save); - layout()->setMenuBar(menuBar); + menuBar()->addAction(tr("Save"), this, &ChartGraph::save); + menuBar()->addAction(tr("Reset view"), [this](){ _chart->zoomReset(); }); } void ChartGraph::plot(const QVariant &graph) @@ -117,13 +126,29 @@ void ChartGraph::plot(const QVariant &graph) QBarSeries *barSeries = nullptr; + qreal minX = INFINITY; + qreal maxX = -INFINITY; qreal minY = INFINITY; qreal maxY = -INFINITY; + qreal minY2 = INFINITY; + qreal maxY2 = -INFINITY; + + QValueAxis *xaxis = new QValueAxis(_chart); + QBarCategoryAxis *barxaxis = new QBarCategoryAxis(_chart); + QValueAxis *yaxis = new QValueAxis(_chart); + QValueAxis *y2axis = new QValueAxis(_chart); + _chart->addAxis(xaxis, Qt::AlignBottom); + _chart->addAxis(yaxis, Qt::AlignLeft); + _chart->addAxis(y2axis, Qt::AlignRight); + _chart->addAxis(barxaxis, Qt::AlignBottom); + y2axis->setGridLinePen(Qt::DashDotLine); for(auto s : map["series"].toList()) { QVariantMap serie = s.toMap(); QString type = serie["type"].toString(); + bool y2 = serie["y2"].toBool(); + if(type == "line" || type == "points" || type == "linePoints" || type.isEmpty()) { QXYSeries *series = nullptr; @@ -151,10 +176,20 @@ void ChartGraph::plot(const QVariant &graph) for(int i = 0; i < y.size(); i++) { qreal val = y[i].toDouble(); - minY = std::min(minY, val); - maxY = std::max(maxY, val); + if(y2) + { + minY2 = std::min(minY2, val); + maxY2 = std::max(maxY2, val); + } + else + { + minY = std::min(minY, val); + maxY = std::max(maxY, val); + } series->append(i, val); } + minX = std::min(minX, 0.0); + maxX = std::max(maxX, y.size() - 1.0); } else { @@ -162,13 +197,25 @@ void ChartGraph::plot(const QVariant &graph) for(int i = 0; i < size; i++) { qreal val = y[i].toDouble(); - minY = std::min(minY, val); - maxY = std::max(maxY, val); + if(y2) + { + minY2 = std::min(minY2, val); + maxY2 = std::max(maxY2, val); + } + else + { + minY = std::min(minY, val); + maxY = std::max(maxY, val); + } + minX = std::min(minX, x[i].toDouble()); + maxX = std::max(maxX, x[i].toDouble()); series->append(x[i].toDouble(), val); } } _chart->addSeries(series); + series->attachAxis(xaxis); + series->attachAxis(y2 ? y2axis : yaxis); if(serie["bestFit"].toBool()) { series->setBestFitLineVisible(true); @@ -193,6 +240,8 @@ void ChartGraph::plot(const QVariant &graph) { barSeries = new QBarSeries(_chart); _chart->addSeries(barSeries); + barSeries->attachAxis(yaxis); + barSeries->attachAxis(barxaxis); } QBarSet *set = new QBarSet(serie["title"].toString()); QVariantList y = serie["y"].toList(); @@ -205,6 +254,9 @@ void ChartGraph::plot(const QVariant &graph) } barSeries->append(set); + for(int i = barxaxis->count() + 1; i <= y.size(); i++) + barxaxis->append(QString::number(i)); + if(serie.contains("color")) { QString color = serie["color"].toString(); @@ -213,13 +265,18 @@ void ChartGraph::plot(const QVariant &graph) } } - _chart->createDefaultAxes(); - QValueAxis *yaxis = qobject_cast(_chart->axes(Qt::Vertical).front()); - if(yaxis) + if(barSeries) { - qreal off = (maxY - minY) * 0.05; - yaxis->setRange(std::min(minY - off, 0.0), maxY + off); + xaxis->setRange(std::min(minX, -0.5), std::max(maxX, barxaxis->count() - 0.5)); + minY = std::min(minY, 0.0); } + else + { + xaxis->setRange(minX, maxX); + } + + yaxis->setRange(minY, maxY); + y2axis->setRange(minY2, maxY2); show(); } diff --git a/chartgraph.h b/chartgraph.h index 4bcb953..85b5bd7 100644 --- a/chartgraph.h +++ b/chartgraph.h @@ -1,13 +1,13 @@ #ifndef CHARTGRAPH_H #define CHARTGRAPH_H -#include +#include #include #include class ChartView; -class ChartGraph : public QDialog +class ChartGraph : public QMainWindow { Q_OBJECT QChart *_chart; @@ -17,7 +17,6 @@ public: void plot(const QVariant &graph); public slots: void save(); -signals: }; #endif // CHARTGRAPH_H