Wt examples  3.3.12
Classes | Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
ChartConfig Class Reference

A class that allows configuration of a cartesian chart. More...

#include <ChartConfig.h>

Inheritance diagram for ChartConfig:
Inheritance graph
[legend]

Classes

struct  AxisControl
 Struct that holds the controls for one axis. More...
 
struct  SeriesControl
 Struct that holds the controls for one series. More...
 

Public Member Functions

 ChartConfig (Wt::Chart::WCartesianChart *chart, Wt::WContainerWidget *parent)
 Constructor. More...
 
void setValueFill (Wt::Chart::FillRangeType fill)
 

Private Member Functions

void connectSignals (Wt::WFormWidget *w)
 
void update ()
 
void addYAxis ()
 
void addAxis (Wt::Chart::Axis axis, int yAxis)
 
void removeYAxis (const Wt::Chart::WAxis *axis)
 
void clearYAxes ()
 

Static Private Member Functions

static bool validate (Wt::WFormWidget *w)
 

Private Attributes

Wt::Chart::WCartesianChart * chart_
 
Wt::Chart::FillRangeType fill_
 
std::vector< SeriesControlseriesControls_
 Controls for series. More...
 
std::vector< AxisControlaxisControls_
 Controls for axes. More...
 
Wt::WLineEdit * titleEdit_
 
Wt::WLineEdit * chartWidthEdit_
 
Wt::WLineEdit * chartHeightEdit_
 
Wt::WComboBox * chartOrientationEdit_
 
Wt::WComboBox * legendLocationEdit_
 
Wt::WComboBox * legendSideEdit_
 
Wt::WComboBox * legendAlignmentEdit_
 
Wt::WCheckBox * borderEdit_
 
Wt::WStandardItemModel * yAxesModel_
 
Wt::WStandardItemModel * xScales_
 
Wt::WStandardItemModel * yScales_
 
Wt::WTable * axisConfig_
 
Wt::WValidator * anyNumberValidator_
 
Wt::WValidator * angleValidator_
 

Detailed Description

A class that allows configuration of a cartesian chart.

This widget provides forms for configuring chart, series, and axis properties and manipulates the chart according to user settings.

This widget is part of the Wt charts example.

Definition at line 40 of file ChartConfig.h.

Constructor & Destructor Documentation

◆ ChartConfig()

ChartConfig::ChartConfig ( Wt::Chart::WCartesianChart *  chart,
Wt::WContainerWidget *  parent 
)

Constructor.

Definition at line 77 of file ChartConfig.C.

