Wt examples  4.2.2
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)
 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_
 
std::shared_ptr< Wt::WStandardItemModel > yAxesModel_
 
std::shared_ptr< Wt::WStandardItemModel > xScales_
 
std::shared_ptr< Wt::WStandardItemModel > yScales_
 
Wt::WTable * axisConfig_
 
std::shared_ptr< Wt::WValidator > anyNumberValidator_
 
std::shared_ptr< 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)

Constructor.

Definition at line 76 of file ChartConfig.C.

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

Member Function Documentation

◆ addAxis()

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

Definition at line 667 of file ChartConfig.C.

668 {
669  int j = ax == Axis::X ? 1 : yAxis + 2;
670 
671  const WAxis& axis = ax == Axis::X ? chart_->axis(Axis::X) : chart_->yAxis(yAxis);
672  AxisControl sc;
673 
674  axisConfig_->elementAt(j, 0)->addNew<WText>(axisName(axis.id(), axis.yAxisId()));
675 
676  sc.visibleEdit = axisConfig_->elementAt(j, 1)->addNew<WCheckBox>();
677  sc.visibleEdit->setChecked(axis.isVisible());
678  connectSignals(sc.visibleEdit);
679 
680  sc.scaleEdit = axisConfig_->elementAt(j, 2)->addNew<WComboBox>();
681  if (axis.scale() == AxisScale::Discrete)
682  sc.scaleEdit->addItem("Discrete scale");
683  else {
684  if (axis.id() == Axis::X) {
685  sc.scaleEdit->setModel(xScales_);
686  sc.scaleEdit->setCurrentIndex(static_cast<int>(axis.scale()));
687  } else {
688  sc.scaleEdit->setModel(yScales_);
689  sc.scaleEdit->setCurrentIndex(static_cast<int>(axis.scale()) - 1);
690  }
691  }
692  connectSignals(sc.scaleEdit);
693 
694  bool autoValues = axis.autoLimits() == (AxisValue::Minimum | AxisValue::Maximum);
695 
696  sc.minimumEdit = axisConfig_->elementAt(j, 4)->addNew<WLineEdit>();
697  sc.minimumEdit->setText(WLocale::currentLocale()
698  .toString(axis.minimum()));
699  sc.minimumEdit->setValidator(anyNumberValidator_);
700  sc.minimumEdit->setEnabled(!autoValues);
701  connectSignals(sc.minimumEdit);
702 
703  sc.maximumEdit = axisConfig_->elementAt(j, 5)->addNew<WLineEdit>();
704  sc.maximumEdit->setText(WLocale::currentLocale()
705  .toString(axis.maximum()));
706  sc.maximumEdit->setValidator(anyNumberValidator_);
707  sc.maximumEdit->setEnabled(!autoValues);
708  connectSignals(sc.maximumEdit);
709 
710  sc.autoEdit = axisConfig_->elementAt(j, 3)->addNew<WCheckBox>();
711  sc.autoEdit->setChecked(autoValues);
712  connectSignals(sc.autoEdit);
713  sc.autoEdit->checked().connect(sc.maximumEdit, &WLineEdit::disable);
714  sc.autoEdit->unChecked().connect(sc.maximumEdit, &WLineEdit::enable);
715  sc.autoEdit->checked().connect(sc.minimumEdit, &WLineEdit::disable);
716  sc.autoEdit->unChecked().connect(sc.minimumEdit, &WLineEdit::enable);
717 
718  sc.gridLinesEdit = axisConfig_->elementAt(j, 6)->addNew<WCheckBox>();
719  connectSignals(sc.gridLinesEdit);
720 
721  sc.labelAngleEdit = axisConfig_->elementAt(j, 7)->addNew<WLineEdit>();
722  sc.labelAngleEdit->setText("0");
723  sc.labelAngleEdit->setValidator(angleValidator_);
724  connectSignals(sc.labelAngleEdit);
725 
726  sc.titleEdit = axisConfig_->elementAt(j, 8)->addNew<WLineEdit>();
727  sc.titleEdit->setText("");
728  connectSignals(sc.titleEdit);
729 
730  sc.titleOrientationEdit = axisConfig_->elementAt(j, 9)->addNew<WComboBox>();
731  sc.titleOrientationEdit->addItem("Horizontal");
732  sc.titleOrientationEdit->addItem("Vertical");
733  sc.titleOrientationEdit->setCurrentIndex(0);
734  connectSignals(sc.titleOrientationEdit);
735 
736  sc.tickDirectionEdit = axisConfig_->elementAt(j, 10)->addNew<WComboBox>();
737  sc.tickDirectionEdit->addItem("Outwards");
738  sc.tickDirectionEdit->addItem("Inwards");
739  sc.tickDirectionEdit->setCurrentIndex(0);
740  connectSignals(sc.tickDirectionEdit);
741 
742  sc.locationEdit = axisConfig_->elementAt(j, 11)->addNew<WComboBox>();
743  sc.locationEdit->addItem("Minimum value");
744  sc.locationEdit->addItem("Maximum value");
745  sc.locationEdit->addItem("Zero value");
746  sc.locationEdit->addItem("Both sides");
747  sc.locationEdit->setCurrentIndex(0);
748  if (axis.location() == AxisValue::Maximum) {
749  sc.locationEdit->setCurrentIndex(1);
750  } else if (axis.location() == AxisValue::Zero) {
751  sc.locationEdit->setCurrentIndex(2);
752  }
753  connectSignals(sc.locationEdit);
754 
755  if (ax != Axis::X) {
756  WPushButton *removeAxisButton =
757  axisConfig_->elementAt(j, 12)->addNew<WPushButton>(utf8("x"));
758  removeAxisButton->clicked().connect(std::bind(&ChartConfig::removeYAxis, this, &axis));
759  }
760 
761  axisConfig_->rowAt(j)->setStyleClass("trdata");
762 
763  axisControls_.push_back(sc);
764 }
std::shared_ptr< Wt::WStandardItemModel > xScales_
Definition: ChartConfig.h:94
std::shared_ptr< Wt::WValidator > angleValidator_
Definition: ChartConfig.h:96
Wt::Chart::WCartesianChart * chart_
Definition: ChartConfig.h:50
Wt::WTable * axisConfig_
Definition: ChartConfig.h:95
void connectSignals(Wt::WFormWidget *w)
Definition: ChartConfig.C:651
void removeYAxis(const Wt::Chart::WAxis *axis)
Definition: ChartConfig.C:766
std::vector< AxisControl > axisControls_
Controls for axes.
Definition: ChartConfig.h:83
std::shared_ptr< Wt::WStandardItemModel > yScales_
Definition: ChartConfig.h:94
std::shared_ptr< Wt::WValidator > anyNumberValidator_
Definition: ChartConfig.h:96

