diff --git a/src/backend/generalTest/GeneralTest.cpp b/src/backend/generalTest/GeneralTest.cpp index 49e5b6618..a7be0b2ca 100644 --- a/src/backend/generalTest/GeneralTest.cpp +++ b/src/backend/generalTest/GeneralTest.cpp @@ -1,575 +1,589 @@ /*************************************************************************** File : GeneralTest.cpp Project : LabPlot Description : Doing Hypothesis-Test on data provided -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "GeneralTest.h" #include "kdefrontend/generalTest/HypothesisTestView.h" #include "backend/spreadsheet/Spreadsheet.h" #include "backend/core/column/Column.h" #include "backend/lib/macros.h" #include "backend/generalTest/MyTableModel.h" #include #include #include #include #include #include extern "C" { #include "backend/nsl/nsl_stats.h" } GeneralTest::GeneralTest(const QString& name, const AspectType& type) : AbstractPart(name, type), m_summaryLayout(new QVBoxLayout()), m_inputStatsTableModel(new MyTableModel()) { for (int i = 0; i < RESULTLINESCOUNT; i++) { m_resultLine[i] = new QLabel(); m_summaryLayout->addWidget(m_resultLine[i]); } } GeneralTest::~GeneralTest() { } void GeneralTest::setDataSourceType(DataSourceType type) { if (type != m_dataSourceType) m_dataSourceType = type; } GeneralTest::DataSourceType GeneralTest::dataSourceType() const { return m_dataSourceType; } void GeneralTest::setDataSourceSpreadsheet(Spreadsheet* spreadsheet) { m_dataSourceSpreadsheet = spreadsheet; for (auto* col : m_dataSourceSpreadsheet->children()) m_allColumns << col->name(); } QString GeneralTest::testName() { return m_currTestName; } QString GeneralTest::statsTable() { return m_statsTable; } QVBoxLayout* GeneralTest::summaryLayout() { return m_summaryLayout; } QAbstractItemModel* GeneralTest::inputStatsTableModel() { return m_inputStatsTableModel; } void GeneralTest::setColumns(QStringList cols) { m_columns.clear(); Column* column = new Column("column"); for (QString col : cols) { if (!cols.isEmpty()) { column = m_dataSourceSpreadsheet->column(col); m_columns.append(column); } } delete column; } void GeneralTest::setColumns(const QVector &cols) { m_columns = cols; } /******************************************************************************************************************** * Protected functions implementations [Helper Functions] ********************************************************************************************************************/ int GeneralTest::testType(int test) { return test & 0x0F; } int GeneralTest::testSubtype(int test) { return test & 0xF0; } //TODO: we should implement or use a general round method QString GeneralTest::round(QVariant number, int precision) { if (number.userType() == QMetaType::Double || number.userType() == QMetaType::Float) { double multiplierPrecision = gsl_pow_int(10, precision); int tempNum = int(number.toDouble()*multiplierPrecision*10); if (tempNum % 10 < 5) return QString::number((tempNum/10) / multiplierPrecision); else return QString::number((tempNum/10 + 1) / multiplierPrecision); } return i18n("%1", number.toString()); } //TODO: Doesn't Column already have a function for this? int GeneralTest::findCount(const Column *column) { int N = column->rowCount(); switch (column->columnMode()) { case (AbstractColumn::Numeric): case (AbstractColumn::Integer): { for (int i = 0; i < N; i++) if (std::isnan(column->valueAt(i))) { N = i; break; } break; } case (AbstractColumn::Month): case (AbstractColumn::Day): case (AbstractColumn::Text): { for (int i = 0; i < N; i++) if (column->textAt(i).isEmpty()) { N = i; break; } break; } case (AbstractColumn::DateTime): break; } return N; } // TODO: put into Column double GeneralTest::findSum(const Column *column, int N) { if (!column->isNumeric()) return 0; if (N < 0) N = findCount(column); double sum = 0; for (int i = 0; i < N; i++) sum += column->valueAt(i); return sum; } // TODO: put into Column double GeneralTest::findSumSq(const Column *column, int N) { if (!column->isNumeric()) return 0; if (N < 0) N = findCount(column); double sumSq = 0; for (int i = 0; i < N; i++) sumSq += gsl_pow_2(column->valueAt(i)); return sumSq; } // TODO: put into Column double GeneralTest::findMean(const Column *column, int N) { if (!column->isNumeric()) return 0; if (N < 0) N = findCount(column); double sum = findSum(column, N); return sum / N; } // TODO: put into Column double GeneralTest::findStd(const Column *column, int N, double mean) { if (!column->isNumeric()) return 0; double std = 0; for (int i = 0; i < N; i++) { double row = column->valueAt(i); std += gsl_pow_2(row - mean); } if (N > 1) std = std / (N-1); std = sqrt(std); return std; } // TODO: put into Column double GeneralTest::findStd(const Column *column, int N) { if (!column->isNumeric()) return 0; if (N < 0) N = findCount(column); double mean = findMean(column, N); return findStd(column, N, mean); } GeneralTest::GeneralErrorType GeneralTest::findStats(const Column* column, int& count, double& sum, double& mean, double& std) { count = findCount(column); sum = findSum(column, count); mean = findMean(column, count); std = findStd(column, count, mean); if (count < 1) return GeneralTest::ErrorEmptyColumn; return GeneralTest::NoError; } GeneralTest::GeneralErrorType GeneralTest::findStatsPaired(const Column* column1, const Column* column2, int& count, double& sum, double& mean, double& std) { sum = 0; mean = 0; std = 0; int count1 = column1->rowCount(); int count2 = column2->rowCount(); count = qMin(count1, count2); double HtmlCell1, HtmlCell2; for (int i = 0; i < count; i++) { HtmlCell1 = column1->valueAt(i); HtmlCell2 = column2->valueAt(i); if (std::isnan(HtmlCell1) || std::isnan(HtmlCell2)) { if (std::isnan(HtmlCell1) && std::isnan(HtmlCell2)) count = i; else return GeneralTest::ErrorUnqualSize; break; } sum += HtmlCell1 - HtmlCell2; } if (count < 1) return GeneralTest::ErrorEmptyColumn; mean = sum / count; double row; for (int i = 0; i < count; i++) { HtmlCell1 = column1->valueAt(i); HtmlCell2 = column2->valueAt(i); row = HtmlCell1 - HtmlCell2; std += gsl_pow_2( (row - mean)); } if (count > 1) std = std / (count-1); std = sqrt(std); return GeneralTest::NoError; } void GeneralTest::countPartitions(Column* column, int& np, int& totalRows) { totalRows = column->rowCount(); np = 0; QString HtmlCellValue; QMap discoveredCategoricalVar; AbstractColumn::ColumnMode originalColMode = column->columnMode(); column->setColumnMode(AbstractColumn::Text); for (int i = 0; i < totalRows; i++) { HtmlCellValue = column->textAt(i); if (HtmlCellValue.isEmpty()) { totalRows = i; break; } if (discoveredCategoricalVar[HtmlCellValue]) continue; discoveredCategoricalVar[HtmlCellValue] = true; np++; } column->setColumnMode(originalColMode); } GeneralTest::GeneralErrorType GeneralTest::findStatsCategorical(Column* column1, Column* column2, int n[], double sum[], double mean[], double std[], QMap& colName, const int& np, const int& totalRows) { Column* columns[] = {column1, column2}; for (int i = 0; i < np; i++) { n[i] = 0; sum[i] = 0; mean[i] = 0; std[i] = 0; } AbstractColumn::ColumnMode originalColMode = columns[0]->columnMode(); columns[0]->setColumnMode(AbstractColumn::Text); int partitionNumber = 1; for (int i = 0; i < totalRows; i++) { QString name = columns[0]->textAt(i); double value = columns[1]->valueAt(i); if (std::isnan(value)) { columns[0]->setColumnMode(originalColMode); return GeneralTest::ErrorUnqualSize; } if (colName[name] == 0) { colName[name] = partitionNumber; partitionNumber++; } n[colName[name]-1]++; sum[colName[name]-1] += value; } for (int i = 0; i < np; i++) mean[i] = sum[i] / n[i]; for (int i = 0; i < totalRows; i++) { QString name = columns[0]->textAt(i); double value = columns[1]->valueAt(i); std[colName[name]-1] += gsl_pow_2( (value - mean[colName[name]-1])); } for (int i = 0; i < np; i++) { if (n[i] > 1) std[i] = std[i] / (n[i] - 1); std[i] = sqrt(std[i]); } columns[0]->setColumnMode(originalColMode); if (columns[0]->isNumeric()) { } return GeneralTest::NoError; } QString GeneralTest::getHtmlTable(int row, int column, QVariant* rowMajor) { if (row < 1 || column < 1) return QString(); QString table; table = "" "" " "; QString bg = "tg-0pky"; bool pky = true; QString element; table += " "; for (int j = 0; j < column; j++) { element = rowMajor[j].toString(); table += " "; } table += " "; if (pky) bg = "tg-0pky"; else bg = "tg-btxf"; pky = !pky; for (int i = 1; i < row; i++) { table += " "; QString element = round(rowMajor[i*column]); table += " "; for (int j = 1; j < column; j++) { element = round(rowMajor[i*column+j]); table += " "; } table += " "; if (pky) bg = "tg-0pky"; else bg = "tg-btxf"; pky = !pky; } table += "
" + i18n("%1", element) + "
" + i18n("%1", element) + "" + i18n("%1", element) + "
"; return table; } QString GeneralTest::getHtmlTable3(const QList& rowMajor) { int rowMajorSize = rowMajor.size(); if (rowMajorSize == 0) return QString(); QString startToolTip = "[tooltip]"; QString endToolTip = "[/tooltip]"; QString startData = "[data]"; QString endData = "[/data]"; QString startTip = "[tip]"; QString endTip = "[/tip]"; QString table; table = ""; table += ""; table += " "; int prevLevel = 0; for (int i = 0; i < rowMajorSize; i++) { HtmlCell* currHtmlCell = rowMajor[i]; if (currHtmlCell->level != prevLevel) { table += " "; table += " "; prevLevel = currHtmlCell->level; } QString HtmlCellStartTag = ""; table += "
isHeader) { HtmlCellStartTag = "data); if (!currHtmlCell->tooltip.isEmpty()) HtmlCellData = startToolTip+ startData+HtmlCellData+endData+ startTip+i18n("%1", currHtmlCell->tooltip)+endTip+ endToolTip; table += HtmlCellStartTag + "rowspan=" + QString::number(currHtmlCell->rowSpanCount) + " " + "colspan=" + QString::number(currHtmlCell->columnSpanCount) + ">" + HtmlCellData + HtmlCellEndTag; } table += "
"; return table; } QString GeneralTest::getLine(const QString& msg, const QString& color) { return "

" + i18n("%1", msg) + "

"; } void GeneralTest::printLine(const int& index, const QString& msg, const QString& color) { if (index < 0 || index >= 10) return; m_resultLine[index]->setText(getLine(msg, color)); return; } void GeneralTest::printTooltip(const int &index, const QString &msg) { if (index < 0 || index >= 10) return; m_resultLine[index]->setToolTip(i18n("%1", msg)); } void GeneralTest::printError(const QString& errorMsg) { printLine(0, errorMsg, "red"); } /******************************************************************************************************************** * virtual functions implementations ********************************************************************************************************************/ /*! Saves as XML. */ void GeneralTest::save(QXmlStreamWriter* writer) const { writer->writeStartElement("GeneralTest"); writeBasicAttributes(writer); writeCommentElement(writer); writer->writeEndElement(); } /*! Loads from XML. */ bool GeneralTest::load(XmlStreamReader* reader, bool preview) { Q_UNUSED(preview); if (!readBasicAttributes(reader)) return false; return !reader->hasError(); } +void GeneralTest::clearInputStatsTable() { +// int rowCount = m_inputStatsTableModel->rowCount(); +// int columnCount = m_inputStatsTableModel->columnCount(); + + QList horizontalHeader = m_inputStatsTableModel->takeRow(0); + QList verticalHeader = m_inputStatsTableModel->takeColumn(0); + + m_inputStatsTableModel->clear(); + m_inputStatsTableModel->appendRow(horizontalHeader); + + verticalHeader.push_front(m_inputStatsTableModel->takeColumn(0)[0]); + m_inputStatsTableModel->insertColumn(0, verticalHeader); +} + Spreadsheet *GeneralTest::dataSourceSpreadsheet() const { return m_dataSourceSpreadsheet; } bool GeneralTest::exportView() const { return true; } bool GeneralTest::printView() { return true; } bool GeneralTest::printPreview() const { return true; } /*! Constructs a primary view on me. This method may be called multiple times during the life time of an Aspect, or it might not get called at all. Aspects must not depend on the existence of a view for their operation. */ //QWidget* GeneralTest::view() const { // if (!m_partView) { // m_view = new HypothesisTestView(const_cast(this)); // m_partView = m_view; // } // return m_partView; //} /*! Returns a new context menu. The caller takes ownership of the menu. */ QMenu* GeneralTest::createContextMenu() { QMenu* menu = AbstractPart::createContextMenu(); // Q_ASSERT(menu); // emit requestProjectContextMenu(menu); return menu; } diff --git a/src/backend/generalTest/GeneralTest.h b/src/backend/generalTest/GeneralTest.h index 83020f12d..e577ab816 100644 --- a/src/backend/generalTest/GeneralTest.h +++ b/src/backend/generalTest/GeneralTest.h @@ -1,150 +1,153 @@ /*************************************************************************** File : GeneralTest.h Project : LabPlot Description : Doing Hypothesis-Test on data provided -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef GENERALTEST_H #define GENERALTEST_H #include "backend/core/AbstractPart.h" #include "backend/lib/macros.h" #include "kdefrontend/generalTest/GeneralTestView.h" class Spreadsheet; class QString; class Column; class QVBoxLayout; class QLabel; class QAbstractItemModel; class MyTableModel; class GeneralTest : public AbstractPart { Q_OBJECT public: explicit GeneralTest(const QString& name, const AspectType& type); ~GeneralTest() override; enum DataSourceType {DataSourceSpreadsheet, DataSourceDatabase}; struct HtmlCell { QString data; int level; bool isHeader; QString tooltip; int rowSpanCount; int columnSpanCount; HtmlCell(QVariant data = "", int level = 0, bool isHeader = false, QString tooltip = "", int rowSpanCount = 1, int columnSpanCount = 1) { this->data = data.toString(); this->level = level; this->isHeader = isHeader; this->tooltip = tooltip; this->rowSpanCount = rowSpanCount; this->columnSpanCount = columnSpanCount; } }; enum GeneralErrorType {ErrorUnqualSize, ErrorEmptyColumn, NoError}; void setDataSourceType(DataSourceType type); DataSourceType dataSourceType() const; void setDataSourceSpreadsheet(Spreadsheet* spreadsheet); Spreadsheet* dataSourceSpreadsheet() const; void setColumns(const QVector& cols); void setColumns(QStringList cols); QStringList allColumns(); QString testName(); QString statsTable(); QVBoxLayout* summaryLayout(); QAbstractItemModel* inputStatsTableModel(); //virtual methods // QIcon icon() const override; QMenu* createContextMenu() override; // QWidget* view() const override; bool exportView() const override; bool printView() override; bool printPreview() const override; void save(QXmlStreamWriter*) const override; bool load(XmlStreamReader*, bool preview) override; +public slots: + void clearInputStatsTable(); + signals: void changed(); void requestProjectContextMenu(QMenu*); void dataSourceTypeChanged(GeneralTest::DataSourceType); void dataSourceSpreadsheetChanged(Spreadsheet*); protected: DataSourceType m_dataSourceType{GeneralTest::DataSourceSpreadsheet}; Spreadsheet* m_dataSourceSpreadsheet{nullptr}; QVector m_columns; QStringList m_allColumns; QString m_currTestName; QString m_statsTable; QVBoxLayout* m_summaryLayout{nullptr}; QLabel* m_resultLine[RESULTLINESCOUNT]; MyTableModel* m_inputStatsTableModel; int testType(int test); int testSubtype(int test); QString round(QVariant number, int precision = 3); int findCount(const Column* column); double findSum(const Column* column, int N = -1); double findSumSq(const Column* column, int N = -1); double findMean(const Column* column, int N = -1); double findStd(const Column* column, int N, double mean); double findStd(const Column* column, int N = -1); void countPartitions(Column* column, int& np, int& totalRows); // double findSumProducts(const Column* columns[], int N = -1); GeneralErrorType findStats(const Column* column,int& count, double& sum, double& mean, double& std); GeneralErrorType findStatsPaired(const Column* column1, const Column* column2, int& count, double& sum, double& mean, double& std); GeneralErrorType findStatsCategorical(Column* column1, Column* column2, int n[], double sum[], double mean[], double std[], QMap& colName, const int& np, const int& totalRows); QString getHtmlTable(int row, int column, QVariant* rowMajor); QString getHtmlTable3(const QList& rowMajor); QString getLine(const QString& msg, const QString& color = "black"); void printLine(const int& index, const QString& msg, const QString& color = "black"); void printTooltip(const int& index, const QString& msg); void printError(const QString& errorMsg); bool m_dbCreated{false}; mutable GeneralTestView* m_view{nullptr}; }; #endif // GeneralTest_H diff --git a/src/backend/generalTest/HypothesisTest.h b/src/backend/generalTest/HypothesisTest.h index a79d1da51..5c7f1e3d6 100644 --- a/src/backend/generalTest/HypothesisTest.h +++ b/src/backend/generalTest/HypothesisTest.h @@ -1,90 +1,88 @@ /*************************************************************************** File : HypothesisTest.h Project : LabPlot Description : Doing Hypothesis-Test on data provided -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef HYPOTHESISTEST_H #define HYPOTHESISTEST_H #include "GeneralTest.h" class HypothesisTest : public GeneralTest { Q_OBJECT public: explicit HypothesisTest(const QString& name); ~HypothesisTest() override; enum HypothesisTestType { // Type TTest = 0x01, ZTest = 0x02, Anova = 0x03, // SubType TwoSampleIndependent = 0x10, TwoSamplePaired = 0x20, OneSample = 0x30, OneWay = 0x40, TwoWay = 0x50 }; enum HypothesisTailType {Positive, Negative, Two}; void setPopulationMean(QVariant populationMean); void setSignificanceLevel(QVariant alpha); void setTail(HypothesisTailType tail); void performTest(int test, bool categoricalVariable = true, bool equalVariance = true, bool calculateStats = true); void performLeveneTest(bool categoricalVariable); void initInputStatsTable(int test, bool calculateStats); QList& statisticValue(); QList& pValue(); QWidget* view() const override; - double myTest; - private: void performTwoSampleIndependentTest(int test, bool categoricalVariable = false, bool equalVariance = true, bool calculateStats = true); void performTwoSamplePairedTest(int test); void performOneSampleTest(int test); void performOneWayAnova(); void performTwoWayAnova(); void m_performLeveneTest(bool categoricalVariable); double getPValue(const int &test, double& value, const QString& col1Name, const QString& col2name, const int df); QString getPValueTooltip(const double& pValue); double m_populationMean; double m_significanceLevel; HypothesisTailType m_tail; QList m_pValue; QList m_statisticValue; }; #endif // HypothesisTest_H diff --git a/src/kdefrontend/generalTest/GeneralTestView.cpp b/src/kdefrontend/generalTest/GeneralTestView.cpp index 30610c431..bd58357f5 100644 --- a/src/kdefrontend/generalTest/GeneralTestView.cpp +++ b/src/kdefrontend/generalTest/GeneralTestView.cpp @@ -1,225 +1,230 @@ /*************************************************************************** - File : GeneralTestView.cpp - Project : LabPlot - Description : View class for Hypothesis Tests' Table - -------------------------------------------------------------------- - Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) + File : GeneralTestView.cpp + Project : LabPlot + Description : View class for Hypothesis Tests' Table + -------------------------------------------------------------------- + Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "GeneralTestView.h" #include "backend/generalTest/GeneralTest.h" #include "backend/lib/macros.h" #include "backend/lib/trace.h" #include "backend/generalTest/MyTextEdit.h" #include #include #include #include #include #include #include #include #include +#include +#include #include /*! - \class GeneralTestView - \brief View class for Hypothesis Test + \class GeneralTestView + \brief View class for Hypothesis Test - \ingroup kdefrontend + \ingroup kdefrontend */ GeneralTestView::GeneralTestView(GeneralTest* GeneralTest) : QWidget(), m_generalTest(GeneralTest), m_testName(new QLabel()), m_statsTable(new MyTextEdit()), m_summaryResults(new QWidget()), + m_inputStatsWidget(new QWidget()), + m_labelInputStatsTable(new QLabel()), m_inputStatsTable(new QTableView()), - m_labelInputStatsTable(new QLabel()) { + m_clearInputStats(new QPushButton()) { + + QVBoxLayout * inputStatsLayout = new QVBoxLayout(m_inputStatsWidget); + inputStatsLayout->addWidget(m_labelInputStatsTable); + inputStatsLayout->addWidget(m_inputStatsTable); + inputStatsLayout->addWidget(m_clearInputStats); m_statsTable->setReadOnly(true); m_testName->setStyleSheet("background-color: white"); m_statsTable->setStyleSheet("background-color: white"); m_summaryResults->setStyleSheet("QToolTip { color: black; background-color: yellow; border: 0px; }"); - m_inputStatsTable->setStyleSheet("background-color: white"); - m_labelInputStatsTable->setStyleSheet("backgroud-color: white"); + m_inputStatsWidget->setStyleSheet("background-color: white"); m_testName->hide(); m_statsTable->hide(); m_summaryResults->hide(); - m_inputStatsTable->hide(); + m_inputStatsWidget->hide(); auto* layout = new QVBoxLayout(this); m_labelInputStatsTable->setText("

" + i18n("Statistic Table")); m_labelInputStatsTable->setToolTip(i18n("Fill this table with pre-calculated statistic value and then press recalculate") + - "

" + - i18n("You can leave one or more columns empty if you feel they are not useful") + - "

"); - m_labelInputStatsTable->hide(); + "

" + + i18n("You can leave one or more columns empty if you feel they are not useful") + + ""); + m_clearInputStats->setText(i18n("Clear")); + m_clearInputStats->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed)); - layout->addWidget(m_labelInputStatsTable); - layout->addWidget(m_inputStatsTable); + layout->addWidget(m_inputStatsWidget); layout->addWidget(m_testName); layout->addWidget(m_statsTable); layout->addWidget(m_summaryResults); layout->addStretch(1); init(); } GeneralTestView::~GeneralTestView() { } void GeneralTestView::init() { initActions(); initMenus(); m_inputStatsTable->setModel(m_generalTest->inputStatsTableModel()); m_inputStatsTable->horizontalHeader()->setVisible(false); m_inputStatsTable->verticalHeader()->setVisible(false); m_inputStatsTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); m_statsTable->setMouseTracking(true); connect(m_generalTest, &GeneralTest::changed, this, &GeneralTestView::changed); + connect(m_clearInputStats, &QPushButton::clicked, m_generalTest, &GeneralTest::clearInputStatsTable); } void GeneralTestView::initActions() { } void GeneralTestView::initMenus() { } void GeneralTestView::clearResult() { for (int i = 0; i < RESULTLINESCOUNT; i++) m_resultLine[i]->clear(); } void GeneralTestView::connectActions() { } void GeneralTestView::fillToolBar(QToolBar* toolBar) { Q_UNUSED(toolBar); } /*! * Populates the menu \c menu with the pivot table and pivot table view relevant actions. * The menu is used * - as the context menu in PivotTableView * - as the "pivot table menu" in the main menu-bar (called form MainWin) * - as a part of the pivot table context menu in project explorer */ void GeneralTestView::createContextMenu(QMenu* menu) { Q_ASSERT(menu); } bool GeneralTestView::exportView() { return true; } bool GeneralTestView::printView() { QPrinter printer; auto* dlg = new QPrintDialog(&printer, this); dlg->setWindowTitle(i18nc("@title:window", "Print Spreadsheet")); bool ret; if ((ret = dlg->exec()) == QDialog::Accepted) print(&printer); delete dlg; return ret; } bool GeneralTestView::printPreview() { QPrintPreviewDialog* dlg = new QPrintPreviewDialog(this); connect(dlg, &QPrintPreviewDialog::paintRequested, this, &GeneralTestView::print); return dlg->exec(); } /*! prints the complete spreadsheet to \c printer. */ void GeneralTestView::print(QPrinter* printer) const { WAIT_CURSOR; QPainter painter (printer); RESET_CURSOR; } void GeneralTestView::changed() { m_testName->setText(m_generalTest->testName()); m_testName->show(); m_summaryResults->show(); if (m_generalTest->statsTable().isEmpty()) m_statsTable->hide(); else { m_statsTable->setHtml(m_generalTest->statsTable()); m_statsTable->show(); } m_summaryResults->setLayout(m_generalTest->summaryLayout()); if (m_inputStatsTable->model()->rowCount() > 0 && - m_inputStatsTable->model()->columnCount() > 0) { - m_inputStatsTable->show(); - m_labelInputStatsTable->show(); - } - else { - m_inputStatsTable->hide(); - m_labelInputStatsTable->hide(); - } + m_inputStatsTable->model()->columnCount() > 0) + m_inputStatsWidget->show(); + else + m_inputStatsWidget->hide(); } void GeneralTestView::exportToFile(const QString& path, const bool exportHeader, const QString& separator, QLocale::Language language) const { Q_UNUSED(exportHeader); Q_UNUSED(separator); Q_UNUSED(language); QFile file(path); if (!file.open(QFile::WriteOnly | QFile::Truncate)) return; PERFTRACE("export pivot table to file"); } void GeneralTestView::exportToLaTeX(const QString & path, const bool exportHeaders, - const bool gridLines, const bool captions, const bool latexHeaders, - const bool skipEmptyRows, const bool exportEntire) const { + const bool gridLines, const bool captions, const bool latexHeaders, + const bool skipEmptyRows, const bool exportEntire) const { Q_UNUSED(exportHeaders); Q_UNUSED(gridLines); Q_UNUSED(captions); Q_UNUSED(latexHeaders); Q_UNUSED(skipEmptyRows); Q_UNUSED(exportEntire); QFile file(path); if (!file.open(QFile::WriteOnly | QFile::Truncate)) return; PERFTRACE("export pivot table to latex"); } diff --git a/src/kdefrontend/generalTest/GeneralTestView.h b/src/kdefrontend/generalTest/GeneralTestView.h index 0df678d29..898a3ec58 100644 --- a/src/kdefrontend/generalTest/GeneralTestView.h +++ b/src/kdefrontend/generalTest/GeneralTestView.h @@ -1,88 +1,91 @@ /*************************************************************************** File : GeneralTestView.h Project : LabPlot Description : View class for Hypothesis Tests' -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef GENERALTESTVIEW_H #define GENERALTESTVIEW_H #include #include "backend/core/AbstractColumn.h" #include "backend/lib/IntervalAttribute.h" class Column; class GeneralTest; class AbstractAspect; class QPrinter; class QToolBar; class QLabel; class MyTextEdit; class QTableView; +class QPushButton; #define RESULTLINESCOUNT 10 class GeneralTestView : public QWidget { Q_OBJECT public: explicit GeneralTestView(GeneralTest*); ~GeneralTestView() override; bool exportView(); bool printView(); bool printPreview(); protected: void init(); void initActions(); void initMenus(); void connectActions(); void exportToFile(const QString&, const bool, const QString&, QLocale::Language) const; void exportToLaTeX(const QString&, const bool exportHeaders, const bool gridLines, const bool captions, const bool latexHeaders, const bool skipEmptyRows,const bool exportEntire) const; GeneralTest* m_generalTest; QLabel* m_testName; MyTextEdit* m_statsTable; QWidget* m_summaryResults{nullptr}; QLabel* m_resultLine[RESULTLINESCOUNT]; - QTableView* m_inputStatsTable; + QWidget* m_inputStatsWidget; QLabel* m_labelInputStatsTable; + QTableView* m_inputStatsTable; + QPushButton* m_clearInputStats; public slots: void createContextMenu(QMenu*); void fillToolBar(QToolBar*); void print(QPrinter*) const; void changed(); void clearResult(); protected slots: }; #endif