78  : WContainerWidget(parent),
79  chart_(chart),
80  fill_(MinimumValueFill)
81 {
82  chart_->setLegendStyle(chart_->legendFont(), WPen(black),
83  WBrush(WColor(0xFF, 0xFA, 0xE5)));
84 
85  PanelList *list = new PanelList(this);
86 
87  WIntValidator *sizeValidator = new WIntValidator(200, 2000, this);
88  sizeValidator->setMandatory(true);
89 
90  anyNumberValidator_ = new WDoubleValidator(this);
91  anyNumberValidator_->setMandatory(true);
92 
93  angleValidator_ = new WDoubleValidator(-90, 90, this);
94  angleValidator_->setMandatory(true);
95 
96  // ---- Chart properties ----
97 
98  WStandardItemModel *orientation = new WStandardItemModel(0, 1, this);
99  addEntry(orientation, "Vertical");
100  addEntry(orientation, "Horizontal");
101 
102  WStandardItemModel *legendLocation = new WStandardItemModel(0, 1, this);
103  addEntry(legendLocation, "Outside");
104  addEntry(legendLocation, "Inside");
105 
106  WStandardItemModel *legendSide = new WStandardItemModel(0, 1, this);
107  addEntry(legendSide, "Top");
108  addEntry(legendSide, "Right");
109  addEntry(legendSide, "Bottom");
110  addEntry(legendSide, "Left");
111 
112  WStandardItemModel *legendAlignment = new WStandardItemModel(0, 1, this);
113  addEntry(legendAlignment, "AlignLeft");
114  addEntry(legendAlignment, "AlignCenter");
115  addEntry(legendAlignment, "AlignRight");
116  addEntry(legendAlignment, "AlignTop");
117  addEntry(legendAlignment, "AlignMiddle");
118  addEntry(legendAlignment, "AlignBottom");
119 
120  WTable *chartConfig = new WTable();
121  chartConfig->setMargin(WLength::Auto, Left | Right);
122 
123  int row = 0;
124  chartConfig->elementAt(row, 0)->addWidget(new WText("Title:"));
125  titleEdit_ = new WLineEdit(chartConfig->elementAt(row, 1));
127  ++row;
128 
129  chartConfig->elementAt(row, 0)->addWidget(new WText("Width:"));
130  chartWidthEdit_ = new WLineEdit(chartConfig->elementAt(row, 1));
132  ->setText(WLocale::currentLocale().toString(chart_->width().value()));
133  chartWidthEdit_->setValidator(sizeValidator);
134  chartWidthEdit_->setMaxLength(4);
136  ++row;
137 
138  chartConfig->elementAt(row, 0)->addWidget(new WText("Height:"));
139  chartHeightEdit_ = new WLineEdit(chartConfig->elementAt(row, 1));
141  ->setText(WLocale::currentLocale().toString(chart_->height().value()));
142  chartHeightEdit_->setValidator(sizeValidator);
143  chartHeightEdit_->setMaxLength(4);
145  ++row;
146 
147  chartConfig->elementAt(row, 0)->addWidget(new WText("Orientation:"));
148  chartOrientationEdit_ = new WComboBox(chartConfig->elementAt(row, 1));
149  chartOrientationEdit_->setModel(orientation);
150  chartOrientationEdit_->setCurrentIndex(0);
152  ++row;
153 
154  chartConfig->elementAt(row, 0)->addWidget(new WText("Legend location:"));
155  legendLocationEdit_ = new WComboBox(chartConfig->elementAt(row, 1));
156  legendLocationEdit_->setModel(legendLocation);
157  legendLocationEdit_->setCurrentIndex(0);
159  ++row;
160 
161  chartConfig->elementAt(row, 0)->addWidget(new WText("Legend side:"));
162  legendSideEdit_ = new WComboBox(chartConfig->elementAt(row, 1));
163  legendSideEdit_->setModel(legendSide);
164  legendSideEdit_->setCurrentIndex(1);
166  ++row;
167 
168  chartConfig->elementAt(row, 0)->addWidget(new WText("Legend alignment:"));
169  legendAlignmentEdit_ = new WComboBox(chartConfig->elementAt(row, 1));
170  legendAlignmentEdit_->setModel(legendAlignment);
171  legendAlignmentEdit_->setCurrentIndex(4);
173  ++row;
174 
175  chartConfig->elementAt(row, 0)->addWidget(new WText("Border:"));
176  borderEdit_ = new WCheckBox(chartConfig->elementAt(row, 1));
177  borderEdit_->setChecked(false);
179  ++row;
180 
181  for (int i = 0; i < chartConfig->rowCount(); ++i) {
182  chartConfig->elementAt(i, 0)->setStyleClass("tdhead");
183  chartConfig->elementAt(i, 1)->setStyleClass("tddata");
184  }
185 
186  WPanel *p = list->addWidget("Chart properties", chartConfig);
187  p->setMargin(WLength::Auto, Left | Right);
188  p->resize(1160, WLength::Auto);
189  p->setMargin(20, Top | Bottom);
190 
191  // ---- Series properties ----
192 
193  WStandardItemModel *types = new WStandardItemModel(0, 1, this);
194  addEntry(types, "Points");
195  addEntry(types, "Line");
196  addEntry(types, "Curve");
197  addEntry(types, "Bar");
198  addEntry(types, "Line Area");
199  addEntry(types, "Curve Area");
200  addEntry(types, "Stacked Bar");
201  addEntry(types, "Stacked Line Area");
202  addEntry(types, "Stacked Curve Area");
203 
204  WStandardItemModel *markers = new WStandardItemModel(0, 1, this);
205  addEntry(markers, "None");
206  addEntry(markers, "Square");
207  addEntry(markers, "Circle");
208  addEntry(markers, "Cross");
209  addEntry(markers, "X cross");
210  addEntry(markers, "Triangle");
211  addEntry(markers, "Pipe");
212  addEntry(markers, "Star");
213  addEntry(markers, "Inverted triangle");
214  addEntry(markers, "Asterisk");
215  addEntry(markers, "Diamond");
216 
217  yAxesModel_ = new WStandardItemModel(0, 1, this);
218  addEntry(yAxesModel_, axisName(YAxis, 0));
219  addEntry(yAxesModel_, axisName(YAxis, 1));
220 
221  WStandardItemModel *labels = new WStandardItemModel(0, 1, this);
222  addEntry(labels, "None");
223  addEntry(labels, "X");
224  addEntry(labels, "Y");
225  addEntry(labels, "X: Y");
226 
227  WTable *seriesConfig = new WTable();
228  seriesConfig->setMargin(WLength::Auto, Left | Right);
229 
230  ::addHeader(seriesConfig, "Name");
231  ::addHeader(seriesConfig, "Enabled");
232  ::addHeader(seriesConfig, "Type");
233  ::addHeader(seriesConfig, "Marker");
234  ::addHeader(seriesConfig, "Y axis");
235  ::addHeader(seriesConfig, "Legend");
236  ::addHeader(seriesConfig, "Shadow");
237  ::addHeader(seriesConfig, "Value labels");
238 
239  seriesConfig->rowAt(0)->setStyleClass("trhead");
240 
241  for (int j = 1; j < chart->model()->columnCount(); ++j) {
242  SeriesControl sc;
243 
244  new WText(chart->model()->headerData(j),
245  seriesConfig->elementAt(j, 0));
246 
247  sc.enabledEdit = new WCheckBox(seriesConfig->elementAt(j, 1));
248  connectSignals(sc.enabledEdit);
249 
250  sc.typeEdit = new WComboBox(seriesConfig->elementAt(j, 2));
251  sc.typeEdit->setModel(types);
252  sc.typeEdit->setCurrentIndex(0);
253  connectSignals(sc.typeEdit);
254 
255  sc.markerEdit = new WComboBox(seriesConfig->elementAt(j, 3));
256  sc.markerEdit->setModel(markers);
257  sc.markerEdit->setCurrentIndex(0);
258  connectSignals(sc.markerEdit);
259 
260  sc.axisEdit = new WComboBox(seriesConfig->elementAt(j, 4));
261  sc.axisEdit->setModel(yAxesModel_);
262  sc.axisEdit->setCurrentIndex(0);
263  connectSignals(sc.axisEdit);
264 
265  sc.legendEdit = new WCheckBox(seriesConfig->elementAt(j, 5));
266  connectSignals(sc.legendEdit);
267 
268  sc.shadowEdit = new WCheckBox(seriesConfig->elementAt(j, 6));
269  connectSignals(sc.shadowEdit);
270 
271  sc.labelsEdit = new WComboBox(seriesConfig->elementAt(j, 7));
272  sc.labelsEdit->setModel(labels);
273  sc.labelsEdit->setCurrentIndex(0);
274  connectSignals(sc.labelsEdit);
275 
276  int si = seriesIndexOf(chart, j);
277 
278  if (si != -1) {
279  sc.enabledEdit->setChecked();
280  const WDataSeries& s = chart_->series(j);
281  switch (s.type()) {
282  case PointSeries:
283  sc.typeEdit->setCurrentIndex(0); break;
284  case LineSeries:
285  sc.typeEdit->setCurrentIndex(s.fillRange() != NoFill ?
286  (s.isStacked() ? 7 : 4) : 1); break;
287  case CurveSeries:
288  sc.typeEdit->setCurrentIndex(s.fillRange() != NoFill ?
289  (s.isStacked() ? 8 : 5) : 2); break;
290  case BarSeries:
291  sc.typeEdit->setCurrentIndex(s.isStacked() ? 6 : 3);
292  }
293 
294  sc.markerEdit->setCurrentIndex((int)s.marker());
295  sc.legendEdit->setChecked(s.isLegendEnabled());
296  sc.shadowEdit->setChecked(s.shadow() != WShadow());
297  }
298 
299  seriesControls_.push_back(sc);
300 
301  seriesConfig->rowAt(j)->setStyleClass("trdata");
302  }
303 
304  p = list->addWidget("Series properties", seriesConfig);
305  p->expand();
306  p->setMargin(WLength::Auto, Left | Right);
307  p->resize(1160, WLength::Auto);
308  p->setMargin(20, Top | Bottom);
309 
310  // ---- Axis properties ----
311 
312  yScales_ = new WStandardItemModel(0, 1, this);
313  addEntry(yScales_, "Linear scale");
314  addEntry(yScales_, "Log scale");
315 
316  xScales_ = new WStandardItemModel(0, 1, this);
317  addEntry(xScales_, "Categories");
318  addEntry(xScales_, "Linear scale");
319  addEntry(xScales_, "Log scale");
320  addEntry(xScales_, "Date scale");
321 
322  WContainerWidget *axisConfig = new WContainerWidget();
323  axisConfig_ = new WTable(axisConfig);
324  axisConfig_->setMargin(WLength::Auto, Left | Right);
325 
326  ::addHeader(axisConfig_, "Axis");
327  ::addHeader(axisConfig_, "Visible");
328  ::addHeader(axisConfig_, "Scale");
329  ::addHeader(axisConfig_, "Automatic");
330  ::addHeader(axisConfig_, "Minimum");
331  ::addHeader(axisConfig_, "Maximum");
332  ::addHeader(axisConfig_, "Gridlines");
333  ::addHeader(axisConfig_, "Label angle");
334  ::addHeader(axisConfig_, "Title");
335  ::addHeader(axisConfig_, "Title orientation");
336  ::addHeader(axisConfig_, "Tick direction");
337  ::addHeader(axisConfig_, "Location");
338 
339  axisConfig_->rowAt(0)->setStyleClass("trhead");
340 
341  addAxis(XAxis, 0);
342  addAxis(YAxis, 0);
343  addAxis(YAxis, 1);
344 
345  WPushButton *addAxisBtn =
346  new WPushButton(Wt::utf8("Add Y axis"), axisConfig);
347  addAxisBtn->clicked().connect(this, &ChartConfig::addYAxis);
348  WPushButton *clearAxesBtn =
349  new WPushButton(Wt::utf8("Clear Y axes"), axisConfig);
350  clearAxesBtn->clicked().connect(this, &ChartConfig::clearYAxes);
351 
352  p = list->addWidget("Axis properties", axisConfig);
353  p->setMargin(WLength::Auto, Left | Right);
354  p->resize(1160, WLength::Auto);
355  p->setMargin(20, Top | Bottom);
356 
357  /*
358  * If we do not have JavaScript, then add a button to reflect changes to
359  * the chart.
360  */
361  if (!WApplication::instance()->environment().javaScript()) {
362  WPushButton *b = new WPushButton(this);
363  b->setText("Update chart");
364  b->setInline(false); // so we can add margin to center horizontally
365  b->setMargin(WLength::Auto, Left | Right);
366  b->clicked().connect(this, &ChartConfig::update);
367  }
368 }

