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

Generated on Mon Apr 8 2013 for the C++ Web Toolkit (Wt) by doxygen 1.7.5.1