Improve chart graph

This commit is contained in:
2025-04-27 17:43:32 +02:00
parent 78f242d808
commit 9f06269aa4
2 changed files with 75 additions and 19 deletions
+73 -16
View File
@@ -4,12 +4,15 @@
#include <QLineSeries> #include <QLineSeries>
#include <QBarSeries> #include <QBarSeries>
#include <QBarSet> #include <QBarSet>
#include <QBarCategoryAxis>
#include <QScatterSeries> #include <QScatterSeries>
#include <QMenu> #include <QMenu>
#include <QMenuBar> #include <QMenuBar>
#include <QValueAxis> #include <QValueAxis>
#include <QFileDialog> #include <QFileDialog>
#include <QSettings> #include <QSettings>
#include <QToolBar>
#include <QStyle>
class ChartView : public QChartView class ChartView : public QChartView
{ {
@@ -22,6 +25,7 @@ public:
protected: protected:
void keyPressEvent(QKeyEvent *event) override void keyPressEvent(QKeyEvent *event) override
{ {
if(!chart()->isZoomed())chart()->zoom(0.999999);//workaround so zoomReset() reset scroll
switch(event->key()) switch(event->key())
{ {
case Qt::Key_Plus: case Qt::Key_Plus:
@@ -52,6 +56,7 @@ protected:
if(event->button() == Qt::LeftButton) if(event->button() == Qt::LeftButton)
{ {
_scroll = true; _scroll = true;
if(!chart()->isZoomed())chart()->zoom(0.999999);//workaround so zoomReset() reset scroll
_mousePos = event->position(); _mousePos = event->position();
} }
@@ -72,25 +77,29 @@ protected:
_scroll = false; _scroll = false;
QChartView::mouseReleaseEvent(event); 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); setAttribute(Qt::WA_DeleteOnClose);
setModal(false);
_chartView = new ChartView(this); _chartView = new ChartView(this);
setLayout(new QVBoxLayout); setCentralWidget(_chartView);
layout()->addWidget(_chartView);
_chart = new QChart; _chart = new QChart;
_chartView->setChart(_chart); _chartView->setChart(_chart);
_chartView->setRenderHint(QPainter::Antialiasing); _chartView->setRenderHint(QPainter::Antialiasing);
resize(1024, 768); resize(1024, 768);
QMenuBar *menuBar = new QMenuBar(this); menuBar()->addAction(tr("Save"), this, &ChartGraph::save);
menuBar->addAction(tr("Save"), this, &ChartGraph::save); menuBar()->addAction(tr("Reset view"), [this](){ _chart->zoomReset(); });
layout()->setMenuBar(menuBar);
} }
void ChartGraph::plot(const QVariant &graph) void ChartGraph::plot(const QVariant &graph)
@@ -117,13 +126,29 @@ void ChartGraph::plot(const QVariant &graph)
QBarSeries *barSeries = nullptr; QBarSeries *barSeries = nullptr;
qreal minX = INFINITY;
qreal maxX = -INFINITY;
qreal minY = INFINITY; qreal minY = INFINITY;
qreal maxY = -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()) for(auto s : map["series"].toList())
{ {
QVariantMap serie = s.toMap(); QVariantMap serie = s.toMap();
QString type = serie["type"].toString(); QString type = serie["type"].toString();
bool y2 = serie["y2"].toBool();
if(type == "line" || type == "points" || type == "linePoints" || type.isEmpty()) if(type == "line" || type == "points" || type == "linePoints" || type.isEmpty())
{ {
QXYSeries *series = nullptr; QXYSeries *series = nullptr;
@@ -151,10 +176,20 @@ void ChartGraph::plot(const QVariant &graph)
for(int i = 0; i < y.size(); i++) for(int i = 0; i < y.size(); i++)
{ {
qreal val = y[i].toDouble(); qreal val = y[i].toDouble();
minY = std::min(minY, val); if(y2)
maxY = std::max(maxY, val); {
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); series->append(i, val);
} }
minX = std::min(minX, 0.0);
maxX = std::max(maxX, y.size() - 1.0);
} }
else else
{ {
@@ -162,13 +197,25 @@ void ChartGraph::plot(const QVariant &graph)
for(int i = 0; i < size; i++) for(int i = 0; i < size; i++)
{ {
qreal val = y[i].toDouble(); qreal val = y[i].toDouble();
minY = std::min(minY, val); if(y2)
maxY = std::max(maxY, val); {
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); series->append(x[i].toDouble(), val);
} }
} }
_chart->addSeries(series); _chart->addSeries(series);
series->attachAxis(xaxis);
series->attachAxis(y2 ? y2axis : yaxis);
if(serie["bestFit"].toBool()) if(serie["bestFit"].toBool())
{ {
series->setBestFitLineVisible(true); series->setBestFitLineVisible(true);
@@ -193,6 +240,8 @@ void ChartGraph::plot(const QVariant &graph)
{ {
barSeries = new QBarSeries(_chart); barSeries = new QBarSeries(_chart);
_chart->addSeries(barSeries); _chart->addSeries(barSeries);
barSeries->attachAxis(yaxis);
barSeries->attachAxis(barxaxis);
} }
QBarSet *set = new QBarSet(serie["title"].toString()); QBarSet *set = new QBarSet(serie["title"].toString());
QVariantList y = serie["y"].toList(); QVariantList y = serie["y"].toList();
@@ -205,6 +254,9 @@ void ChartGraph::plot(const QVariant &graph)
} }
barSeries->append(set); barSeries->append(set);
for(int i = barxaxis->count() + 1; i <= y.size(); i++)
barxaxis->append(QString::number(i));
if(serie.contains("color")) if(serie.contains("color"))
{ {
QString color = serie["color"].toString(); QString color = serie["color"].toString();
@@ -213,13 +265,18 @@ void ChartGraph::plot(const QVariant &graph)
} }
} }
_chart->createDefaultAxes(); if(barSeries)
QValueAxis *yaxis = qobject_cast<QValueAxis*>(_chart->axes(Qt::Vertical).front());
if(yaxis)
{ {
qreal off = (maxY - minY) * 0.05; xaxis->setRange(std::min(minX, -0.5), std::max(maxX, barxaxis->count() - 0.5));
yaxis->setRange(std::min(minY - off, 0.0), maxY + off); minY = std::min(minY, 0.0);
} }
else
{
xaxis->setRange(minX, maxX);
}
yaxis->setRange(minY, maxY);
y2axis->setRange(minY2, maxY2);
show(); show();
} }
+2 -3
View File
@@ -1,13 +1,13 @@
#ifndef CHARTGRAPH_H #ifndef CHARTGRAPH_H
#define CHARTGRAPH_H #define CHARTGRAPH_H
#include <QDialog> #include <QMainWindow>
#include <QJSValue> #include <QJSValue>
#include <QChart> #include <QChart>
class ChartView; class ChartView;
class ChartGraph : public QDialog class ChartGraph : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
QChart *_chart; QChart *_chart;
@@ -17,7 +17,6 @@ public:
void plot(const QVariant &graph); void plot(const QVariant &graph);
public slots: public slots:
void save(); void save();
signals:
}; };
#endif // CHARTGRAPH_H #endif // CHARTGRAPH_H