◆ addYAxis()

void ChartConfig::addYAxis ( )
private

Definition at line 658 of file ChartConfig.C.

659 {
660  int yAxis = chart_->addYAxis(cpp14::make_unique<WAxis>());
661  addAxis(Axis::Y, yAxis);
662  addEntry(yAxesModel_, axisName(Axis::Y, yAxis));
663  if (yAxis == 0)
664  update();
665 }
Wt::Chart::WCartesianChart * chart_
Definition: ChartConfig.h:50
void update()
Definition: ChartConfig.C:383
void addAxis(Wt::Chart::Axis axis, int yAxis)
Definition: ChartConfig.C:667
std::shared_ptr< Wt::WStandardItemModel > yAxesModel_
Definition: ChartConfig.h:94

◆ clearYAxes()

void ChartConfig::clearYAxes ( )
private

Definition at line 780 of file ChartConfig.C.

781 {
782  if (chart_->yAxisCount() == 0)
783  return;
784 
785  for (std::size_t i = 0; i < chart_->series().size(); ++i) {
786  chart_->series()[i]->bindToYAxis(-1);
787  }
788  chart_->clearYAxes();
789  while (axisConfig_->rowCount() > 2)
790  axisConfig_->removeRow(2);
791  yAxesModel_->clear();
792  axisControls_.resize(1);
793 }
Wt::Chart::WCartesianChart * chart_
Definition: ChartConfig.h:50
Wt::WTable * axisConfig_
Definition: ChartConfig.h:95
std::vector< AxisControl > axisControls_
Controls for axes.
Definition: ChartConfig.h:83
std::shared_ptr< Wt::WStandardItemModel > yAxesModel_
Definition: ChartConfig.h:94

◆ connectSignals()

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

Definition at line 651 of file ChartConfig.C.

