basic charts

This commit is contained in:
Benedek László 2024-05-14 23:02:08 +02:00
parent 679b2d3eca
commit a3af29a572
8 changed files with 140 additions and 44 deletions

View File

@ -0,0 +1,26 @@
#pragma once
#include <graph/server/spec.h>
#include <qabstractseries.h>
#include <QChart>
#include <QChartView>
#include <QLineSeries>
#include <QListWidgetItem>
#include <QValueAxis>
namespace Graph::GUI {
class ChartWidget : public QListWidgetItem {
public:
ChartWidget(QWidget* parent = nullptr, const chart_spec_t& spec = chart_spec_t());
~ChartWidget();
QChartView* getView() const { return view; }
QChart* getChart() const { return chart; }
QList<QAbstractSeries*> getSeries() const { return chart->series(); }
private:
QChartView* view;
QChart* chart;
QValueAxis *x, *y;
};
} // namespace Graph::GUI

View File

@ -4,7 +4,11 @@
#include <QMenuBar> #include <QMenuBar>
#include <QStatusBar> #include <QStatusBar>
#include <QToolBar> #include <QToolBar>
#include <vector>
#include "graph/server/gui/chart/chart.h"
#include <graph/server/plugin.h> #include <graph/server/plugin.h>
#include <qlineseries.h>
#include <qlistwidget.h>
namespace Ui { namespace Ui {
class MainWindow; class MainWindow;
@ -24,6 +28,7 @@ private slots:
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
PluginModel* pluginsModel; PluginModel* pluginModel;
std::vector<ChartWidget*> charts;
}; };
} // namespace Graph::GUI } // namespace Graph::GUI

View File

@ -1,22 +1,19 @@
#pragma once #pragma once
#include <cstdint> #include <QString>
#include <string>
struct graph_spec_t { struct axis_spec_t {
std::string title; QString label;
bool auto_limit = true;
double min;
double max;
};
struct chart_spec_t {
QString title;
bool grid = false; bool grid = false;
bool legend = false; bool legend = false;
struct axis { struct {
struct x { axis_spec_t x, y;
std::string label; } axis;
uint64_t limit = UINT64_MAX;
};
struct y {
std::string label;
bool auto_limit = true;
double min;
double max;
};
};
}; };

View File

@ -1,4 +1,4 @@
find_package(Qt6 REQUIRED COMPONENTS Widgets) find_package(Qt6 REQUIRED COMPONENTS Widgets Charts)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOUIC ON)
@ -6,14 +6,13 @@ set(CMAKE_AUTOUIC ON)
file(GLOB_RECURSE SERVER_SOURCES "*.cpp") file(GLOB_RECURSE SERVER_SOURCES "*.cpp")
file(GLOB_RECURSE SERVER_UI "*.ui") file(GLOB_RECURSE SERVER_UI "*.ui")
file(GLOB_RECURSE SERVER_RES "*.qrc") file(GLOB_RECURSE SERVER_RES "*.qrc")
# file(GLOB_RECURSE SERVER_HEADERS "${CMAKE_SOURCE_DIR}/inc/graph/server/*.h")
file(GLOB_RECURSE SERVER_HEADERS "../../../inc/graph/server/*.h") file(GLOB_RECURSE SERVER_HEADERS "../../../inc/graph/server/*.h")
cmake_print_variables(SERVER_SOURCES) # cmake_print_variables(SERVER_SOURCES)
cmake_print_variables(SERVER_UI) # cmake_print_variables(SERVER_UI)
cmake_print_variables(SERVER_RES) # cmake_print_variables(SERVER_RES)
cmake_print_variables(SERVER_HEADERS) # cmake_print_variables(SERVER_HEADERS)
cmake_print_variables(CMAKE_BINARY_DIR) # cmake_print_variables(CMAKE_BINARY_DIR)
qt_wrap_cpp(SERVER_GEN_SRC ${SERVER_SRC}) qt_wrap_cpp(SERVER_GEN_SRC ${SERVER_SRC})
qt_wrap_ui(SERVER_GEN_UI ${SERVER_UI}) qt_wrap_ui(SERVER_GEN_UI ${SERVER_UI})
@ -24,5 +23,5 @@ add_executable(server
) )
target_include_directories(server PRIVATE "${CMAKE_BINARY_DIR}/src") target_include_directories(server PRIVATE "${CMAKE_BINARY_DIR}/src")
target_link_libraries(server PRIVATE dl Qt6::Widgets) target_link_libraries(server PRIVATE dl Qt6::Widgets Qt6::Charts)
set_target_properties(server PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") set_target_properties(server PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")

View File

@ -0,0 +1,44 @@
#include <graph/server/gui/chart/chart.h>
#include <qsizepolicy.h>
#include <iostream>
namespace Graph::GUI {
ChartWidget::ChartWidget(QWidget* parent, const chart_spec_t& spec) : QListWidgetItem() {
view = new QChartView(parent);
chart = new QChart();
// chart
if (spec.legend)
chart->legend()->show();
else
chart->legend()->hide();
chart->setTitle(spec.title);
// axis
x = new QValueAxis();
y = new QValueAxis();
if (!spec.axis.x.auto_limit)
x->setRange(spec.axis.x.min, spec.axis.x.max);
if (!spec.axis.y.auto_limit)
y->setRange(spec.axis.y.min, spec.axis.y.max);
x->setTitleText(spec.axis.x.label);
y->setTitleText(spec.axis.y.label);
chart->addAxis(x, Qt::AlignBottom);
chart->addAxis(y, Qt::AlignLeft);
view->setChart(chart);
view->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setSizeHint(view->sizeHint()*2);
}
ChartWidget::~ChartWidget() {
// delete view;
// delete chart;
// delete x;
// delete y;
}
} // namespace Graph::GUI