Member Function Documentation

◆ addAxis()

void ChartConfig::addAxis ( Wt::Chart::Axis  axis,
int  yAxis 
)
private

Definition at line 658 of file ChartConfig.C.

659 {
660  int j = ax == XAxis ? 1 : yAxis + 2;
661 
662  const WAxis& axis = ax == XAxis ? chart_->axis(XAxis) : chart_->yAxis(yAxis);
663  AxisControl sc;
664 
665  new WText(axisName(axis.id(), axis.yAxisId()), axisConfig_->elementAt(j, 0));
666 
667  sc.visibleEdit = new WCheckBox(axisConfig_->elementAt(j, 1));
668  sc.visibleEdit->setChecked(axis.isVisible());
669  connectSignals(sc.visibleEdit);
670 
671  sc.scaleEdit = new WComboBox(axisConfig_->elementAt(j, 2));
672  if (axis.scale() == CategoryScale)
673  sc.scaleEdit->addItem("Category scale");
674  else {
675  if (axis.id() == XAxis) {
676  sc.scaleEdit->setModel(xScales_);
677  sc.scaleEdit->setCurrentIndex(axis.scale());
678  } else {
679  sc.scaleEdit->setModel(yScales_);
680  sc.scaleEdit->setCurrentIndex(axis.scale() - 1);
681  }
682  }
683  connectSignals(sc.scaleEdit);
684 
685  bool autoValues = axis.autoLimits() == (MinimumValue | MaximumValue);
686 
687  sc.minimumEdit = new WLineEdit(axisConfig_->elementAt(j, 4));
688  sc.minimumEdit->setText(WLocale::currentLocale()
689  .toString(axis.minimum()));
690  sc.minimumEdit->setValidator(anyNumberValidator_);
691  sc.minimumEdit->setEnabled(!autoValues);
692  connectSignals(sc.minimumEdit);
693 
694  sc.maximumEdit = new WLineEdit(axisConfig_->elementAt(j, 5));
695  sc.maximumEdit->setText(WLocale::currentLocale()
696  .toString(axis.maximum()));
697  sc.maximumEdit->setValidator(anyNumberValidator_);
698  sc.maximumEdit->setEnabled(!autoValues);
699  connectSignals(sc.maximumEdit);
700 
701  sc.autoEdit = new WCheckBox(axisConfig_->elementAt(j, 3));
702  sc.autoEdit->setChecked(autoValues);
703  connectSignals(sc.autoEdit);
704  sc.autoEdit->checked().connect(sc.maximumEdit, &WLineEdit::disable);
705  sc.autoEdit->unChecked().connect(sc.maximumEdit, &WLineEdit::enable);
706  sc.autoEdit->checked().connect(sc.minimumEdit, &WLineEdit::disable);
707  sc.autoEdit->unChecked().connect(sc.minimumEdit, &WLineEdit::enable);
708 
709  sc.gridLinesEdit = new WCheckBox(axisConfig_->elementAt(j, 6));
710  connectSignals(sc.gridLinesEdit);
711 
712  sc.labelAngleEdit = new WLineEdit(axisConfig_->elementAt(j, 7));
713  sc.labelAngleEdit->setText("0");
714  sc.labelAngleEdit->setValidator(angleValidator_);
715  connectSignals(sc.labelAngleEdit);
716 
717  sc.titleEdit = new WLineEdit(axisConfig_->elementAt(j, 8));
718  sc.titleEdit->setText("");
719  connectSignals(sc.titleEdit);
720 
721  sc.titleOrientationEdit = new WComboBox(axisConfig_->elementAt(j, 9));
722  sc.titleOrientationEdit->addItem("Horizontal");
723  sc.titleOrientationEdit->addItem("Vertical");
724  sc.titleOrientationEdit->setCurrentIndex(0);
725  connectSignals(sc.titleOrientationEdit);
726 
727  sc.tickDirectionEdit = new WComboBox(axisConfig_->elementAt(j, 10));
728  sc.tickDirectionEdit->addItem("Outwards");
729  sc.tickDirectionEdit->addItem("Inwards");
730  sc.tickDirectionEdit->setCurrentIndex(0);
731  connectSignals(sc.tickDirectionEdit);
732 
733  sc.locationEdit = new WComboBox(axisConfig_->elementAt(j, 11));
734  sc.locationEdit->addItem("Minimum value");
735  sc.locationEdit->addItem("Maximum value");
736  sc.locationEdit->addItem("Zero value");
737  sc.locationEdit->addItem("Both sides");
738  sc.locationEdit->setCurrentIndex(0);
739  if (axis.location() == MaximumValue) {
740  sc.locationEdit->setCurrentIndex(1);
741  } else if (axis.location() == ZeroValue) {
742  sc.locationEdit->setCurrentIndex(2);
743  }
744  connectSignals(sc.locationEdit);
745 
746  if (ax != XAxis) {
747  WPushButton *removeAxisButton =
748  new WPushButton(Wt::utf8("x"), axisConfig_->elementAt(j, 12));
749  removeAxisButton->clicked().connect(boost::bind(&ChartConfig::removeYAxis, this, &axis));
750  }
751 
752  axisConfig_->rowAt(j)->setStyleClass("trdata");
753 
754  axisControls_.push_back(sc);
755 }