652 {
653  w->changed().connect(this, &ChartConfig::update);
654  if (dynamic_cast<WLineEdit *>(w))
655  w->enterPressed().connect(this, &ChartConfig::update);
656 }
void update()
Definition: ChartConfig.C:383

◆ removeYAxis()

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

Definition at line 766 of file ChartConfig.C.

767 {
768  int yAxis = axis->yAxisId();
769  for (std::size_t i = 0; i < chart_->series().size(); ++i) {
770  if (chart_->series()[i]->yAxis() == yAxis)
771  chart_->series()[i]->bindToYAxis(-1);
772  }
773  chart_->removeYAxis(yAxis);
774  axisConfig_->removeRow(yAxis + 2);
775  yAxesModel_->removeRow(yAxis);
776  axisControls_.erase(axisControls_.begin() + yAxis + 1);
777  update();
778 }
Wt::Chart::WCartesianChart * chart_
Definition: ChartConfig.h:50
Wt::WTable * axisConfig_
Definition: ChartConfig.h:95
std::vector< AxisControl > axisControls_
Controls for axes.
Definition: ChartConfig.h:83
void update()
Definition: ChartConfig.C:383
std::shared_ptr< Wt::WStandardItemModel > yAxesModel_
Definition: ChartConfig.h:94

◆ setValueFill()

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

Definition at line 378 of file ChartConfig.C.

379 {
380  fill_ = fill;
381 }
Wt::Chart::FillRangeType fill_
Definition: ChartConfig.h:51

◆ update()

void ChartConfig::update ( )
private

Definition at line 383 of file ChartConfig.C.