View File

@ -1,33 +1,57 @@
#include <graph/server/gui/mainwindow.h> #include <graph/server/gui/mainwindow.h>
#include <graph/server/plugin.h> #include <graph/server/plugin.h>
#include <graph/server/ui_mainwindow.h> #include <graph/server/ui_mainwindow.h>
#include <qlineseries.h>
#include <qlistwidget.h>
#include <qpoint.h>
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox> #include <QMessageBox>
#include <iostream> #include <iostream>
#include <stdexcept> #include <stdexcept>
#include "graph/server/gui/chart/chart.h"
#include "graph/server/spec.h"
namespace Graph::GUI { namespace Graph::GUI {
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) { MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this); ui->setupUi(this);
// plugins // plugins
pluginsModel = new PluginModel(this); pluginModel = new PluginModel(this);
ui->pluginsListView->setModel(pluginsModel); ui->pluginsListView->setModel(pluginModel);
// unload plugin // unload plugin
connect(ui->pluginsListView, &QListView::doubleClicked, [&](const QModelIndex& index) { connect(ui->pluginsListView, &QListView::doubleClicked, [&](const QModelIndex& index) {
pluginsModel->removeRow(index.row()); QMessageBox::StandardButton result = QMessageBox::question(this, "Unload plugin?", "Are you sure?", QMessageBox::Yes | QMessageBox::Cancel);
pluginsModel->remove(index.row());
ui->pluginsListView->doItemsLayout(); if (result == QMessageBox::Yes) {
pluginModel->removeRow(index.row());
pluginModel->remove(index.row());
ui->pluginsListView->doItemsLayout();
}
}); });
} }
MainWindow::~MainWindow() { MainWindow::~MainWindow() {
delete ui; for (ChartWidget* chart : charts) {
delete pluginsModel; delete chart;
}
delete pluginModel;
} }
void MainWindow::on_action_Add_triggered() {} void MainWindow::on_action_Add_triggered() {
ChartWidget* chart =
new ChartWidget(ui->graphsListWidget, {.title = "My Title", .grid = true, .legend = true, .axis = {.x = {.label = "x axis"}, .y = {.label = "y axis"}}});
ui->graphsListWidget->addItem(chart);
ui->graphsListWidget->setItemWidget(chart, chart->getView());
QLineSeries* series = new QLineSeries();
series->setName("some series");
*series << QPointF(0, 1) << QPointF(1, 2) << QPoint(2, 3);
chart->getChart()->addSeries(series);
}
void MainWindow::on_action_Load_triggered() { void MainWindow::on_action_Load_triggered() {
QString file = QFileDialog::getOpenFileName(this, "Load plugin", ".", "Plugins (*.so *.dll *.dylib)"); QString file = QFileDialog::getOpenFileName(this, "Load plugin", ".", "Plugins (*.so *.dll *.dylib)");
@ -36,15 +60,15 @@ void MainWindow::on_action_Load_triggered() {
return; return;
try { try {
pluginsModel->add(new Plugin(file.toStdString())); pluginModel->add(new Plugin(file.toStdString()));
} catch (std::runtime_error e) { } catch (std::runtime_error e) {
std::cout << e.what() << std::endl; std::cout << e.what() << std::endl;
QMessageBox::critical(this, "Error", "Failed to load plugin.", QMessageBox::StandardButton::Ignore); QMessageBox::critical(this, "Error", "Failed to load plugin.", QMessageBox::StandardButton::Ignore);
} }
int row = pluginsModel->rowCount(); int row = pluginModel->rowCount();
pluginsModel->insertRow(row); pluginModel->insertRow(row);
QModelIndex index = pluginsModel->index(row); QModelIndex index = pluginModel->index(row);
ui->pluginsListView->doItemsLayout(); ui->pluginsListView->doItemsLayout();
ui->pluginsListView->setCurrentIndex(index); ui->pluginsListView->setCurrentIndex(index);
} }

View File

@ -76,21 +76,25 @@
<property name="text"> <property name="text">
<string>&amp;Load</string> <string>&amp;Load</string>
</property> </property>
</action> <property name="shortcut">
<action name="action_Unload"> <string>Ctrl+L</string>
<property name="text">
<string>&amp;Unload</string>
</property> </property>
</action> </action>
<action name="action_Add"> <action name="action_Add">
<property name="text"> <property name="text">
<string>&amp;Add</string> <string>&amp;Add</string>
</property> </property>
<property name="shortcut">
<string>Ctrl+A</string>
</property>
</action> </action>
<action name="action_Remove"> <action name="action_Remove">
<property name="text"> <property name="text">
<string>&amp;Remove</string> <string>&amp;Remove</string>
</property> </property>
<property name="shortcut">
<string>Ctrl+R</string>
</property>
</action> </action>
</widget> </widget>
<resources/> <resources/>

View File

@ -1,8 +1,5 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <graph/server/plugin.h> #include <graph/server/plugin.h>
#include <qnamespace.h>
#include <qobject.h>
#include <qvariant.h>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>