◆ addYAxis()

void ChartConfig::addYAxis ( )
private

Definition at line 649 of file ChartConfig.C.

650 {
651  int yAxis = chart_->addYAxis(new WAxis());
652  addAxis(YAxis, yAxis);
653  addEntry(yAxesModel_, axisName(YAxis, yAxis));
654  if (yAxis == 0)
655  update();
656 }

◆ clearYAxes()

void ChartConfig::clearYAxes ( )
private

Definition at line 771 of file ChartConfig.C.

772 {
773  if (chart_->yAxisCount() == 0)
774  return;
775 
776  for (std::size_t i = 0; i < chart_->series().size(); ++i) {
777  chart_->series()[i]->bindToYAxis(-1);
778  }
779  chart_->clearYAxes();
780  while (axisConfig_->rowCount() > 2)
781  axisConfig_->deleteRow(2);
782  yAxesModel_->clear();
783  axisControls_.resize(1);
784 }

◆ connectSignals()

void ChartConfig::connectSignals ( Wt::WFormWidget *  w)
private

Definition at line 642 of file ChartConfig.C.

643 {
644  w->changed().connect(this, &ChartConfig::update);
645  if (dynamic_cast<WLineEdit *>(w))
646  w->enterPressed().connect(this, &ChartConfig::update);
647 }

