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

Generated on Tue Nov 29 2011 for the C++ Web Toolkit (Wt) by doxygen 1.7.5.1