384 {
385  bool haveLegend = false;
386  std::vector<std::unique_ptr<WDataSeries>> series;
387 
388  for (int i = 1; i < chart_->model()->columnCount(); ++i) {
389  SeriesControl& sc = seriesControls_[i-1];
390 
391  if (sc.enabledEdit->isChecked()) {
392  std::unique_ptr<WDataSeries> s
393  = cpp14::make_unique<WDataSeries>(i);
394 
395  switch (sc.typeEdit->currentIndex()) {
396  case 0:
397  s->setType(SeriesType::Point);
398  if (sc.markerEdit->currentIndex() == 0)
399  sc.markerEdit->setCurrentIndex(1);
400  break;
401  case 1:
402  s->setType(SeriesType::Line);
403  break;
404  case 2:
405  s->setType(SeriesType::Curve);
406  break;
407  case 3:
408  s->setType(SeriesType::Bar);
409  break;
410  case 4:
411  s->setType(SeriesType::Line);
412  s->setFillRange(fill_);
413  break;
414  case 5:
415  s->setType(SeriesType::Curve);
416  s->setFillRange(fill_);
417  break;
418  case 6:
419  s->setType(SeriesType::Bar);
420  s->setStacked(true);
421  break;
422  case 7:
423  s->setType(SeriesType::Line);
424  s->setFillRange(fill_);
425  s->setStacked(true);
426  break;
427  case 8:
428  s->setType(SeriesType::Curve);
429  s->setFillRange(fill_);
430  s->setStacked(true);
431  }
432 
433  //set WPainterPath to draw a pipe
434  if(sc.markerEdit->currentIndex() == static_cast<int>(MarkerType::Custom)){ //was customMarker before
435  WPainterPath pp = WPainterPath();
436  pp.moveTo(0, -6);
437  pp.lineTo(0, 6);
438  s->setCustomMarker(pp);
439  }
440 
441  s->setMarker(static_cast<MarkerType>(sc.markerEdit->currentIndex()));
442 
443  s->bindToYAxis(sc.axisEdit->currentIndex());
444 
445  if (sc.legendEdit->isChecked()) {
446  s->setLegendEnabled(true);
447  haveLegend = true;
448  } else
449  s->setLegendEnabled(false);
450 
451  if (sc.shadowEdit->isChecked()) {
452  s->setShadow(WShadow(3, 3, WColor(0, 0, 0, 127), 3));
453  } else
454  s->setShadow(WShadow());
455 
456  switch (sc.labelsEdit->currentIndex()) {
457  case 1:
458  s->setLabelsEnabled(Axis::X);
459  break;
460  case 2:
461  s->setLabelsEnabled(Axis::Y);
462  break;
463  case 3:
464  s->setLabelsEnabled(Axis::X);
465  s->setLabelsEnabled(Axis::Y);
466  break;
467  }
468 
469  series.push_back(std::move(s));
470  }
471  }
472 
473  chart_->setSeries(std::move(series));
474 
475  for (std::size_t i = 0; i < axisControls_.size(); ++i) {
476  AxisControl& sc = axisControls_[i];
477  WAxis& axis = i == 0 ? chart_->axis(Axis::X) : chart_->yAxis(i - 1);
478 
479  axis.setVisible(sc.visibleEdit->isChecked());
480 
481  if (sc.scaleEdit->count() != 1) {
482  int k = sc.scaleEdit->currentIndex();
483  if (axis.id() != Axis::X)
484  k += 1;
485  else {
486  if (k == 0)
487  chart_->setType(ChartType::Category);
488  else
489  chart_->setType(ChartType::Scatter);
490  }
491 
492  switch (k) {
493  case 1:
494  axis.setScale(AxisScale::Linear); break;
495  case 2:
496  axis.setScale(AxisScale::Log); break;
497  case 3:
498  axis.setScale(AxisScale::Date); break;
499  }
500  }
501 
502  if (sc.autoEdit->isChecked())
503  axis.setAutoLimits(AxisValue::Minimum | AxisValue::Maximum);
504  else {
505  if (!(axis.autoLimits() & (AxisValue::Minimum | AxisValue::Maximum)).empty()) {
506  sc.minimumEdit->setText(WLocale::currentLocale()
507  .toString(axis.minimum()));
508  sc.maximumEdit->setText(WLocale::currentLocale()
509  .toString(axis.maximum()));
510  }
511  if (validate(sc.minimumEdit) && validate(sc.maximumEdit)) {
512  double min, max;
513  getDouble(sc.minimumEdit, min);
514  getDouble(sc.maximumEdit, max);
515 
516  if (axis.scale() == AxisScale::Log)
517  if (min <= 0)
518  min = 0.0001;
519 
520  if (axis.scale() == AxisScale::Date){
521  //the number of julian days until year 1986
522  WDate dMin = WDate(1900,1,1);
523  double gregDaysMin = (double)dMin.toJulianDay();
524  //the number of julian days until year 1988
525  WDate dMax = WDate(3000,1,1);
526  double gregDaysMax = (double)dMax.toJulianDay();
527 
528  bool greg_year_validation =
529  (min > gregDaysMin &&
530  min < gregDaysMax &&
531  max > gregDaysMin &&
532  max < gregDaysMax);
533 
534  if(!greg_year_validation){
535  min = gregDaysMin;
536  max = gregDaysMax;
537  }
538  }
539 
540  axis.setRange(min, max);
541  }
542 
543  }
544 
545  if (validate(sc.labelAngleEdit)) {
546  double angle;
547  getDouble(sc.labelAngleEdit, angle);
548  axis.setLabelAngle(angle);
549  }
550 
551  axis.setGridLinesEnabled(sc.gridLinesEdit->isChecked());
552 
553  axis.setTitle(sc.titleEdit->text());
554 
555  axis.setTitleOrientation(sc.titleOrientationEdit->currentIndex() == 0 ? Orientation::Horizontal : Orientation::Vertical);
556 
557  axis.setTickDirection(sc.tickDirectionEdit->currentIndex() == 0 ? TickDirection::Outwards : TickDirection::Inwards);
558 
559  switch (sc.locationEdit->currentIndex()) {
560  case 0:
561  axis.setLocation(AxisValue::Minimum);
562  break;
563  case 1:
564  axis.setLocation(AxisValue::Maximum);
565  break;
566  case 2:
567  axis.setLocation(AxisValue::Zero);
568  break;
569  case 3:
570  axis.setLocation(AxisValue::Both);
571  break;
572  }
573  }
574 
575  chart_->setTitle(titleEdit_->text());
576 
578  double width, height;
579  getDouble(chartWidthEdit_, width);
580  getDouble(chartHeightEdit_, height);
581  chart_->resize(width, height);
582  }
583 
584  switch (chartOrientationEdit_->currentIndex()) {
585  case 0:
586  chart_->setOrientation(Orientation::Vertical); break;
587  case 1:
588  chart_->setOrientation(Orientation::Horizontal); break;
589  }
590 
591  chart_->setLegendEnabled(haveLegend);
592 
593  if (haveLegend) {
594  LegendLocation location = LegendLocation::Outside;
595  Side side = Side::Right;
596  AlignmentFlag alignment = AlignmentFlag::Middle;
597  switch (legendLocationEdit_->currentIndex()) {
598  case 0: location = LegendLocation::Outside; break;
599  case 1: location = LegendLocation::Inside; break;
600  }
601 
602  switch (legendSideEdit_->currentIndex()) {
603  case 0: side = Side::Top; break;
604  case 1: side = Side::Right; break;
605  case 2: side = Side::Bottom; break;
606  case 3: side = Side::Left; break;
607  }
608 
609  if (side == Side::Left || side == Side::Right) {
610  if (legendAlignmentEdit_->currentIndex() < 3)
611  legendAlignmentEdit_->setCurrentIndex(4);
612  } else {
613  if (legendAlignmentEdit_->currentIndex() >= 3)
614  legendAlignmentEdit_->setCurrentIndex(2);
615  }
616 
617  switch (legendAlignmentEdit_->currentIndex()) {
618  case 0: alignment = AlignmentFlag::Left; break;
619  case 1: alignment = AlignmentFlag::Center; break;
620  case 2: alignment = AlignmentFlag::Right; break;
621  case 3: alignment = AlignmentFlag::Top; break;
622  case 4: alignment = AlignmentFlag::Middle; break;
623  case 5: alignment = AlignmentFlag::Bottom; break;
624  }
625 
626  chart_->setLegendLocation(location, side, alignment);
627 
628  chart_->setLegendColumns((side == Side::Top || side == Side::Bottom ) ? 2 : 1,
629  WLength(100));
630  }
631 
632  if (borderEdit_->isChecked()) {
633  chart_->setBorderPen(WPen());
634  } else {
635  chart_->setBorderPen(PenStyle::None);
636  }
637 }
Wt::WCheckBox * borderEdit_
Definition: ChartConfig.h:92
Wt::Chart::FillRangeType fill_
Definition: ChartConfig.h:51
Wt::WLineEdit * titleEdit_
Definition: ChartConfig.h:85
Wt::Chart::WCartesianChart * chart_
Definition: ChartConfig.h:50
Wt::WLineEdit * chartWidthEdit_
Definition: ChartConfig.h:86
Wt::WComboBox * chartOrientationEdit_
Definition: ChartConfig.h:88
Wt::WComboBox * legendLocationEdit_
Definition: ChartConfig.h:89
std::vector< SeriesControl > seriesControls_
Controls for series.
Definition: ChartConfig.h:65
Wt::WComboBox * legendSideEdit_
Definition: ChartConfig.h:90
std::vector< AxisControl > axisControls_
Controls for axes.
Definition: ChartConfig.h:83
Wt::WComboBox * legendAlignmentEdit_
Definition: ChartConfig.h:91
static bool validate(Wt::WFormWidget *w)
Definition: ChartConfig.C:639
Wt::WLineEdit * chartHeightEdit_
Definition: ChartConfig.h:87

◆ validate()

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

Definition at line 639 of file ChartConfig.C.

640 {
641  bool valid = w->validate() == ValidationState::Valid;
642 
643  if (!WApplication::instance()->environment().javaScript()) {
644  w->setStyleClass(valid ? "" : "Wt-invalid");
645  w->setToolTip(valid ? "" : "Invalid value");
646  }
647 
648  return valid;
649 }

Member Data Documentation

◆ angleValidator_

std::shared_ptr<Wt::WValidator> ChartConfig::angleValidator_
private

Definition at line 96 of file ChartConfig.h.

◆ anyNumberValidator_

std::shared_ptr<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_

std::shared_ptr<Wt::WStandardItemModel> ChartConfig::xScales_
private

Definition at line 94 of file ChartConfig.h.

◆ yAxesModel_

std::shared_ptr<Wt::WStandardItemModel> ChartConfig::yAxesModel_
private

Definition at line 94 of file ChartConfig.h.

◆ yScales_

std::shared_ptr<Wt::WStandardItemModel> ChartConfig::yScales_
private

Definition at line 94 of file ChartConfig.h.


The documentation for this class was generated from the following files:

Generated on Fri Mar 20 2020 for the C++ Web Toolkit (Wt) by doxygen 1.8.15