1 /*************************************************************************** 2 File : PolynomFitDialog.cpp 3 Project : QtiPlot 4 -------------------------------------------------------------------- 5 Copyright : (C) 2006 - 2011 by Ion Vasilief 6 Email (use @ for *) : ion_vasilief*yahoo.fr 7 Description : Fit polynomial dialog 8 9 ***************************************************************************/ 10 11 /*************************************************************************** 12 * * 13 * This program is free software; you can redistribute it and/or modify * 14 * it under the terms of the GNU General Public License as published by * 15 * the Free Software Foundation; either version 2 of the License, or * 16 * (at your option) any later version. * 17 * * 18 * This program is distributed in the hope that it will be useful, * 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 21 * GNU General Public License for more details. * 22 * * 23 * You should have received a copy of the GNU General Public License * 24 * along with this program; if not, write to the Free Software * 25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 26 * Boston, MA 02110-1301 USA * 27 * * 28 ***************************************************************************/ 29 #include "PolynomFitDialog.h" 30 #include <PolynomialFit.h> 31 #include <Graph.h> 32 #include <ApplicationWindow.h> 33 #include <DoubleSpinBox.h> 34 #include <ColorButton.h> 35 #include <RangeSelectorTool.h> 36 37 #include <QSpinBox> 38 #include <QCheckBox> 39 #include <QMessageBox> 40 #include <QLayout> 41 #include <QGroupBox> 42 #include <QPushButton> 43 #include <QLabel> 44 #include <QComboBox> 45 46 PolynomFitDialog::PolynomFitDialog( QWidget* parent, Qt::WFlags fl ) 47 : QDialog( parent, fl ) 48 { 49 setObjectName( "PolynomFitDialog" ); 50 setWindowTitle(tr("QtiPlot - Polynomial Fit Options")); 51 setAttribute(Qt::WA_DeleteOnClose); 52 setSizeGripEnabled( true ); 53 54 QGroupBox *gb1 = new QGroupBox(); 55 QGridLayout *gl1 = new QGridLayout(gb1); 56 gl1->addWidget(new QLabel(tr("Polynomial Fit of")), 0, 0); 57 58 boxName = new QComboBox(); 59 gl1->addWidget(boxName, 0, 1); 60 61 gl1->addWidget(new QLabel( tr("Order (1 - 9, 1 = linear)")), 1, 0); 62 boxOrder = new QSpinBox(); 63 boxOrder->setRange(1, 9); 64 boxOrder->setValue(2); 65 gl1->addWidget(boxOrder, 1, 1); 66 67 gl1->addWidget(new QLabel( tr("Fit curve # pts")), 2, 0); 68 boxPoints = new QSpinBox(); 69 boxPoints->setRange(1, 1000); 70 boxPoints->setSingleStep(50); 71 boxPoints->setSpecialValueText(tr("Not enough points")); 72 gl1->addWidget(boxPoints, 2, 1); 73 74 ApplicationWindow *app = (ApplicationWindow *)parent; 75 76 gl1->addWidget(new QLabel( tr("Fit curve Xmin")), 3, 0); 77 boxStart = new DoubleSpinBox(); 78 boxStart->setDecimals(app->d_decimal_digits); 79 boxStart->setLocale(app->locale()); 80 gl1->addWidget(boxStart, 3, 1); 81 82 gl1->addWidget( new QLabel( tr("Fit curve Xmax")), 4, 0); 83 boxEnd = new DoubleSpinBox(); 84 boxEnd->setDecimals(app->d_decimal_digits); 85 boxEnd->setLocale(app->locale()); 86 gl1->addWidget(boxEnd, 4, 1); 87 88 gl1->addWidget(new QLabel( tr("Color")), 5, 0); 89 boxColor = new ColorButton(); 90 boxColor->setColor(Qt::red); 91 gl1->addWidget(boxColor, 5, 1); 92 93 boxShowFormula = new QCheckBox(tr( "Show Formula on Graph?" )); 94 boxShowFormula->setChecked( false ); 95 gl1->addWidget(boxShowFormula, 6, 1); 96 gl1->setRowStretch(7, 1); 97 gl1->setColumnStretch(1, 1); 98 99 buttonFit = new QPushButton(tr( "&Fit" )); 100 buttonFit->setDefault( true ); 101 102 buttonCancel = new QPushButton(tr( "&Close" )); 103 104 QVBoxLayout* vl = new QVBoxLayout(); 105 vl->addWidget(buttonFit); 106 vl->addWidget(buttonCancel); 107 vl->addStretch(); 108 109 QHBoxLayout* hlayout = new QHBoxLayout(this); 110 hlayout->addWidget(gb1, 1); 111 hlayout->addLayout(vl); 112 113 connect( buttonFit, SIGNAL( clicked() ), this, SLOT( fit() ) ); 114 connect( buttonCancel, SIGNAL( clicked() ), this, SLOT( close() ) ); 115 connect( boxName, SIGNAL( activated(const QString &) ), this, SLOT(activateCurve(const QString &))); 116 } 117 118 void PolynomFitDialog::fit() 119 { 120 QString curveName = boxName->currentText(); 121 QStringList curvesList = graph->analysableCurvesList(); 122 if (!curvesList.contains(curveName)){ 123 QMessageBox::critical(this, tr("QtiPlot - Warning"), 124 tr("The curve <b> %1 </b> doesn't exist anymore! Operation aborted!").arg(curveName)); 125 boxName->clear(); 126 boxName->insertStringList(curvesList); 127 return; 128 } 129 130 curveName = curveName.left(curveName.indexOf(" [")); 131 132 ApplicationWindow *app = (ApplicationWindow *)this->parent(); 133 PolynomialFit *fitter = new PolynomialFit(app, graph, boxOrder->value(), boxShowFormula->isChecked()); 134 if (fitter->setDataFromCurve((QwtPlotCurve *)graph->curve(curveName), boxStart->value(), boxEnd->value())){ 135 fitter->setColor(boxColor->color()); 136 fitter->setOutputPrecision(app->fit_output_precision); 137 fitter->generateFunction(app->generateUniformFitPoints, app->fitPoints); 138 fitter->fit(); 139 delete fitter; 140 } 141 } 142 143 void PolynomFitDialog::setGraph(Graph *g) 144 { 145 if (!g) 146 return; 147 148 graph = g; 149 boxName->addItems (g->analysableCurvesList()); 150 151 if (g->rangeSelectorsEnabled()) 152 boxName->setCurrentIndex(boxName->findText(g->curveRange(g->rangeSelectorTool()->selectedCurve()))); 153 154 activateCurve(boxName->currentText()); 155 156 connect (graph, SIGNAL(destroyed()), this, SLOT(close())); 157 connect (graph, SIGNAL(dataRangeChanged()), this, SLOT(changeDataRange())); 158 } 159 160 void PolynomFitDialog::activateCurve(const QString& s) 161 { 162 double start, end; 163 int n_points = graph->range((QwtPlotCurve *)graph->curve(s.left(s.indexOf(" ["))), &start, &end); 164 165 boxStart->setValue(start); 166 boxEnd->setValue(end); 167 boxPoints->setValue(QMAX(n_points, 100)); 168 } 169 170 void PolynomFitDialog::changeDataRange() 171 { 172 double start = graph->selectedXStartValue(); 173 double end = graph->selectedXEndValue(); 174 boxStart->setValue(QMIN(start, end)); 175 boxEnd->setValue(QMAX(start, end)); 176 } 177