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

Generated on Fri Jul 27 2012 for the C++ Web Toolkit (Wt) by doxygen 1.7.5.1