Wt examples  3.3.5
/usr/src/RPM/BUILD/wt-3.3.5-rc2/examples/charts/ChartConfig.C
Go to the documentation of this file.
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 }

Generated on Tue Mar 22 2016 for the C++ Web Toolkit (Wt) by doxygen 1.7.6.1