Wt examples  3.3.4
ChartConfig.C
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008 Emweb bvba, Kessel-Lo, Belgium.
3  *
4  * See the LICENSE file for terms of use.
5  */
6 
7 #include "ChartConfig.h"
8 #include "PanelList.h"
9 
10 #include <iostream>
11 #include <boost/date_time/gregorian/greg_year.hpp>
12 
13 #include <Wt/WAbstractItemModel>
14 #include <Wt/WApplication>
15 #include <Wt/WCheckBox>
16 #include <Wt/WComboBox>
17 #include <Wt/WDoubleValidator>
18 #include <Wt/WDate>
19 #include <Wt/WEnvironment>
20 #include <Wt/WIntValidator>
21 #include <Wt/WLineEdit>
22 #include <Wt/WLocale>
23 #include <Wt/WPanel>
24 #include <Wt/WPushButton>
25 #include <Wt/WStandardItemModel>
26 #include <Wt/WTable>
27 #include <Wt/WText>
28 #include <Wt/WPainterPath>
29 
30 #include <Wt/Chart/WCartesianChart>
31 
32 using namespace Wt;
33 using namespace Wt::Chart;
34 
35 namespace {
36  void addHeader(WTable *t, const char *value) {
37  t->elementAt(0, t->columnCount())->addWidget(new WText(value));
38  }
39 
40  void addEntry(WAbstractItemModel *model, const char *value) {
41  model->insertRows(model->rowCount(), 1);
42  model->setData(model->rowCount()-1, 0, boost::any(std::string(value)));
43  }
44 
45  bool getDouble(WLineEdit *edit, double& value) {
46  try {
47  value = WLocale::currentLocale().toDouble(edit->text());
48  return true;
49  } catch (...) {
50  return false;
51  }
52  }
53 
54  int seriesIndexOf(WCartesianChart* chart, int modelColumn) {
55  for (unsigned i = 0; i < chart->series().size(); ++i)
56  if (chart->series()[i].modelColumn() == modelColumn)
57  return i;
58 
59  return -1;
60  }
61 }
62 
63 ChartConfig::ChartConfig(WCartesianChart *chart, WContainerWidget *parent)
64  : WContainerWidget(parent),
65  chart_(chart),
66  fill_(MinimumValueFill)
67 {
68  chart_->setLegendStyle(chart_->legendFont(), WPen(black),
69  WBrush(WColor(0xFF, 0xFA, 0xE5)));
70 
71  PanelList *list = new PanelList(this);
72 
73  WIntValidator *sizeValidator = new WIntValidator(200, 2000, this);
74  sizeValidator->setMandatory(true);
75 
76  WDoubleValidator *anyNumberValidator = new WDoubleValidator(this);
77  anyNumberValidator->setMandatory(true);
78 
79  WDoubleValidator *angleValidator = new WDoubleValidator(-90, 90, this);
80  angleValidator->setMandatory(true);
81 
82  // ---- Chart properties ----
83 
84  WStandardItemModel *orientation = new WStandardItemModel(0, 1, this);
85  addEntry(orientation, "Vertical");
86  addEntry(orientation, "Horizontal");
87 
88  WStandardItemModel *legendLocation = new WStandardItemModel(0, 1, this);
89  addEntry(legendLocation, "Outside");
90  addEntry(legendLocation, "Inside");
91 
92  WStandardItemModel *legendSide = new WStandardItemModel(0, 1, this);
93  addEntry(legendSide, "Top");
94  addEntry(legendSide, "Right");
95  addEntry(legendSide, "Bottom");
96  addEntry(legendSide, "Left");
97 
98  WStandardItemModel *legendAlignment = new WStandardItemModel(0, 1, this);
99  addEntry(legendAlignment, "AlignLeft");
100  addEntry(legendAlignment, "AlignCenter");
101  addEntry(legendAlignment, "AlignRight");
102  addEntry(legendAlignment, "AlignTop");
103  addEntry(legendAlignment, "AlignMiddle");
104  addEntry(legendAlignment, "AlignBottom");
105 
106  WTable *chartConfig = new WTable();
107  chartConfig->setMargin(WLength::Auto, Left | Right);
108 
109  int row = 0;
110  chartConfig->elementAt(row, 0)->addWidget(new WText("Title:"));
111  titleEdit_ = new WLineEdit(chartConfig->elementAt(row, 1));
113  ++row;
114 
115  chartConfig->elementAt(row, 0)->addWidget(new WText("Width:"));
116  chartWidthEdit_ = new WLineEdit(chartConfig->elementAt(row, 1));
118  ->setText(WLocale::currentLocale().toString(chart_->width().value()));
119  chartWidthEdit_->setValidator(sizeValidator);
120  chartWidthEdit_->setMaxLength(4);
122  ++row;
123 
124  chartConfig->elementAt(row, 0)->addWidget(new WText("Height:"));
125  chartHeightEdit_ = new WLineEdit(chartConfig->elementAt(row, 1));
127  ->setText(WLocale::currentLocale().toString(chart_->height().value()));
128  chartHeightEdit_->setValidator(sizeValidator);
129  chartHeightEdit_->setMaxLength(4);
131  ++row;
132 
133  chartConfig->elementAt(row, 0)->addWidget(new WText("Orientation:"));
134  chartOrientationEdit_ = new WComboBox(chartConfig->elementAt(row, 1));
135  chartOrientationEdit_->setModel(orientation);
137  ++row;
138 
139  chartConfig->elementAt(row, 0)->addWidget(new WText("Legend location:"));
140  legendLocationEdit_ = new WComboBox(chartConfig->elementAt(row, 1));
141  legendLocationEdit_->setModel(legendLocation);
143  ++row;
144 
145  chartConfig->elementAt(row, 0)->addWidget(new WText("Legend side:"));
146  legendSideEdit_ = new WComboBox(chartConfig->elementAt(row, 1));
147  legendSideEdit_->setModel(legendSide);
148  legendSideEdit_->setCurrentIndex(1);
150  ++row;
151 
152  chartConfig->elementAt(row, 0)->addWidget(new WText("Legend alignment:"));
153  legendAlignmentEdit_ = new WComboBox(chartConfig->elementAt(row, 1));
154  legendAlignmentEdit_->setModel(legendAlignment);
155  legendAlignmentEdit_->setCurrentIndex(4);
157  ++row;
158 
159  for (int i = 0; i < chartConfig->rowCount(); ++i) {
160  chartConfig->elementAt(i, 0)->setStyleClass("tdhead");
161  chartConfig->elementAt(i, 1)->setStyleClass("tddata");
162  }
163 
164  WPanel *p = list->addWidget("Chart properties", chartConfig);
165  p->setMargin(WLength::Auto, Left | Right);
166  p->resize(880, WLength::Auto);
167  p->setMargin(20, Top | Bottom);
168 
169  // ---- Series properties ----
170 
171  WStandardItemModel *types = new WStandardItemModel(0, 1, this);
172  addEntry(types, "Points");
173  addEntry(types, "Line");
174  addEntry(types, "Curve");
175  addEntry(types, "Bar");
176  addEntry(types, "Line Area");
177  addEntry(types, "Curve Area");
178  addEntry(types, "Stacked Bar");
179  addEntry(types, "Stacked Line Area");
180  addEntry(types, "Stacked Curve Area");
181 
182  WStandardItemModel *markers = new WStandardItemModel(0, 1, this);
183  addEntry(markers, "None");
184  addEntry(markers, "Square");
185  addEntry(markers, "Circle");
186  addEntry(markers, "Cross");
187  addEntry(markers, "X cross");
188  addEntry(markers, "Triangle");
189  addEntry(markers, "Diamond");
190 
191  WStandardItemModel *axes = new WStandardItemModel(0, 1, this);
192  addEntry(axes, "1st Y axis");
193  addEntry(axes, "2nd Y axis");
194 
195  WStandardItemModel *labels = new WStandardItemModel(0, 1, this);
196  addEntry(labels, "None");
197  addEntry(labels, "X");
198  addEntry(labels, "Y");
199  addEntry(labels, "X: Y");
200 
201  WTable *seriesConfig = new WTable();
202  seriesConfig->setMargin(WLength::Auto, Left | Right);
203 
204  ::addHeader(seriesConfig, "Name");
205  ::addHeader(seriesConfig, "Enabled");
206  ::addHeader(seriesConfig, "Type");
207  ::addHeader(seriesConfig, "Marker");
208  ::addHeader(seriesConfig, "Y axis");
209  ::addHeader(seriesConfig, "Legend");
210  ::addHeader(seriesConfig, "Shadow");
211  ::addHeader(seriesConfig, "Value labels");
212 
213  seriesConfig->rowAt(0)->setStyleClass("trhead");
214 
215  for (int j = 1; j < chart->model()->columnCount(); ++j) {
216  SeriesControl sc;
217 
218  new WText(asString(chart->model()->headerData(j)),
219  seriesConfig->elementAt(j, 0));
220 
221  sc.enabledEdit = new WCheckBox(seriesConfig->elementAt(j, 1));
223 
224  sc.typeEdit = new WComboBox(seriesConfig->elementAt(j, 2));
225  sc.typeEdit->setModel(types);
227 
228  sc.markerEdit = new WComboBox(seriesConfig->elementAt(j, 3));
229  sc.markerEdit->setModel(markers);
231 
232  sc.axisEdit = new WComboBox(seriesConfig->elementAt(j, 4));
233  sc.axisEdit->setModel(axes);
235 
236  sc.legendEdit = new WCheckBox(seriesConfig->elementAt(j, 5));
238 
239  sc.shadowEdit = new WCheckBox(seriesConfig->elementAt(j, 6));
241 
242  sc.labelsEdit = new WComboBox(seriesConfig->elementAt(j, 7));
243  sc.labelsEdit->setModel(labels);
245 
246  int si = seriesIndexOf(chart, j);
247 
248  if (si != -1) {
249  sc.enabledEdit->setChecked();
250  const WDataSeries& s = chart_->series(j);
251  switch (s.type()) {
252  case PointSeries:
253  sc.typeEdit->setCurrentIndex(0); break;
254  case LineSeries:
255  sc.typeEdit->setCurrentIndex(s.fillRange() != NoFill ?
256  (s.isStacked() ? 7 : 4) : 1); break;
257  case CurveSeries:
258  sc.typeEdit->setCurrentIndex(s.fillRange() != NoFill ?
259  (s.isStacked() ? 8 : 5) : 2); break;
260  case BarSeries:
261  sc.typeEdit->setCurrentIndex(s.isStacked() ? 6 : 3);
262  }
263 
264  sc.markerEdit->setCurrentIndex((int)s.marker());
265  sc.legendEdit->setChecked(s.isLegendEnabled());
266  sc.shadowEdit->setChecked(s.shadow() != WShadow());
267  }
268 
269  seriesControls_.push_back(sc);
270 
271  seriesConfig->rowAt(j)->setStyleClass("trdata");
272  }
273 
274  p = list->addWidget("Series properties", seriesConfig);
275  p->expand();
276  p->setMargin(WLength::Auto, Left | Right);
277  p->resize(880, WLength::Auto);
278  p->setMargin(20, Top | Bottom);
279 
280  // ---- Axis properties ----
281 
282  WStandardItemModel *yScales = new WStandardItemModel(0, 1, this);
283  addEntry(yScales, "Linear scale");
284  addEntry(yScales, "Log scale");
285 
286  WStandardItemModel *xScales = new WStandardItemModel(0, 1, this);
287  addEntry(xScales, "Categories");
288  addEntry(xScales, "Linear scale");
289  addEntry(xScales, "Log scale");
290  addEntry(xScales, "Date scale");
291 
292  WTable *axisConfig = new WTable();
293  axisConfig->setMargin(WLength::Auto, Left | Right);
294 
295  ::addHeader(axisConfig, "Axis");
296  ::addHeader(axisConfig, "Visible");
297  ::addHeader(axisConfig, "Scale");
298  ::addHeader(axisConfig, "Automatic");
299  ::addHeader(axisConfig, "Minimum");
300  ::addHeader(axisConfig, "Maximum");
301  ::addHeader(axisConfig, "Gridlines");
302  ::addHeader(axisConfig, "Label angle");
303 
304  axisConfig->rowAt(0)->setStyleClass("trhead");
305 
306  for (int i = 0; i < 3; ++i) {
307  const char *axisName[] = { "X axis", "1st Y axis", "2nd Y axis" };
308  int j = i + 1;
309 
310  const WAxis& axis = chart_->axis(static_cast<Axis>(i));
311  AxisControl sc;
312 
313  new WText(WString(axisName[i], UTF8), axisConfig->elementAt(j, 0));
314 
315  sc.visibleEdit = new WCheckBox(axisConfig->elementAt(j, 1));
316  sc.visibleEdit->setChecked(axis.isVisible());
318 
319  sc.scaleEdit = new WComboBox(axisConfig->elementAt(j, 2));
320  if (axis.scale() == CategoryScale)
321  sc.scaleEdit->addItem("Category scale");
322  else {
323  if (axis.id() == XAxis) {
324  sc.scaleEdit->setModel(xScales);
325  sc.scaleEdit->setCurrentIndex(axis.scale());
326  } else {
327  sc.scaleEdit->setModel(yScales);
328  sc.scaleEdit->setCurrentIndex(axis.scale() - 1);
329  }
330  }
332 
333  bool autoValues = axis.autoLimits() == (MinimumValue | MaximumValue);
334 
335  sc.minimumEdit = new WLineEdit(axisConfig->elementAt(j, 4));
336  sc.minimumEdit->setText(WLocale::currentLocale()
337  .toString(axis.minimum()));
338  sc.minimumEdit->setValidator(anyNumberValidator);
339  sc.minimumEdit->setEnabled(!autoValues);
341 
342  sc.maximumEdit = new WLineEdit(axisConfig->elementAt(j, 5));
343  sc.maximumEdit->setText(WLocale::currentLocale()
344  .toString(axis.maximum()));
345  sc.maximumEdit->setValidator(anyNumberValidator);
346  sc.maximumEdit->setEnabled(!autoValues);
348 
349  sc.autoEdit = new WCheckBox(axisConfig->elementAt(j, 3));
350  sc.autoEdit->setChecked(autoValues);
352  sc.autoEdit->checked().connect(sc.maximumEdit, &WLineEdit::disable);
353  sc.autoEdit->unChecked().connect(sc.maximumEdit, &WLineEdit::enable);
354  sc.autoEdit->checked().connect(sc.minimumEdit, &WLineEdit::disable);
355  sc.autoEdit->unChecked().connect(sc.minimumEdit, &WLineEdit::enable);
356 
357  sc.gridLinesEdit = new WCheckBox(axisConfig->elementAt(j, 6));
359 
360  sc.labelAngleEdit = new WLineEdit(axisConfig->elementAt(j, 7));
361  sc.labelAngleEdit->setText("0");
362  sc.labelAngleEdit->setValidator(angleValidator);
364 
365  axisConfig->rowAt(j)->setStyleClass("trdata");
366 
367  axisControls_.push_back(sc);
368  }
369 
370  p = list->addWidget("Axis properties", axisConfig);
371  p->setMargin(WLength::Auto, Left | Right);
372  p->resize(880, WLength::Auto);
373  p->setMargin(20, Top | Bottom);
374 
375  /*
376  * If we do not have JavaScript, then add a button to reflect changes to
377  * the chart.
378  */
379  if (!WApplication::instance()->environment().javaScript()) {
380  WPushButton *b = new WPushButton(this);
381  b->setText("Update chart");
382  b->setInline(false); // so we can add margin to center horizontally
383  b->setMargin(WLength::Auto, Left | Right);
384  b->clicked().connect(this, &ChartConfig::update);
385  }
386 }
387 
388 void ChartConfig::setValueFill(FillRangeType fill)
389 {
390  fill_ = fill;
391 }
392 
394 {
395  bool haveLegend = false;
396  std::vector<WDataSeries> series;
397 
398  for (int i = 1; i < chart_->model()->columnCount(); ++i) {
399  SeriesControl& sc = seriesControls_[i-1];
400 
401  if (sc.enabledEdit->isChecked()) {
402  WDataSeries s(i);
403 
404  switch (sc.typeEdit->currentIndex()) {
405  case 0:
406  s.setType(PointSeries);
407  if (sc.markerEdit->currentIndex() == 0)
408  sc.markerEdit->setCurrentIndex(1);
409  break;
410  case 1:
411  s.setType(LineSeries);
412  sc.markerEdit->setCurrentIndex(0);
413  break;
414  case 2:
415  s.setType(CurveSeries);
416  sc.markerEdit->setCurrentIndex(0);
417  break;
418  case 3:
419  s.setType(BarSeries);
420  sc.markerEdit->setCurrentIndex(0);
421  break;
422  case 4:
423  s.setType(LineSeries);
424  s.setFillRange(fill_);
425  sc.markerEdit->setCurrentIndex(0);
426  break;
427  case 5:
428  s.setType(CurveSeries);
429  s.setFillRange(fill_);
430  sc.markerEdit->setCurrentIndex(0);
431  break;
432  case 6:
433  s.setType(BarSeries);
434  s.setStacked(true);
435  sc.markerEdit->setCurrentIndex(0);
436  break;
437  case 7:
438  s.setType(LineSeries);
439  s.setFillRange(fill_);
440  s.setStacked(true);
441  sc.markerEdit->setCurrentIndex(0);
442  break;
443  case 8:
444  s.setType(CurveSeries);
445  s.setFillRange(fill_);
446  s.setStacked(true);
447  sc.markerEdit->setCurrentIndex(0);
448  }
449 
450  //set WPainterPath to draw a diamond
451  if(sc.markerEdit->currentIndex() == CustomMarker){
452  WPainterPath pp = WPainterPath();
453  pp.moveTo(-6, 0);
454  pp.lineTo(0, 6);
455  pp.lineTo(6, 0);
456  pp.lineTo(0, -6);
457  pp.lineTo(-6, 0);
458  s.setCustomMarker(pp);
459  }
460 
461  s.setMarker(static_cast<MarkerType>(sc.markerEdit->currentIndex()));
462 
463  if (sc.axisEdit->currentIndex() == 1) {
464  s.bindToAxis(Y2Axis);
465  }
466 
467  if (sc.legendEdit->isChecked()) {
468  s.setLegendEnabled(true);
469  haveLegend = true;
470  } else
471  s.setLegendEnabled(false);
472 
473  if (sc.shadowEdit->isChecked()) {
474  s.setShadow(WShadow(3, 3, WColor(0, 0, 0, 127), 3));
475  } else
476  s.setShadow(WShadow());
477 
478  switch (sc.labelsEdit->currentIndex()) {
479  case 1:
480  s.setLabelsEnabled(XAxis);
481  break;
482  case 2:
483  s.setLabelsEnabled(YAxis);
484  break;
485  case 3:
486  s.setLabelsEnabled(XAxis);
487  s.setLabelsEnabled(YAxis);
488  break;
489  }
490 
491  series.push_back(s);
492  }
493  }
494 
495  chart_->setSeries(series);
496 
497  for (int i = 0; i < 3; ++i) {
498  AxisControl& sc = axisControls_[i];
499  WAxis& axis = chart_->axis(static_cast<Axis>(i));
500 
501  axis.setVisible(sc.visibleEdit->isChecked());
502 
503  if (sc.scaleEdit->count() != 1) {
504  int k = sc.scaleEdit->currentIndex();
505  if (axis.id() != XAxis)
506  k += 1;
507  else {
508  if (k == 0)
509  chart_->setType(CategoryChart);
510  else
511  chart_->setType(ScatterPlot);
512  }
513 
514  switch (k) {
515  case 1:
516  axis.setScale(LinearScale); break;
517  case 2:
518  axis.setScale(LogScale); break;
519  case 3:
520  axis.setScale(DateScale); break;
521  }
522  }
523 
524  if (sc.autoEdit->isChecked())
525  axis.setAutoLimits(MinimumValue | MaximumValue);
526  else {
527  if (validate(sc.minimumEdit) && validate(sc.maximumEdit)) {
528  double min, max;
529  getDouble(sc.minimumEdit, min);
530  getDouble(sc.maximumEdit, max);
531 
532  if (axis.scale() == LogScale)
533  if (min <= 0)
534  min = 0.0001;
535 
536  if (axis.scale() == DateScale){
537  //the number of julian days until year 1986
538  WDate dMin = WDate(1900,1,1);
539  double gregDaysMin = (double)dMin.toJulianDay();
540  //the number of julian days until year 1988
541  WDate dMax = WDate(3000,1,1);
542  double gregDaysMax = (double)dMax.toJulianDay();
543 
544  bool greg_year_validation =
545  (min > gregDaysMin &&
546  min < gregDaysMax &&
547  max > gregDaysMin &&
548  max < gregDaysMax);
549 
550  if(!greg_year_validation){
551  min = gregDaysMin;
552  max = gregDaysMax;
553  }
554  }
555 
556  axis.setRange(min, max);
557  }
558 
559  }
560 
561  if (validate(sc.labelAngleEdit)) {
562  double angle;
563  getDouble(sc.labelAngleEdit, angle);
564  axis.setLabelAngle(angle);
565  }
566 
567  axis.setGridLinesEnabled(sc.gridLinesEdit->isChecked());
568  }
569 
570  chart_->setTitle(titleEdit_->text());
571 
573  double width, height;
574  getDouble(chartWidthEdit_, width);
575  getDouble(chartHeightEdit_, height);
576  chart_->resize(width, height);
577  }
578 
579  switch (chartOrientationEdit_->currentIndex()) {
580  case 0:
581  chart_->setOrientation(Vertical); break;
582  case 1:
583  chart_->setOrientation(Horizontal); break;
584  }
585 
586  chart_->setLegendEnabled(haveLegend);
587 
588  if (haveLegend) {
589  LegendLocation location = LegendOutside;
590  Side side = Right;
591  AlignmentFlag alignment = AlignMiddle;
592 
593  switch (legendLocationEdit_->currentIndex()) {
594  case 0: location = LegendOutside; break;
595  case 1: location = LegendInside; break;
596  }
597 
598  switch (legendSideEdit_->currentIndex()) {
599  case 0: side = Top; break;
600  case 1: side = Right; break;
601  case 2: side = Bottom; break;
602  case 3: side = Left; break;
603  }
604 
605  if (side == Left || side == Right) {
606  if (legendAlignmentEdit_->currentIndex() < 3)
607  legendAlignmentEdit_->setCurrentIndex(4);
608  } else {
609  if (legendAlignmentEdit_->currentIndex() >= 3)
610  legendAlignmentEdit_->setCurrentIndex(2);
611  }
612 
613  switch (legendAlignmentEdit_->currentIndex()) {
614  case 0: alignment = AlignLeft; break;
615  case 1: alignment = AlignCenter; break;
616  case 2: alignment = AlignRight; break;
617  case 3: alignment = AlignTop; break;
618  case 4: alignment = AlignMiddle; break;
619  case 5: alignment = AlignBottom; break;
620  }
621 
622  chart_->setLegendLocation(location, side, alignment);
623 
624  chart_->setLegendColumns((side == Top || side == Bottom ) ? 2 : 1,
625  WLength(100));
626  }
627 }
628 
629 bool ChartConfig::validate(WFormWidget *w)
630 {
631  bool valid = w->validate() == WValidator::Valid;
632 
633  if (!WApplication::instance()->environment().javaScript()) {
634  w->setStyleClass(valid ? "" : "Wt-invalid");
635  w->setToolTip(valid ? "" : "Invalid value");
636  }
637 
638  return valid;
639 }
640 
641 void ChartConfig::connectSignals(WFormWidget *w)
642 {
643  w->changed().connect(this, &ChartConfig::update);
644  if (dynamic_cast<WLineEdit *>(w))
645  w->enterPressed().connect(this, &ChartConfig::update);
646 }
ChartConfig(Wt::Chart::WCartesianChart *chart, Wt::WContainerWidget *parent)
Constructor.
Definition: ChartConfig.C:63
Wt::WComboBox * axisEdit
Definition: ChartConfig.h:55
Wt::Chart::FillRangeType fill_
Definition: ChartConfig.h:48
Wt::WComboBox * scaleEdit
Definition: ChartConfig.h:67
Wt::WLineEdit * titleEdit_
Definition: ChartConfig.h:78
Wt::Chart::WCartesianChart * chart_
Definition: ChartConfig.h:47
void connectSignals(Wt::WFormWidget *w)
Definition: ChartConfig.C:641
Wt::WCheckBox * enabledEdit
Definition: ChartConfig.h:52
Struct that holds the controls for one series.
Definition: ChartConfig.h:51
Wt::WComboBox * typeEdit
Definition: ChartConfig.h:53
Wt::WCheckBox * visibleEdit
Definition: ChartConfig.h:66
Wt::WComboBox * markerEdit
Definition: ChartConfig.h:54
Wt::WLineEdit * chartWidthEdit_
Definition: ChartConfig.h:79
Struct that holds the controls for one axis.
Definition: ChartConfig.h:65
Wt::WPanel * addWidget(const Wt::WString &text, Wt::WWidget *w)
Definition: PanelList.C:17
Wt::WComboBox * chartOrientationEdit_
Definition: ChartConfig.h:81
Wt::WComboBox * legendLocationEdit_
Definition: ChartConfig.h:82
std::vector< SeriesControl > seriesControls_
Controls for series.
Definition: ChartConfig.h:62
Wt::WLineEdit * minimumEdit
Definition: ChartConfig.h:69
Wt::WComboBox * legendSideEdit_
Definition: ChartConfig.h:83
std::vector< AxisControl > axisControls_
Controls for axes.
Definition: ChartConfig.h:76
void update()
Definition: ChartConfig.C:393
Wt::WCheckBox * shadowEdit
Definition: ChartConfig.h:57
Wt::WComboBox * labelsEdit
Definition: ChartConfig.h:58
void setValueFill(Wt::Chart::FillRangeType fill)
Definition: ChartConfig.C:388
Wt::WLineEdit * labelAngleEdit
Definition: ChartConfig.h:72
Wt::WCheckBox * legendEdit
Definition: ChartConfig.h:56
Wt::WCheckBox * gridLinesEdit
Definition: ChartConfig.h:71
Wt::WComboBox * legendAlignmentEdit_
Definition: ChartConfig.h:84
Wt::WCheckBox * autoEdit
Definition: ChartConfig.h:68
Wt::WLineEdit * maximumEdit
Definition: ChartConfig.h:70
static bool validate(Wt::WFormWidget *w)
Definition: ChartConfig.C:629
Wt::WLineEdit * chartHeightEdit_
Definition: ChartConfig.h:80

Generated on Thu Jul 16 2015 for the C++ Web Toolkit (Wt) by doxygen 1.8.9.1