complete chart view window with option to select chart from thermo columns
This commit is contained in:
@ -13,18 +13,95 @@
|
|||||||
|
|
||||||
#include "chartviewer.h"
|
#include "chartviewer.h"
|
||||||
|
|
||||||
|
#include <QHBoxLayout>
|
||||||
#include <QLineSeries>
|
#include <QLineSeries>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
using namespace QtCharts;
|
using namespace QtCharts;
|
||||||
|
|
||||||
ChartViewer::ChartViewer(QWidget *parent) :
|
ChartWindow::ChartWindow(const QString &_filename, QWidget *parent) :
|
||||||
QChartView(parent), last_step(-1), chart(new QChart), series(new QLineSeries),
|
QWidget(parent), menu(new QMenuBar), file(new QMenu("&File")), active_chart(-1),
|
||||||
|
filename(_filename)
|
||||||
|
{
|
||||||
|
auto *top = new QHBoxLayout;
|
||||||
|
menu->addMenu(file);
|
||||||
|
menu->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
|
||||||
|
|
||||||
|
columns = new QComboBox;
|
||||||
|
top->addWidget(menu);
|
||||||
|
top->addWidget(columns);
|
||||||
|
saveAsAct = file->addAction("&Save Graph As...", this, &ChartWindow::saveAs);
|
||||||
|
closeAct = file->addAction("&Close", this, &QWidget::close);
|
||||||
|
auto *layout = new QVBoxLayout;
|
||||||
|
layout->addLayout(top);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
connect(columns, SIGNAL(currentIndexChanged(int)), this, SLOT(change_chart(int)));
|
||||||
|
QSettings settings;
|
||||||
|
resize(settings.value("chartx", 500).toInt(), settings.value("charty", 320).toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChartWindow::add_chart(const QString &title, int index)
|
||||||
|
{
|
||||||
|
auto *chart = new ChartViewer(title, index);
|
||||||
|
layout()->addWidget(chart);
|
||||||
|
columns->addItem(title, index);
|
||||||
|
columns->show();
|
||||||
|
// hide all but the first chart added
|
||||||
|
if (charts.size() > 0) chart->hide();
|
||||||
|
charts.append(chart);
|
||||||
|
active_chart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChartWindow::add_data(int step, double data, int index)
|
||||||
|
{
|
||||||
|
for (auto &c : charts)
|
||||||
|
if (c->get_index() == index) c->add_data(step, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChartWindow::saveAs()
|
||||||
|
{
|
||||||
|
if (charts.empty() || (active_chart < 0)) return;
|
||||||
|
QString defaultname = filename + "." + columns->currentText() + ".png";
|
||||||
|
if (filename.isEmpty()) defaultname = columns->currentText() + ".png";
|
||||||
|
QString fileName = QFileDialog::getSaveFileName(this, "Save Chart as Image", defaultname,
|
||||||
|
"Image Files (*.jpg *.png *.bmp *.ppm)");
|
||||||
|
if (!fileName.isEmpty()) {
|
||||||
|
charts[active_chart]->grab().save(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChartWindow::change_chart(int index)
|
||||||
|
{
|
||||||
|
int choice = columns->currentData().toInt();
|
||||||
|
for (auto &c : charts) {
|
||||||
|
if (choice == c->get_index())
|
||||||
|
c->show();
|
||||||
|
else
|
||||||
|
c->hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChartWindow::closeEvent(QCloseEvent *event)
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
if (!isMaximized()) {
|
||||||
|
settings.setValue("chartx", width());
|
||||||
|
settings.setValue("charty", height());
|
||||||
|
}
|
||||||
|
QWidget::closeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
ChartViewer::ChartViewer(const QString &title, int _index, QWidget *parent) :
|
||||||
|
QChartView(parent), last_step(-1), index(_index), chart(new QChart), series(new QLineSeries),
|
||||||
xaxis(new QValueAxis), yaxis(new QValueAxis)
|
xaxis(new QValueAxis), yaxis(new QValueAxis)
|
||||||
{
|
{
|
||||||
chart->legend()->hide();
|
chart->legend()->hide();
|
||||||
chart->addAxis(xaxis,Qt::AlignBottom);
|
chart->addAxis(xaxis, Qt::AlignBottom);
|
||||||
chart->addAxis(yaxis,Qt::AlignLeft);
|
chart->addAxis(yaxis, Qt::AlignLeft);
|
||||||
chart->addSeries(series);
|
chart->addSeries(series);
|
||||||
series->attachAxis(xaxis);
|
series->attachAxis(xaxis);
|
||||||
series->attachAxis(yaxis);
|
series->attachAxis(yaxis);
|
||||||
@ -33,22 +110,17 @@ ChartViewer::ChartViewer(QWidget *parent) :
|
|||||||
yaxis->setTickCount(5);
|
yaxis->setTickCount(5);
|
||||||
xaxis->setMinorTickCount(5);
|
xaxis->setMinorTickCount(5);
|
||||||
yaxis->setMinorTickCount(5);
|
yaxis->setMinorTickCount(5);
|
||||||
|
yaxis->setTitleText(title);
|
||||||
|
series->setName(title);
|
||||||
|
|
||||||
setRenderHint(QPainter::Antialiasing);
|
setRenderHint(QPainter::Antialiasing);
|
||||||
setChart(chart);
|
setChart(chart);
|
||||||
setRubberBand(QChartView::RectangleRubberBand);
|
setRubberBand(QChartView::RectangleRubberBand);
|
||||||
|
|
||||||
QSettings settings;
|
|
||||||
resize(settings.value("chartx", 500).toInt(), settings.value("charty", 320).toInt());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChartViewer::add_column(const QString &title)
|
/* -------------------------------------------------------------------- */
|
||||||
{
|
|
||||||
yaxis->setTitleText(title);
|
|
||||||
series->setName(title);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChartViewer::add_data(int step, int column, double data)
|
void ChartViewer::add_data(int step, double data)
|
||||||
{
|
{
|
||||||
if (last_step < step) {
|
if (last_step < step) {
|
||||||
last_step = step;
|
last_step = step;
|
||||||
@ -70,16 +142,6 @@ void ChartViewer::add_data(int step, int column, double data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChartViewer::closeEvent(QCloseEvent *event)
|
|
||||||
{
|
|
||||||
QSettings settings;
|
|
||||||
if (!isMaximized()) {
|
|
||||||
settings.setValue("chartx", width());
|
|
||||||
settings.setValue("charty", height());
|
|
||||||
}
|
|
||||||
QChartView::closeEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
// c-basic-offset: 4
|
// c-basic-offset: 4
|
||||||
// End:
|
// End:
|
||||||
|
|||||||
@ -14,23 +14,61 @@
|
|||||||
#ifndef CHARTVIEWER_H
|
#ifndef CHARTVIEWER_H
|
||||||
#define CHARTVIEWER_H
|
#define CHARTVIEWER_H
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QString>
|
||||||
|
#include <QWidget>
|
||||||
#include <QtCharts>
|
#include <QtCharts>
|
||||||
|
|
||||||
class ChartViewer : public QtCharts::QChartView {
|
class QAction;
|
||||||
|
class QMenuBar;
|
||||||
|
class QMenu;
|
||||||
|
class QComboBox;
|
||||||
|
class ChartViewer;
|
||||||
|
|
||||||
|
class ChartWindow : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ChartViewer(QWidget *parent = nullptr);
|
ChartWindow(const QString &filename, QWidget *parent = nullptr);
|
||||||
bool has_columns() const { return last_step >= 0; }
|
|
||||||
void add_column(const QString &title);
|
bool has_charts() const { return !charts.isEmpty(); }
|
||||||
void add_data(int step, int column, double data);
|
void add_chart(const QString &title, int index);
|
||||||
int get_last_step() const;
|
void add_data(int step, double data, int index);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void saveAs();
|
||||||
|
void change_chart(int index);
|
||||||
|
|
||||||
|
// void normalSize();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int last_step;
|
QMenuBar *menu;
|
||||||
|
QMenu *file;
|
||||||
|
QComboBox *columns;
|
||||||
|
QAction *saveAsAct;
|
||||||
|
QAction *closeAct;
|
||||||
|
|
||||||
|
QString filename;
|
||||||
|
int active_chart;
|
||||||
|
QList<ChartViewer *> charts;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
class ChartViewer : public QtCharts::QChartView {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ChartViewer(const QString &title, int index, QWidget *parent = nullptr);
|
||||||
|
|
||||||
|
void add_data(int step, double data);
|
||||||
|
int get_index() const { return index; };
|
||||||
|
|
||||||
|
private:
|
||||||
|
int last_step, index;
|
||||||
QtCharts::QChart *chart;
|
QtCharts::QChart *chart;
|
||||||
QtCharts::QLineSeries *series;
|
QtCharts::QLineSeries *series;
|
||||||
QtCharts::QValueAxis *xaxis;
|
QtCharts::QValueAxis *xaxis;
|
||||||
|
|||||||
@ -414,15 +414,26 @@ void LammpsGui::logupdate()
|
|||||||
else
|
else
|
||||||
step = (int)*(int64_t *)ptr;
|
step = (int)*(int64_t *)ptr;
|
||||||
int ncols = *(int *)lammps.last_thermo("num", 0);
|
int ncols = *(int *)lammps.last_thermo("num", 0);
|
||||||
if (!chartwindow->has_columns()) {
|
if (!chartwindow->has_charts()) {
|
||||||
// for (int i = 0; i < ncols; ++i) {
|
for (int i = 0; i < ncols; ++i) {
|
||||||
chartwindow->add_column((const char *)lammps.last_thermo("keyword", 1));
|
QString label = (const char *)lammps.last_thermo("keyword", i);
|
||||||
// }
|
// no need to store the timestep column
|
||||||
|
if (label == "Step") continue;
|
||||||
|
chartwindow->add_chart(label, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (int i = 0; i < ncols; ++i) {
|
for (int i = 0; i < ncols; ++i) {
|
||||||
chartwindow->add_data(step, 0, *(double *)lammps.last_thermo("data", 1));
|
int datatype = *(int *)lammps.last_thermo("type", i);
|
||||||
// }
|
double data;
|
||||||
|
if (datatype == 0) // int
|
||||||
|
data = *(int *)lammps.last_thermo("data", i);
|
||||||
|
else if (datatype == 2) // double
|
||||||
|
data = *(double *)lammps.last_thermo("data", i);
|
||||||
|
else if (datatype == 4) // bigint
|
||||||
|
data = (double)*(int64_t *)lammps.last_thermo("data", i);
|
||||||
|
chartwindow->add_data(step, data, i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -458,15 +469,23 @@ void LammpsGui::run_done()
|
|||||||
else
|
else
|
||||||
step = (int)*(int64_t *)ptr;
|
step = (int)*(int64_t *)ptr;
|
||||||
int ncols = *(int *)lammps.last_thermo("num", 0);
|
int ncols = *(int *)lammps.last_thermo("num", 0);
|
||||||
if (!chartwindow->has_columns()) {
|
for (int i = 0; i < ncols; ++i) {
|
||||||
// for (int i = 0; i < ncols; ++i) {
|
if (!chartwindow->has_charts()) {
|
||||||
chartwindow->add_column((const char *)lammps.last_thermo("keyword", 1));
|
QString label = (const char *)lammps.last_thermo("keyword", i);
|
||||||
// }
|
// no need to store the timestep column
|
||||||
|
if (label == "Step") continue;
|
||||||
|
chartwindow->add_chart(label, i);
|
||||||
|
}
|
||||||
|
int datatype = *(int *)lammps.last_thermo("type", i);
|
||||||
|
double data;
|
||||||
|
if (datatype == 0) // int
|
||||||
|
data = *(int *)lammps.last_thermo("data", i);
|
||||||
|
else if (datatype == 2) // double
|
||||||
|
data = *(double *)lammps.last_thermo("data", i);
|
||||||
|
else if (datatype == 4) // bigint
|
||||||
|
data = (double)*(int64_t *)lammps.last_thermo("data", i);
|
||||||
|
chartwindow->add_data(step, data, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (int i = 0; i < ncols; ++i) {
|
|
||||||
chartwindow->add_data(step, 0, *(double *)lammps.last_thermo("data", 1));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -552,13 +571,13 @@ void LammpsGui::run_buffer()
|
|||||||
|
|
||||||
// if configured, delete old log window before opening new one
|
// if configured, delete old log window before opening new one
|
||||||
if (settings.value("chartreplace", false).toBool()) delete chartwindow;
|
if (settings.value("chartreplace", false).toBool()) delete chartwindow;
|
||||||
chartwindow = new ChartViewer();
|
chartwindow = new ChartWindow(current_file);
|
||||||
chartwindow->setWindowTitle("LAMMPS-GUI - Thermo charts from running LAMMPS on buffer - " +
|
chartwindow->setWindowTitle("LAMMPS-GUI - Thermo charts from running LAMMPS on buffer - " +
|
||||||
current_file);
|
current_file);
|
||||||
chartwindow->setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
|
chartwindow->setWindowIcon(QIcon(":/lammps-icon-128x128.png"));
|
||||||
chartwindow->setMinimumSize(400, 300);
|
chartwindow->setMinimumSize(400, 300);
|
||||||
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), chartwindow);
|
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), chartwindow);
|
||||||
QObject::connect(shortcut, &QShortcut::activated, chartwindow, &ChartViewer::close);
|
QObject::connect(shortcut, &QShortcut::activated, chartwindow, &ChartWindow::close);
|
||||||
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Slash), chartwindow);
|
shortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Slash), chartwindow);
|
||||||
QObject::connect(shortcut, &QShortcut::activated, this, &LammpsGui::stop_run);
|
QObject::connect(shortcut, &QShortcut::activated, this, &LammpsGui::stop_run);
|
||||||
chartwindow->show();
|
chartwindow->show();
|
||||||
|
|||||||
@ -39,7 +39,7 @@ class Highlighter;
|
|||||||
class StdCapture;
|
class StdCapture;
|
||||||
class Preferences;
|
class Preferences;
|
||||||
class ImageViewer;
|
class ImageViewer;
|
||||||
class ChartViewer;
|
class ChartWindow;
|
||||||
|
|
||||||
class LammpsGui : public QMainWindow {
|
class LammpsGui : public QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -86,7 +86,7 @@ private:
|
|||||||
QLabel *status;
|
QLabel *status;
|
||||||
QPlainTextEdit *logwindow;
|
QPlainTextEdit *logwindow;
|
||||||
ImageViewer *imagewindow;
|
ImageViewer *imagewindow;
|
||||||
ChartViewer *chartwindow;
|
ChartWindow *chartwindow;
|
||||||
QTimer *logupdater;
|
QTimer *logupdater;
|
||||||
QLabel *dirstatus;
|
QLabel *dirstatus;
|
||||||
QProgressBar *progress;
|
QProgressBar *progress;
|
||||||
|
|||||||
Reference in New Issue
Block a user