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 <QBarSeries>
#include <QBarSet>
#include <QBarCategoryAxis>
#include <QScatterSeries>
#include <QMenu>
#include <QMenuBar>
#include <QValueAxis>
#include <QFileDialog>
#include <QSettings>
#include <QToolBar>
#include <QStyle>
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<QValueAxis*>(_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();
}