◆ removeYAxis()

void ChartConfig::removeYAxis ( const Wt::Chart::WAxis *  axis)
private

Definition at line 757 of file ChartConfig.C.

758 {
759  int yAxis = axis->yAxisId();
760  for (std::size_t i = 0; i < chart_->series().size(); ++i) {
761  if (chart_->series()[i]->yAxis() == yAxis)
762  chart_->series()[i]->bindToYAxis(-1);
763  }
764  chart_->removeYAxis(yAxis);
765  axisConfig_->deleteRow(yAxis + 2);
766  yAxesModel_->removeRow(yAxis);
767  axisControls_.erase(axisControls_.begin() + yAxis + 1);
768  update();
769 }

◆ setValueFill()

void ChartConfig::setValueFill ( Wt::Chart::FillRangeType  fill)

Definition at line 370 of file ChartConfig.C.

371 {
372  fill_ = fill;
373 }

◆ update()

void ChartConfig::update ( )
private

Definition at line 375 of file ChartConfig.C.

376 {
377  bool haveLegend = false;
378  std::vector<WDataSeries *> series;
379 
380  for (int i = 1; i < chart_->model()->columnCount(); ++i) {
381  SeriesControl& sc = seriesControls_[i-1];
382 
383  if (sc.enabledEdit->isChecked()) {
384  WDataSeries *s = new WDataSeries(i);
385 
386  switch (sc.typeEdit->currentIndex()) {
387  case 0:
388  s->setType(PointSeries);
389  if (sc.markerEdit->currentIndex() == 0)
390  sc.markerEdit->setCurrentIndex(1);
391  break;
392  case 1:
393  s->setType(LineSeries);
394  break;
395  case 2:
396  s->setType(CurveSeries);
397  break;
398  case 3:
399  s->setType(BarSeries);
400  break;
401  case 4:
402  s->setType(LineSeries);
403  s->setFillRange(fill_);
404  break;
405  case 5:
406  s->setType(CurveSeries);
407  s->setFillRange(fill_);
408  break;
409  case 6:
410  s->setType(BarSeries);
411  s->setStacked(true);
412  break;
413  case 7:
414  s->setType(LineSeries);
415  s->setFillRange(fill_);
416  s->setStacked(true);
417  break;
418  case 8:
419  s->setType(CurveSeries);
420  s->setFillRange(fill_);
421  s->setStacked(true);
422  }
423 
424  //set WPainterPath to draw a pipe
425  if(sc.markerEdit->currentIndex() == CustomMarker){
426  WPainterPath pp = WPainterPath();
427  pp.moveTo(0, -6);
428  pp.lineTo(0, 6);
429  s->setCustomMarker(pp);
430  }
431 
432  s->setMarker(static_cast<MarkerType>(sc.markerEdit->currentIndex()));
433 
434  s->bindToYAxis(sc.axisEdit->currentIndex());
435 
436  if (sc.legendEdit->isChecked()) {
437  s->setLegendEnabled(true);
438  haveLegend = true;
439  } else
440  s->setLegendEnabled(false);
441 
442  if (sc.shadowEdit->isChecked()) {
443  s->setShadow(WShadow(3, 3, WColor(0, 0, 0, 127), 3));
444  } else
445  s->setShadow(WShadow());
446 
447  switch (sc.labelsEdit->currentIndex()) {
448  case 1:
449  s->setLabelsEnabled(XAxis);
450  break;
451  case 2:
452  s->setLabelsEnabled(YAxis);
453  break;
454  case 3:
455  s->setLabelsEnabled(XAxis);
456  s->setLabelsEnabled(YAxis);
457  break;
458  }
459 
460  series.push_back(s);
461  }
462  }
463 
464  chart_->setSeries(series);
465 
466  for (std::size_t i = 0; i < axisControls_.size(); ++i) {
467  AxisControl& sc = axisControls_[i];
468  WAxis& axis = i == 0 ? chart_->axis(XAxis) : chart_->yAxis(i - 1);
469 
470  axis.setVisible(sc.visibleEdit->isChecked());
471 
472  if (sc.scaleEdit->count() != 1) {
473  int k = sc.scaleEdit->currentIndex();
474  if (axis.id() != XAxis)
475  k += 1;
476  else {
477  if (k == 0)
478  chart_->setType(CategoryChart);
479  else
480  chart_->setType(ScatterPlot);
481  }
482 
483  switch (k) {
484  case 1:
485  axis.setScale(LinearScale); break;
486  case 2:
487  axis.setScale(LogScale); break;
488  case 3:
489  axis.setScale(DateScale); break;
490  }
491  }
492 
493  if (sc.autoEdit->isChecked())
494  axis.setAutoLimits(MinimumValue | MaximumValue);
495  else {
496  if (axis.autoLimits() & (MinimumValue | MaximumValue)) {
497  sc.minimumEdit->setText(WLocale::currentLocale()
498  .toString(axis.minimum()));
499  sc.maximumEdit->setText(WLocale::currentLocale()
500  .toString(axis.maximum()));
501  }
502  if (validate(sc.minimumEdit) && validate(sc.maximumEdit)) {
503  double min, max;
504  getDouble(sc.minimumEdit, min);
505  getDouble(sc.maximumEdit, max);
506 
507  if (axis.scale() == LogScale)
508  if (min <= 0)
509  min = 0.0001;
510 
511  if (axis.scale() == DateScale){
512  //the number of julian days until year 1986
513  WDate dMin = WDate(1900,1,1);
514  double gregDaysMin = (double)dMin.toJulianDay();
515  //the number of julian days until year 1988
516  WDate dMax = WDate(3000,1,1);
517  double gregDaysMax = (double)dMax.toJulianDay();
518 
519  bool greg_year_validation =
520  (min > gregDaysMin &&
521  min < gregDaysMax &&
522  max > gregDaysMin &&
523  max < gregDaysMax);
524 
525  if(!greg_year_validation){
526  min = gregDaysMin;
527  max = gregDaysMax;
528  }
529  }
530 
531  axis.setRange(min, max);
532  }
533 
534  }
535 
536  if (validate(sc.labelAngleEdit)) {
537  double angle;
538  getDouble(sc.labelAngleEdit, angle);
539  axis.setLabelAngle(angle);
540  }
541 
542  axis.setGridLinesEnabled(sc.gridLinesEdit->isChecked());
543 
544  axis.setTitle(sc.titleEdit->text());
545 
546  axis.setTitleOrientation(sc.titleOrientationEdit->currentIndex() == 0 ? Horizontal : Vertical);
547 
548  axis.setTickDirection(sc.tickDirectionEdit->currentIndex() == 0 ? Outwards : Inwards);
549 
550  switch (sc.locationEdit->currentIndex()) {
551  case 0:
552  axis.setLocation(MinimumValue);
553  break;
554  case 1:
555  axis.setLocation(MaximumValue);
556  break;
557  case 2:
558  axis.setLocation(ZeroValue);
559  break;
560  case 3:
561  axis.setLocation(BothSides);
562  break;
563  }
564  }
565 
566  chart_->setTitle(titleEdit_->text());
567 
569  double width, height;
570  getDouble(chartWidthEdit_, width);
571  getDouble(chartHeightEdit_, height);
572  chart_->resize(width, height);
573  }
574 
575  switch (chartOrientationEdit_->currentIndex()) {
576  case 0:
577  chart_->setOrientation(Vertical); break;
578  case 1:
579  chart_->setOrientation(Horizontal); break;
580  }
581 
582  chart_->setLegendEnabled(haveLegend);
583 
584  if (haveLegend) {
585  LegendLocation location = LegendOutside;
586  Side side = Right;
587  AlignmentFlag alignment = AlignMiddle;
588  switch (legendLocationEdit_->currentIndex()) {
589  case 0: location = LegendOutside; break;
590  case 1: location = LegendInside; break;
591  }
592 
593  switch (legendSideEdit_->currentIndex()) {
594  case 0: side = Top; break;
595  case 1: side = Right; break;
596  case 2: side = Bottom; break;
597  case 3: side = Left; break;
598  }
599 
600  if (side == Left || side == Right) {
601  if (legendAlignmentEdit_->currentIndex() < 3)
602  legendAlignmentEdit_->setCurrentIndex(4);
603  } else {
604  if (legendAlignmentEdit_->currentIndex() >= 3)
605  legendAlignmentEdit_->setCurrentIndex(2);
606  }
607 
608  switch (legendAlignmentEdit_->currentIndex()) {
609  case 0: alignment = AlignLeft; break;
610  case 1: alignment = AlignCenter; break;
611  case 2: alignment = AlignRight; break;
612  case 3: alignment = AlignTop; break;
613  case 4: alignment = AlignMiddle; break;
614  case 5: alignment = AlignBottom; break;
615  }
616 
617  chart_->setLegendLocation(location, side, alignment);
618 
619  chart_->setLegendColumns((side == Top || side == Bottom ) ? 2 : 1,
620  WLength(100));
621  }
622 
623  if (borderEdit_->isChecked()) {
624  chart_->setBorderPen(WPen());
625  } else {
626  chart_->setBorderPen(NoPen);
627  }
628 }

