Commit e85d623d authored by Tobias WEBER's avatar Tobias WEBER
Browse files

started with PDF and Gnuplot exporting

parent 023e8dca
......@@ -24,4 +24,4 @@ add_subdirectory(tools/pol)
# (former) main tool
#add_subdirectory(tools/main)
add_subdirectory(tools/main)
......@@ -5,7 +5,7 @@
#
cmake_minimum_required(VERSION 3.0)
project(in20tools)
project(maintool)
message("Build type: ${CMAKE_BUILD_TYPE}")
......@@ -73,13 +73,14 @@ include_directories(
)
add_executable(in20
add_executable(maintool
main.cpp mainwnd.cpp mainwnd.h
filebrowser.cpp filebrowser.h
workspace.cpp workspace.h
data.cpp data.h plot.cpp plot.h
command.cpp command.h
globals.cpp globals.h
hacks.cpp hacks.h
${BISON_cliparser_OUTPUT_SOURCE} ${BISON_cliparser_OUTPUT_HEADER}
${FLEX_clilexer_OUTPUTS} ${FLEX_clilexer_OUTPUT_HEADER}
......@@ -93,7 +94,7 @@ add_executable(in20
)
target_link_libraries(in20
target_link_libraries(maintool
${Boost_LIBRARIES}
Qt5::Core Qt5::Gui Qt5::Widgets Qt5::PrintSupport
-ldl
......
......@@ -603,4 +603,76 @@ Dataset Dataset::norm(std::size_t mon) const
return dataset;
}
/**
* export data to gnuplot
*/
bool Dataset::SaveGpl(const std::string& file) const
{
std::ofstream ofstr(file);
if(!ofstr)
return false;
ofstr.precision(8);
std::size_t N = GetNumChannels();
for(std::size_t ch=0; ch<N; ++ch)
{
const Data& dat = GetChannel(ch);
std::size_t Nx = dat.GetNumAxes();
std::size_t Nc = dat.GetNumCounters();
std::size_t Nm = dat.GetNumMonitors();
// channel empty ?
if(Nx == 0) continue;
// has to be the same for all columns
std::size_t rows = dat.GetCounter(0).size();
ofstr << "$dat_" << ch << " << ENDDATA\n";
for(std::size_t iRow = 0; iRow < rows; ++iRow)
{
// iterate all x axes
for(std::size_t iX = 0; iX < Nx; ++iX)
{
const auto& vec = dat.GetAxis(iX);
for(auto d : vec)
ofstr << d << "\t";
}
// iterate all counters
for(std::size_t iC = 0; iC < Nc; ++iC)
{
const auto& vec = dat.GetCounter(iC);
const auto& vecErr = dat.GetCounterErrors(iC);
for(std::size_t iVec = 0; iVec<vec.size(); ++iVec)
ofstr << vec[iVec] << "\t" << vecErr[iVec] << "\t";
}
// iterate all monitors
for(std::size_t iM = 0; iM < Nm; ++iM)
{
const auto& vec = dat.GetMonitor(iM);
const auto& vecErr = dat.GetMonitorErrors(iM);
for(std::size_t iVec = 0; iVec<vec.size(); ++iVec)
ofstr << vec[iVec] << "\t" << vecErr[iVec] << "\t";
}
ofstr << "\n";
}
ofstr << "ENDDATA\n";
}
return true;
}
// ----------------------------------------------------------------------------
......@@ -142,6 +142,9 @@ public:
public:
Dataset norm(std::size_t mon = 0) const;
// export to gnuplot
bool SaveGpl(const std::string& file) const;
// binary operators
friend Dataset operator +(const Dataset& dat1, const Dataset& dat2);
......
/**
* hacks
* @author Tobias Weber <tweber@ill.fr>
* @date 29-Aug-2019
* @license see 'LICENSE' file
*/
#include <string>
#include <locale>
#include "hacks.h"
/**
* function to prevent boost.filesystem linking error
*/
namespace boost{ namespace filesystem{ namespace path_traits{
void convert(const wchar_t *begin, const wchar_t *end,
std::string& str, const std::codecvt<wchar_t, char, std::mbstate_t>& cvt)
{
std::size_t len = end-begin;
str.resize(len);
std::mbstate_t state;
const wchar_t* in_next = nullptr;
char* out_next = nullptr;
cvt.out(state, begin, end, in_next, str.data(), str.data()+len, out_next);
}
}}}
/**
* hacks
* @author Tobias Weber <tweber@ill.fr>
* @date 29-aug-19
* @license see 'LICENSE' file
*/
#ifndef __MAGTOOLS_HACKS_H__
#define __MAGTOOLS_HACKS_H__
#endif
......@@ -30,7 +30,7 @@ MainWnd::MainWnd(QSettings* pSettings)
m_pBrowser(new FileBrowser(this, pSettings)),
m_pWS(new WorkSpace(this, pSettings)),
m_pCLI(new CommandLine(this, pSettings)),
m_pCurPlot(new PlotterDock(this))
m_pCurPlot(new PlotterDock(this, pSettings))
{
// the command line widget has to be accessible globally for error output
g_pCLI = m_pCLI;
......
......@@ -6,19 +6,30 @@
*/
#include "plot.h"
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QFileDialog>
#include <QtWidgets/QMessageBox>
using t_real = t_real_dat;
Plotter::Plotter(QWidget *parent) : QWidget(parent)
Plotter::Plotter(QWidget *parent, QSettings* pSettings) : QWidget(parent), m_pSettings(pSettings)
{
auto *pGrid = new QGridLayout(this);
pGrid->setHorizontalSpacing(4);
pGrid->setVerticalSpacing(4);
pGrid->setContentsMargins(0,0,0,0);
pGrid->addWidget(m_pPlotter, 0, 0, 1, 1);
m_pPlotContextMenu->setTitle("Plot");
m_pPlotContextMenu->addAction("Export to Gnuplot...", this, &Plotter::SaveGpl);
m_pPlotContextMenu->addAction("Save as PDF...", this, &Plotter::SavePDF);
m_pPlotter->setContextMenuPolicy(Qt::CustomContextMenu);
connect(m_pPlotter, &QCustomPlot::customContextMenuRequested, this, &Plotter::ShowPlotContextMenu);
}
......@@ -28,9 +39,75 @@ Plotter::~Plotter()
}
/**
* show the context menu for the plotter
*/
void Plotter::ShowPlotContextMenu(const QPoint& pt)
{
auto ptGlob = m_pPlotter->mapToGlobal(pt);
ptGlob.setY(ptGlob.y() + 8);
m_pPlotContextMenu->popup(ptGlob);
}
/**
* save plot as PDF file
*/
void Plotter::SavePDF()
{
QString dirLast = "";
if(m_pSettings)
m_pSettings->value("dir_pdf", "").toString();
QString file = QFileDialog::getSaveFileName(this, "Save as PDF", dirLast, "PDF Files (*.pdf *.PDF)");
if(file=="")
return;
if(!m_pPlotter->savePdf(file))
{
QMessageBox::critical(this, "PDF Export", "Could not save PDF file.");
return;
}
if(m_pSettings)
m_pSettings->setValue("dir_pdf", QFileInfo(file).path());
}
/**
* export plot to Gnuplot
*/
void Plotter::SaveGpl()
{
if(!m_pdataset)
{
QMessageBox::critical(this, "Gnuplot Export", "No dataset associated to plot.");
return;
}
QString dirLast = "";
if(m_pSettings)
m_pSettings->value("dir_gpl", "").toString();
QString file = QFileDialog::getSaveFileName(this, "Export to Gnuplot", dirLast, "Gnuplot Files (*.gpl *.GPL)");
if(file=="")
return;
if(!m_pdataset->SaveGpl(file.toStdString()))
{
QMessageBox::critical(this, "Gnuplot Export", "Could not save Gnuplot file.");
return;
}
if(m_pSettings)
m_pSettings->setValue("dir_gpl", QFileInfo(file).path());
}
void Plotter::Clear()
{
m_pPlotter->clearGraphs();
m_pdataset = nullptr;
}
......@@ -44,6 +121,7 @@ void Plotter::Plot(const Dataset &dataset)
};
Clear();
m_pdataset = &dataset;
t_real xmin = std::numeric_limits<t_real>::max();
t_real xmax = -xmin;
......@@ -127,8 +205,8 @@ void Plotter::Plot(const Dataset &dataset)
// ----------------------------------------------------------------------------
// dock
PlotterDock::PlotterDock(QWidget* pParent)
: QDockWidget(pParent), m_pPlot(std::make_unique<Plotter>(this))
PlotterDock::PlotterDock(QWidget* pParent, QSettings* pSettings)
: QDockWidget(pParent), m_pPlot(std::make_unique<Plotter>(this, pSettings))
{
this->setObjectName("plotter");
this->setWindowTitle("Current Plot");
......
......@@ -8,19 +8,29 @@
#ifndef __PLOT_H__
#define __PLOT_H__
#include <QtCore/QSettings>
#include <QtWidgets/QWidget>
#include <QtWidgets/QMenu>
#include "qcp/qcustomplot.h"
#include "data.h"
class Plotter : public QWidget
{
private:
QSettings *m_pSettings = nullptr;
QCustomPlot *m_pPlotter = new QCustomPlot(this);
QMenu *m_pPlotContextMenu = new QMenu(m_pPlotter);
// current dataset
const Dataset* m_pdataset = nullptr;
public:
Plotter(QWidget *parent);
Plotter(QWidget *parent, QSettings* = nullptr);
virtual ~Plotter();
QCustomPlot* GetPlotter() { return m_pPlotter; }
......@@ -28,6 +38,11 @@ public:
void Plot(const Dataset &dataset);
void Clear();
void ShowPlotContextMenu(const QPoint& pt);
void SavePDF();
void SaveGpl();
};
......@@ -41,11 +56,12 @@ private:
std::unique_ptr<Plotter> m_pPlot;
public:
PlotterDock(QWidget* pParent = nullptr);
PlotterDock(QWidget* pParent = nullptr, QSettings* = nullptr);
virtual ~PlotterDock();
const Plotter* GetWidget() const { return m_pPlot.get(); }
Plotter* GetWidget() { return m_pPlot.get(); }
};
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment