|
Wt examples
3.3.5
|
00001 /* 00002 * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium. 00003 * 00004 * See the LICENSE file for terms of use. 00005 */ 00006 00007 #include "ChartConfig.h" 00008 #include "PanelList.h" 00009 00010 #include <iostream> 00011 #include <boost/date_time/gregorian/greg_year.hpp> 00012 00013 #include <Wt/WAbstractItemModel> 00014 #include <Wt/WApplication> 00015 #include <Wt/WCheckBox> 00016 #include <Wt/WComboBox> 00017 #include <Wt/WDoubleValidator> 00018 #include <Wt/WDate> 00019 #include <Wt/WEnvironment> 00020 #include <Wt/WIntValidator> 00021 #include <Wt/WLineEdit> 00022 #include <Wt/WLocale> 00023 #include <Wt/WPanel> 00024 #include <Wt/WPushButton> 00025 #include <Wt/WStandardItemModel> 00026 #include <Wt/WTable> 00027 #include <Wt/WText> 00028 #include <Wt/WPainterPath> 00029 00030 #include <Wt/Chart/WCartesianChart> 00031 00032 using namespace Wt; 00033 using namespace Wt::Chart; 00034 00035 namespace { 00036 void addHeader(WTable *t, const char *value) { 00037 t->elementAt(0, t->columnCount())->addWidget(new WText(value)); 00038 } 00039 00040 void addEntry(WAbstractItemModel *model, const char *value) { 00041 model->insertRows(model->rowCount(), 1); 00042 model->setData(model->rowCount()-1, 0, boost::any(std::string(value))); 00043 } 00044 00045 bool getDouble(WLineEdit *edit, double& value) { 00046 try { 00047 value = WLocale::currentLocale().toDouble(edit->text()); 00048 return true; 00049 } catch (...) { 00050 return false; 00051 } 00052 } 00053 00054 int seriesIndexOf(WCartesianChart* chart, int modelColumn) { 00055 for (unsigned i = 0; i < chart->series().size(); ++i) 00056 if (chart->series()[i].modelColumn() == modelColumn) 00057 return i; 00058 00059 return -1; 00060 } 00061 } 00062 00063 ChartConfig::ChartConfig(WCartesianChart *chart, WContainerWidget *parent) 00064 : WContainerWidget(parent), 00065 chart_(chart), 00066 fill_(MinimumValueFill) 00067 { 00068 chart_->setLegendStyle(chart_->legendFont(), WPen(black), 00069 WBrush(WColor(0xFF, 0xFA, 0xE5))); 00070 00071 PanelList *list = new PanelList(this); 00072 00073 WIntValidator *sizeValidator = new WIntValidator(200, 2000, this); 00074 sizeValidator->setMandatory(true); 00075 00076 WDoubleValidator *anyNumberValidator = new WDoubleValidator(this); 00077 anyNumberValidator->setMandatory(true); 00078 00079 WDoubleValidator *angleValidator = new WDoubleValidator(-90, 90, this); 00080 angleValidator->setMandatory(true); 00081 00082 // ---- Chart properties ---- 00083 00084 WStandardItemModel *orientation = new WStandardItemModel(0, 1, this); 00085 addEntry(orientation, "Vertical"); 00086 addEntry(orientation, "Horizontal"); 00087 00088 WStandardItemModel *legendLocation = new WStandardItemModel(0, 1, this); 00089 addEntry(legendLocation, "Outside"); 00090 addEntry(legendLocation, "Inside"); 00091 00092 WStandardItemModel *legendSide = new WStandardItemModel(0, 1, this); 00093 addEntry(legendSide, "Top"); 00094 addEntry(legendSide, "Right"); 00095 addEntry(legendSide, "Bottom"); 00096 addEntry(legendSide, "Left"); 00097 00098 WStandardItemModel *legendAlignment = new WStandardItemModel(0, 1, this); 00099 addEntry(legendAlignment, "AlignLeft"); 00100 addEntry(legendAlignment, "AlignCenter"); 00101 addEntry(legendAlignment, "AlignRight"); 00102 addEntry(legendAlignment, "AlignTop"); 00103 addEntry(legendAlignment, "AlignMiddle"); 00104 addEntry(legendAlignment, "AlignBottom"); 00105 00106 WTable *chartConfig = new WTable(); 00107 chartConfig->setMargin(WLength::Auto, Left | Right); 00108 00109 int row = 0; 00110 chartConfig->elementAt(row, 0)->addWidget(new WText("Title:")); 00111 titleEdit_ = new WLineEdit(chartConfig->elementAt(row, 1)); 00112 connectSignals(titleEdit_); 00113 ++row; 00114 00115 chartConfig->elementAt(row, 0)->addWidget(new WText("Width:")); 00116 chartWidthEdit_ = new WLineEdit(chartConfig->elementAt(row, 1)); 00117 chartWidthEdit_ 00118 ->setText(WLocale::currentLocale().toString(chart_->width().value())); 00119 chartWidthEdit_->setValidator(sizeValidator); 00120 chartWidthEdit_->setMaxLength(4); 00121 connectSignals(chartWidthEdit_); 00122 ++row; 00123 00124 chartConfig->elementAt(row, 0)->addWidget(new WText("Height:")); 00125 chartHeightEdit_ = new WLineEdit(chartConfig->elementAt(row, 1)); 00126 chartHeightEdit_ 00127 ->setText(WLocale::currentLocale().toString(chart_->height().value())); 00128 chartHeightEdit_->setValidator(sizeValidator); 00129 chartHeightEdit_->setMaxLength(4); 00130 connectSignals(chartHeightEdit_); 00131 ++row; 00132 00133 chartConfig->elementAt(row, 0)->addWidget(new WText("Orientation:")); 00134 chartOrientationEdit_ = new WComboBox(chartConfig->elementAt(row, 1)); 00135 chartOrientationEdit_->setModel(orientation); 00136 chartOrientationEdit_->setCurrentIndex(0); 00137 connectSignals(chartOrientationEdit_); 00138 ++row; 00139 00140 chartConfig->elementAt(row, 0)->addWidget(new WText("Legend location:")); 00141 legendLocationEdit_ = new WComboBox(chartConfig->elementAt(row, 1)); 00142 legendLocationEdit_->setModel(legendLocation); 00143 legendLocationEdit_->setCurrentIndex(0); 00144 connectSignals(legendLocationEdit_); 00145 ++row; 00146 00147 chartConfig->elementAt(row, 0)->addWidget(new WText("Legend side:")); 00148 legendSideEdit_ = new WComboBox(chartConfig->elementAt(row, 1)); 00149 legendSideEdit_->setModel(legendSide); 00150 legendSideEdit_->setCurrentIndex(1); 00151 legendSideEdit_->setCurrentIndex(0); 00152 connectSignals(legendSideEdit_); 00153 ++row; 00154 00155 chartConfig->elementAt(row, 0)->addWidget(new WText("Legend alignment:")); 00156 legendAlignmentEdit_ = new WComboBox(chartConfig->elementAt(row, 1)); 00157 legendAlignmentEdit_->setModel(legendAlignment); 00158 legendAlignmentEdit_->setCurrentIndex(4); 00159 legendAlignmentEdit_->setCurrentIndex(0); 00160 connectSignals(legendAlignmentEdit_); 00161 ++row; 00162 00163 chartConfig->elementAt(row, 0)->addWidget(new WText("Border:")); 00164 borderEdit_ = new WCheckBox(chartConfig->elementAt(row, 1)); 00165 borderEdit_->setChecked(false); 00166 connectSignals(borderEdit_); 00167 ++row; 00168 00169 for (int i = 0; i < chartConfig->rowCount(); ++i) { 00170 chartConfig->elementAt(i, 0)->setStyleClass("tdhead"); 00171 chartConfig->elementAt(i, 1)->setStyleClass("tddata"); 00172 } 00173 00174 WPanel *p = list->addWidget("Chart properties", chartConfig); 00175 p->setMargin(WLength::Auto, Left | Right); 00176 p->resize(1080, WLength::Auto); 00177 p->setMargin(20, Top | Bottom); 00178 00179 // ---- Series properties ---- 00180 00181 WStandardItemModel *types = new WStandardItemModel(0, 1, this); 00182 addEntry(types, "Points"); 00183 addEntry(types, "Line"); 00184 addEntry(types, "Curve"); 00185 addEntry(types, "Bar"); 00186 addEntry(types, "Line Area"); 00187 addEntry(types, "Curve Area"); 00188 addEntry(types, "Stacked Bar"); 00189 addEntry(types, "Stacked Line Area"); 00190 addEntry(types, "Stacked Curve Area"); 00191 00192 WStandardItemModel *markers = new WStandardItemModel(0, 1, this); 00193 addEntry(markers, "None"); 00194 addEntry(markers, "Square"); 00195 addEntry(markers, "Circle"); 00196 addEntry(markers, "Cross"); 00197 addEntry(markers, "X cross"); 00198 addEntry(markers, "Triangle"); 00199 addEntry(markers, "Diamond"); 00200 00201 WStandardItemModel *axes = new WStandardItemModel(0, 1, this); 00202 addEntry(axes, "1st Y axis"); 00203 addEntry(axes, "2nd Y axis"); 00204 00205 WStandardItemModel *labels = new WStandardItemModel(0, 1, this); 00206 addEntry(labels, "None"); 00207 addEntry(labels, "X"); 00208 addEntry(labels, "Y"); 00209 addEntry(labels, "X: Y"); 00210 00211 WTable *seriesConfig = new WTable(); 00212 seriesConfig->setMargin(WLength::Auto, Left | Right); 00213 00214 ::addHeader(seriesConfig, "Name"); 00215 ::addHeader(seriesConfig, "Enabled"); 00216 ::addHeader(seriesConfig, "Type"); 00217 ::addHeader(seriesConfig, "Marker"); 00218 ::addHeader(seriesConfig, "Y axis"); 00219 ::addHeader(seriesConfig, "Legend"); 00220 ::addHeader(seriesConfig, "Shadow"); 00221 ::addHeader(seriesConfig, "Value labels"); 00222 00223 seriesConfig->rowAt(0)->setStyleClass("trhead"); 00224 00225 for (int j = 1; j < chart->model()->columnCount(); ++j) { 00226 SeriesControl sc; 00227 00228 new WText(asString(chart->model()->headerData(j)), 00229 seriesConfig->elementAt(j, 0)); 00230 00231 sc.enabledEdit = new WCheckBox(seriesConfig->elementAt(j, 1)); 00232 connectSignals(sc.enabledEdit); 00233 00234 sc.typeEdit = new WComboBox(seriesConfig->elementAt(j, 2)); 00235 sc.typeEdit->setModel(types); 00236 sc.typeEdit->setCurrentIndex(0); 00237 connectSignals(sc.typeEdit); 00238 00239 sc.markerEdit = new WComboBox(seriesConfig->elementAt(j, 3)); 00240 sc.markerEdit->setModel(markers); 00241 sc.markerEdit->setCurrentIndex(0); 00242 connectSignals(sc.markerEdit); 00243 00244 sc.axisEdit = new WComboBox(seriesConfig->elementAt(j, 4)); 00245 sc.axisEdit->setModel(axes); 00246 sc.axisEdit->setCurrentIndex(0); 00247 connectSignals(sc.axisEdit); 00248 00249 sc.legendEdit = new WCheckBox(seriesConfig->elementAt(j, 5)); 00250 connectSignals(sc.legendEdit); 00251 00252 sc.shadowEdit = new WCheckBox(seriesConfig->elementAt(j, 6)); 00253 connectSignals(sc.shadowEdit); 00254 00255 sc.labelsEdit = new WComboBox(seriesConfig->elementAt(j, 7)); 00256 sc.labelsEdit->setModel(labels); 00257 sc.labelsEdit->setCurrentIndex(0); 00258 connectSignals(sc.labelsEdit); 00259 00260 int si = seriesIndexOf(chart, j); 00261 00262 if (si != -1) { 00263 sc.enabledEdit->setChecked(); 00264 const WDataSeries& s = chart_->series(j); 00265 switch (s.type()) { 00266 case PointSeries: 00267 sc.typeEdit->setCurrentIndex(0); break; 00268 case LineSeries: 00269 sc.typeEdit->setCurrentIndex(s.fillRange() != NoFill ? 00270 (s.isStacked() ? 7 : 4) : 1); break; 00271 case CurveSeries: 00272 sc.typeEdit->setCurrentIndex(s.fillRange() != NoFill ? 00273 (s.isStacked() ? 8 : 5) : 2); break; 00274 case BarSeries: 00275 sc.typeEdit->setCurrentIndex(s.isStacked() ? 6 : 3); 00276 } 00277 00278 sc.markerEdit->setCurrentIndex((int)s.marker()); 00279 sc.legendEdit->setChecked(s.isLegendEnabled()); 00280 sc.shadowEdit->setChecked(s.shadow() != WShadow()); 00281 } 00282 00283 seriesControls_.push_back(sc); 00284 00285 seriesConfig->rowAt(j)->setStyleClass("trdata"); 00286 } 00287 00288 p = list->addWidget("Series properties", seriesConfig); 00289 p->expand(); 00290 p->setMargin(WLength::Auto, Left | Right); 00291 p->resize(1080, WLength::Auto); 00292 p->setMargin(20, Top | Bottom); 00293 00294 // ---- Axis properties ---- 00295 00296 WStandardItemModel *yScales = new WStandardItemModel(0, 1, this); 00297 addEntry(yScales, "Linear scale"); 00298 addEntry(yScales, "Log scale"); 00299 00300 WStandardItemModel *xScales = new WStandardItemModel(0, 1, this); 00301 addEntry(xScales, "Categories"); 00302 addEntry(xScales, "Linear scale"); 00303 addEntry(xScales, "Log scale"); 00304 addEntry(xScales, "Date scale"); 00305 00306 WTable *axisConfig = new WTable(); 00307 axisConfig->setMargin(WLength::Auto, Left | Right); 00308 00309 ::addHeader(axisConfig, "Axis"); 00310 ::addHeader(axisConfig, "Visible"); 00311 ::addHeader(axisConfig, "Scale"); 00312 ::addHeader(axisConfig, "Automatic"); 00313 ::addHeader(axisConfig, "Minimum"); 00314 ::addHeader(axisConfig, "Maximum"); 00315 ::addHeader(axisConfig, "Gridlines"); 00316 ::addHeader(axisConfig, "Label angle"); 00317 ::addHeader(axisConfig, "Title"); 00318 ::addHeader(axisConfig, "Title orientation"); 00319 ::addHeader(axisConfig, "Tick direction"); 00320 ::addHeader(axisConfig, "Location"); 00321 00322 axisConfig->rowAt(0)->setStyleClass("trhead"); 00323 00324 for (int i = 0; i < 3; ++i) { 00325 const char *axisName[] = { "X axis", "1st Y axis", "2nd Y axis" }; 00326 int j = i + 1; 00327 00328 const WAxis& axis = chart_->axis(static_cast<Axis>(i)); 00329 AxisControl sc; 00330 00331 new WText(WString(axisName[i], UTF8), axisConfig->elementAt(j, 0)); 00332 00333 sc.visibleEdit = new WCheckBox(axisConfig->elementAt(j, 1)); 00334 sc.visibleEdit->setChecked(axis.isVisible()); 00335 connectSignals(sc.visibleEdit); 00336 00337 sc.scaleEdit = new WComboBox(axisConfig->elementAt(j, 2)); 00338 if (axis.scale() == CategoryScale) 00339 sc.scaleEdit->addItem("Category scale"); 00340 else { 00341 if (axis.id() == XAxis) { 00342 sc.scaleEdit->setModel(xScales); 00343 sc.scaleEdit->setCurrentIndex(axis.scale()); 00344 } else { 00345 sc.scaleEdit->setModel(yScales); 00346 sc.scaleEdit->setCurrentIndex(axis.scale() - 1); 00347 } 00348 } 00349 connectSignals(sc.scaleEdit); 00350 00351 bool autoValues = axis.autoLimits() == (MinimumValue | MaximumValue); 00352 00353 sc.minimumEdit = new WLineEdit(axisConfig->elementAt(j, 4)); 00354 sc.minimumEdit->setText(WLocale::currentLocale() 00355 .toString(axis.minimum())); 00356 sc.minimumEdit->setValidator(anyNumberValidator); 00357 sc.minimumEdit->setEnabled(!autoValues); 00358 connectSignals(sc.minimumEdit); 00359 00360 sc.maximumEdit = new WLineEdit(axisConfig->elementAt(j, 5)); 00361 sc.maximumEdit->setText(WLocale::currentLocale() 00362 .toString(axis.maximum())); 00363 sc.maximumEdit->setValidator(anyNumberValidator); 00364 sc.maximumEdit->setEnabled(!autoValues); 00365 connectSignals(sc.maximumEdit); 00366 00367 sc.autoEdit = new WCheckBox(axisConfig->elementAt(j, 3)); 00368 sc.autoEdit->setChecked(autoValues); 00369 connectSignals(sc.autoEdit); 00370 sc.autoEdit->checked().connect(sc.maximumEdit, &WLineEdit::disable); 00371 sc.autoEdit->unChecked().connect(sc.maximumEdit, &WLineEdit::enable); 00372 sc.autoEdit->checked().connect(sc.minimumEdit, &WLineEdit::disable); 00373 sc.autoEdit->unChecked().connect(sc.minimumEdit, &WLineEdit::enable); 00374 00375 sc.gridLinesEdit = new WCheckBox(axisConfig->elementAt(j, 6)); 00376 connectSignals(sc.gridLinesEdit); 00377 00378 sc.labelAngleEdit = new WLineEdit(axisConfig->elementAt(j, 7)); 00379 sc.labelAngleEdit->setText("0"); 00380 sc.labelAngleEdit->setValidator(angleValidator); 00381 connectSignals(sc.labelAngleEdit); 00382 00383 sc.titleEdit = new WLineEdit(axisConfig->elementAt(j, 8)); 00384 sc.titleEdit->setText(""); 00385 connectSignals(sc.titleEdit); 00386 00387 sc.titleOrientationEdit = new WComboBox(axisConfig->elementAt(j, 9)); 00388 sc.titleOrientationEdit->addItem("Horizontal"); 00389 sc.titleOrientationEdit->addItem("Vertical"); 00390 sc.titleOrientationEdit->setCurrentIndex(0); 00391 connectSignals(sc.titleOrientationEdit); 00392 00393 sc.tickDirectionEdit = new WComboBox(axisConfig->elementAt(j, 10)); 00394 sc.tickDirectionEdit->addItem("Outwards"); 00395 sc.tickDirectionEdit->addItem("Inwards"); 00396 sc.tickDirectionEdit->setCurrentIndex(0); 00397 connectSignals(sc.tickDirectionEdit); 00398 00399 sc.locationEdit = new WComboBox(axisConfig->elementAt(j, 11)); 00400 sc.locationEdit->addItem("Minimum value"); 00401 sc.locationEdit->addItem("Maximum value"); 00402 sc.locationEdit->addItem("Zero value"); 00403 sc.locationEdit->addItem("Both sides"); 00404 sc.locationEdit->setCurrentIndex(0); 00405 if (axis.location() == ZeroValue) { 00406 sc.locationEdit->setCurrentIndex(2); 00407 } 00408 connectSignals(sc.locationEdit); 00409 00410 axisConfig->rowAt(j)->setStyleClass("trdata"); 00411 00412 axisControls_.push_back(sc); 00413 } 00414 00415 p = list->addWidget("Axis properties", axisConfig); 00416 p->setMargin(WLength::Auto, Left | Right); 00417 p->resize(1080, WLength::Auto); 00418 p->setMargin(20, Top | Bottom); 00419 00420 /* 00421 * If we do not have JavaScript, then add a button to reflect changes to 00422 * the chart. 00423 */ 00424 if (!WApplication::instance()->environment().javaScript()) { 00425 WPushButton *b = new WPushButton(this); 00426 b->setText("Update chart"); 00427 b->setInline(false); // so we can add margin to center horizontally 00428 b->setMargin(WLength::Auto, Left | Right); 00429 b->clicked().connect(this, &ChartConfig::update); 00430 } 00431 } 00432 00433 void ChartConfig::setValueFill(FillRangeType fill) 00434 { 00435 fill_ = fill; 00436 } 00437 00438 void ChartConfig::update() 00439 { 00440 bool haveLegend = false; 00441 std::vector<WDataSeries> series; 00442 00443 for (int i = 1; i < chart_->model()->columnCount(); ++i) { 00444 SeriesControl& sc = seriesControls_[i-1]; 00445 00446 if (sc.enabledEdit->isChecked()) { 00447 WDataSeries s(i); 00448 00449 switch (sc.typeEdit->currentIndex()) { 00450 case 0: 00451 s.setType(PointSeries); 00452 if (sc.markerEdit->currentIndex() == 0) 00453 sc.markerEdit->setCurrentIndex(1); 00454 break; 00455 case 1: 00456 s.setType(LineSeries); 00457 sc.markerEdit->setCurrentIndex(0); 00458 break; 00459 case 2: 00460 s.setType(CurveSeries); 00461 sc.markerEdit->setCurrentIndex(0); 00462 break; 00463 case 3: 00464 s.setType(BarSeries); 00465 sc.markerEdit->setCurrentIndex(0); 00466 break; 00467 case 4: 00468 s.setType(LineSeries); 00469 s.setFillRange(fill_); 00470 sc.markerEdit->setCurrentIndex(0); 00471 break; 00472 case 5: 00473 s.setType(CurveSeries); 00474 s.setFillRange(fill_); 00475 sc.markerEdit->setCurrentIndex(0); 00476 break; 00477 case 6: 00478 s.setType(BarSeries); 00479 s.setStacked(true); 00480 sc.markerEdit->setCurrentIndex(0); 00481 break; 00482 case 7: 00483 s.setType(LineSeries); 00484 s.setFillRange(fill_); 00485 s.setStacked(true); 00486 sc.markerEdit->setCurrentIndex(0); 00487 break; 00488 case 8: 00489 s.setType(CurveSeries); 00490 s.setFillRange(fill_); 00491 s.setStacked(true); 00492 sc.markerEdit->setCurrentIndex(0); 00493 } 00494 00495 //set WPainterPath to draw a diamond 00496 if(sc.markerEdit->currentIndex() == CustomMarker){ 00497 WPainterPath pp = WPainterPath(); 00498 pp.moveTo(-6, 0); 00499 pp.lineTo(0, 6); 00500 pp.lineTo(6, 0); 00501 pp.lineTo(0, -6); 00502 pp.lineTo(-6, 0); 00503 s.setCustomMarker(pp); 00504 } 00505 00506 s.setMarker(static_cast<MarkerType>(sc.markerEdit->currentIndex())); 00507 00508 if (sc.axisEdit->currentIndex() == 1) { 00509 s.bindToAxis(Y2Axis); 00510 } 00511 00512 if (sc.legendEdit->isChecked()) { 00513 s.setLegendEnabled(true); 00514 haveLegend = true; 00515 } else 00516 s.setLegendEnabled(false); 00517 00518 if (sc.shadowEdit->isChecked()) { 00519 s.setShadow(WShadow(3, 3, WColor(0, 0, 0, 127), 3)); 00520 } else 00521 s.setShadow(WShadow()); 00522 00523 switch (sc.labelsEdit->currentIndex()) { 00524 case 1: 00525 s.setLabelsEnabled(XAxis); 00526 break; 00527 case 2: 00528 s.setLabelsEnabled(YAxis); 00529 break; 00530 case 3: 00531 s.setLabelsEnabled(XAxis); 00532 s.setLabelsEnabled(YAxis); 00533 break; 00534 } 00535 00536 series.push_back(s); 00537 } 00538 } 00539 00540 chart_->setSeries(series); 00541 00542 for (int i = 0; i < 3; ++i) { 00543 AxisControl& sc = axisControls_[i]; 00544 WAxis& axis = chart_->axis(static_cast<Axis>(i)); 00545 00546 axis.setVisible(sc.visibleEdit->isChecked()); 00547 00548 if (sc.scaleEdit->count() != 1) { 00549 int k = sc.scaleEdit->currentIndex(); 00550 if (axis.id() != XAxis) 00551 k += 1; 00552 else { 00553 if (k == 0) 00554 chart_->setType(CategoryChart); 00555 else 00556 chart_->setType(ScatterPlot); 00557 } 00558 00559 switch (k) { 00560 case 1: 00561 axis.setScale(LinearScale); break; 00562 case 2: 00563 axis.setScale(LogScale); break; 00564 case 3: 00565 axis.setScale(DateScale); break; 00566 } 00567 } 00568 00569 if (sc.autoEdit->isChecked()) 00570 axis.setAutoLimits(MinimumValue | MaximumValue); 00571 else { 00572 if (axis.autoLimits() & (MinimumValue | MaximumValue)) { 00573 sc.minimumEdit->setText(WLocale::currentLocale() 00574 .toString(axis.minimum())); 00575 sc.maximumEdit->setText(WLocale::currentLocale() 00576 .toString(axis.maximum())); 00577 } 00578 if (validate(sc.minimumEdit) && validate(sc.maximumEdit)) { 00579 double min, max; 00580 getDouble(sc.minimumEdit, min); 00581 getDouble(sc.maximumEdit, max); 00582 00583 if (axis.scale() == LogScale) 00584 if (min <= 0) 00585 min = 0.0001; 00586 00587 if (axis.scale() == DateScale){ 00588 //the number of julian days until year 1986 00589 WDate dMin = WDate(1900,1,1); 00590 double gregDaysMin = (double)dMin.toJulianDay(); 00591 //the number of julian days until year 1988 00592 WDate dMax = WDate(3000,1,1); 00593 double gregDaysMax = (double)dMax.toJulianDay(); 00594 00595 bool greg_year_validation = 00596 (min > gregDaysMin && 00597 min < gregDaysMax && 00598 max > gregDaysMin && 00599 max < gregDaysMax); 00600 00601 if(!greg_year_validation){ 00602 min = gregDaysMin; 00603 max = gregDaysMax; 00604 } 00605 } 00606 00607 axis.setRange(min, max); 00608 } 00609 00610 } 00611 00612 if (validate(sc.labelAngleEdit)) { 00613 double angle; 00614 getDouble(sc.labelAngleEdit, angle); 00615 axis.setLabelAngle(angle); 00616 } 00617 00618 axis.setGridLinesEnabled(sc.gridLinesEdit->isChecked()); 00619 00620 axis.setTitle(sc.titleEdit->text()); 00621 00622 axis.setTitleOrientation(sc.titleOrientationEdit->currentIndex() == 0 ? Horizontal : Vertical); 00623 00624 axis.setTickDirection(sc.tickDirectionEdit->currentIndex() == 0 ? Outwards : Inwards); 00625 00626 switch (sc.locationEdit->currentIndex()) { 00627 case 0: 00628 axis.setLocation(MinimumValue); 00629 break; 00630 case 1: 00631 axis.setLocation(MaximumValue); 00632 break; 00633 case 2: 00634 axis.setLocation(ZeroValue); 00635 break; 00636 case 3: 00637 axis.setLocation(BothSides); 00638 break; 00639 } 00640 } 00641 00642 chart_->setTitle(titleEdit_->text()); 00643 00644 if (validate(chartWidthEdit_) && validate(chartHeightEdit_)) { 00645 double width, height; 00646 getDouble(chartWidthEdit_, width); 00647 getDouble(chartHeightEdit_, height); 00648 chart_->resize(width, height); 00649 } 00650 00651 switch (chartOrientationEdit_->currentIndex()) { 00652 case 0: 00653 chart_->setOrientation(Vertical); break; 00654 case 1: 00655 chart_->setOrientation(Horizontal); break; 00656 } 00657 00658 chart_->setLegendEnabled(haveLegend); 00659 00660 if (haveLegend) { 00661 LegendLocation location = LegendOutside; 00662 Side side = Right; 00663 AlignmentFlag alignment = AlignMiddle; 00664 switch (legendLocationEdit_->currentIndex()) { 00665 case 0: location = LegendOutside; break; 00666 case 1: location = LegendInside; break; 00667 } 00668 00669 switch (legendSideEdit_->currentIndex()) { 00670 case 0: side = Top; break; 00671 case 1: side = Right; break; 00672 case 2: side = Bottom; break; 00673 case 3: side = Left; break; 00674 } 00675 00676 if (side == Left || side == Right) { 00677 if (legendAlignmentEdit_->currentIndex() < 3) 00678 legendAlignmentEdit_->setCurrentIndex(4); 00679 } else { 00680 if (legendAlignmentEdit_->currentIndex() >= 3) 00681 legendAlignmentEdit_->setCurrentIndex(2); 00682 } 00683 00684 switch (legendAlignmentEdit_->currentIndex()) { 00685 case 0: alignment = AlignLeft; break; 00686 case 1: alignment = AlignCenter; break; 00687 case 2: alignment = AlignRight; break; 00688 case 3: alignment = AlignTop; break; 00689 case 4: alignment = AlignMiddle; break; 00690 case 5: alignment = AlignBottom; break; 00691 } 00692 00693 chart_->setLegendLocation(location, side, alignment); 00694 00695 chart_->setLegendColumns((side == Top || side == Bottom ) ? 2 : 1, 00696 WLength(100)); 00697 } 00698 00699 if (borderEdit_->isChecked()) { 00700 chart_->setBorderPen(WPen()); 00701 } else { 00702 chart_->setBorderPen(NoPen); 00703 } 00704 } 00705 00706 bool ChartConfig::validate(WFormWidget *w) 00707 { 00708 bool valid = w->validate() == WValidator::Valid; 00709 00710 if (!WApplication::instance()->environment().javaScript()) { 00711 w->setStyleClass(valid ? "" : "Wt-invalid"); 00712 w->setToolTip(valid ? "" : "Invalid value"); 00713 } 00714 00715 return valid; 00716 } 00717 00718 void ChartConfig::connectSignals(WFormWidget *w) 00719 { 00720 w->changed().connect(this, &ChartConfig::update); 00721 if (dynamic_cast<WLineEdit *>(w)) 00722 w->enterPressed().connect(this, &ChartConfig::update); 00723 }
1.7.6.1