◆ validate()

bool ChartConfig::validate ( Wt::WFormWidget *  w)
staticprivate

Definition at line 630 of file ChartConfig.C.

631 {
632  bool valid = w->validate() == WValidator::Valid;
633 
634  if (!WApplication::instance()->environment().javaScript()) {
635  w->setStyleClass(valid ? "" : "Wt-invalid");
636  w->setToolTip(valid ? "" : "Invalid value");
637  }
638 
639  return valid;
640 }

Member Data Documentation

◆ angleValidator_

Wt::WValidator * ChartConfig::angleValidator_
private

Definition at line 96 of file ChartConfig.h.

◆ anyNumberValidator_

Wt::WValidator* ChartConfig::anyNumberValidator_
private

Definition at line 96 of file ChartConfig.h.

◆ axisConfig_

Wt::WTable* ChartConfig::axisConfig_
private

Definition at line 95 of file ChartConfig.h.

◆ axisControls_

std::vector<AxisControl> ChartConfig::axisControls_
private

Controls for axes.

Definition at line 83 of file ChartConfig.h.

◆ borderEdit_

Wt::WCheckBox* ChartConfig::borderEdit_
private

Definition at line 92 of file ChartConfig.h.

◆ chart_

Wt::Chart::WCartesianChart* ChartConfig::chart_
private

Definition at line 50 of file ChartConfig.h.

◆ chartHeightEdit_

Wt::WLineEdit* ChartConfig::chartHeightEdit_
private

Definition at line 87 of file ChartConfig.h.

◆ chartOrientationEdit_

Wt::WComboBox* ChartConfig::chartOrientationEdit_
private

Definition at line 88 of file ChartConfig.h.

◆ chartWidthEdit_

Wt::WLineEdit* ChartConfig::chartWidthEdit_
private

Definition at line 86 of file ChartConfig.h.

◆ fill_

Wt::Chart::FillRangeType ChartConfig::fill_
private

Definition at line 51 of file ChartConfig.h.

◆ legendAlignmentEdit_

Wt::WComboBox* ChartConfig::legendAlignmentEdit_
private

Definition at line 91 of file ChartConfig.h.

◆ legendLocationEdit_

Wt::WComboBox* ChartConfig::legendLocationEdit_
private

Definition at line 89 of file ChartConfig.h.

◆ legendSideEdit_

Wt::WComboBox* ChartConfig::legendSideEdit_
private

Definition at line 90 of file ChartConfig.h.

◆ seriesControls_

std::vector<SeriesControl> ChartConfig::seriesControls_
private

Controls for series.

Definition at line 65 of file ChartConfig.h.

◆ titleEdit_

Wt::WLineEdit* ChartConfig::titleEdit_
private

Definition at line 85 of file ChartConfig.h.

◆ xScales_

Wt::WStandardItemModel * ChartConfig::xScales_
private

Definition at line 94 of file ChartConfig.h.

◆ yAxesModel_

Wt::WStandardItemModel* ChartConfig::yAxesModel_
private

Definition at line 94 of file ChartConfig.h.

◆ yScales_

Wt::WStandardItemModel * ChartConfig::yScales_
private

Definition at line 94 of file ChartConfig.h.


The documentation for this class was generated from the following files:
ChartConfig::anyNumberValidator_
Wt::WValidator * anyNumberValidator_
Definition: ChartConfig.h:96
PanelList
Definition: PanelList.h:16
ChartConfig::xScales_
Wt::WStandardItemModel * xScales_
Definition: ChartConfig.h:94
ChartConfig::connectSignals
void connectSignals(Wt::WFormWidget *w)
Definition: ChartConfig.C:642
ChartConfig::titleEdit_
Wt::WLineEdit * titleEdit_
Definition: ChartConfig.h:85
ChartConfig::fill_
Wt::Chart::FillRangeType fill_
Definition: ChartConfig.h:51
ChartConfig::chart_
Wt::Chart::WCartesianChart * chart_
Definition: ChartConfig.h:50
ChartConfig::yAxesModel_
Wt::WStandardItemModel * yAxesModel_
Definition: ChartConfig.h:94
ChartConfig::axisConfig_
Wt::WTable * axisConfig_
Definition: ChartConfig.h:95
ChartConfig::chartWidthEdit_
Wt::WLineEdit * chartWidthEdit_
Definition: ChartConfig.h:86
ChartConfig::seriesControls_
std::vector< SeriesControl > seriesControls_
Controls for series.
Definition: ChartConfig.h:65
ChartConfig::legendSideEdit_
Wt::WComboBox * legendSideEdit_
Definition: ChartConfig.h:90
ChartConfig::update
void update()
Definition: ChartConfig.C:375
PanelList::addWidget
Wt::WPanel * addWidget(const Wt::WString &text, Wt::WWidget *w)
Definition: PanelList.C:17
ChartConfig::removeYAxis
void removeYAxis(const Wt::Chart::WAxis *axis)
Definition: ChartConfig.C:757
ChartConfig::chartOrientationEdit_
Wt::WComboBox * chartOrientationEdit_
Definition: ChartConfig.h:88
ChartConfig::legendLocationEdit_
Wt::WComboBox * legendLocationEdit_
Definition: ChartConfig.h:89
ChartConfig::clearYAxes
void clearYAxes()
Definition: ChartConfig.C:771
ChartConfig::axisControls_
std::vector< AxisControl > axisControls_
Controls for axes.
Definition: ChartConfig.h:83
ChartConfig::addYAxis
void addYAxis()
Definition: ChartConfig.C:649
ChartConfig::legendAlignmentEdit_
Wt::WComboBox * legendAlignmentEdit_
Definition: ChartConfig.h:91
ChartConfig::yScales_
Wt::WStandardItemModel * yScales_
Definition: ChartConfig.h:94
ChartConfig::chartHeightEdit_
Wt::WLineEdit * chartHeightEdit_
Definition: ChartConfig.h:87
ChartConfig::borderEdit_
Wt::WCheckBox * borderEdit_
Definition: ChartConfig.h:92
ChartConfig::validate
static bool validate(Wt::WFormWidget *w)
Definition: ChartConfig.C:630
ChartConfig::addAxis
void addAxis(Wt::Chart::Axis axis, int yAxis)
Definition: ChartConfig.C:658
ChartConfig::angleValidator_
Wt::WValidator * angleValidator_
Definition: ChartConfig.h:96

Generated on Mon Sep 5 2022 for the C++ Web Toolkit (Wt) by doxygen 1.8.17