12 #include <Wt/WAbstractItemModel.h> 13 #include <Wt/WApplication.h> 14 #include <Wt/WCheckBox.h> 15 #include <Wt/WComboBox.h> 16 #include <Wt/WDoubleValidator.h> 18 #include <Wt/WEnvironment.h> 19 #include <Wt/WIntValidator.h> 20 #include <Wt/WLineEdit.h> 21 #include <Wt/WLocale.h> 22 #include <Wt/WPanel.h> 23 #include <Wt/WPushButton.h> 24 #include <Wt/WStandardItemModel.h> 25 #include <Wt/WTable.h> 27 #include <Wt/WPainterPath.h> 29 #include <Wt/Chart/WCartesianChart.h> 35 void addHeader(
WTable *t,
const char *value) {
39 void addEntry(std::shared_ptr<WAbstractItemModel> model,
const char *value) {
40 model->insertRows(model->rowCount(), 1);
41 model->setData(model->rowCount()-1, 0, cpp17::any(std::string(value)));
44 bool getDouble(
WLineEdit *edit,
double& value) {
54 for (
unsigned i = 0; i < chart->
series().size(); ++i)
72 std::shared_ptr<WIntValidator> sizeValidator
73 = std::make_shared<WIntValidator>(200,2000);
74 sizeValidator->setMandatory(
true);
76 std::shared_ptr<WDoubleValidator> anyNumberValidator
77 = std::make_shared<WDoubleValidator>();
78 anyNumberValidator->setMandatory(
true);
80 std::shared_ptr<WDoubleValidator> angleValidator
81 = std::make_shared<WDoubleValidator>(-90,90);
82 angleValidator->setMandatory(
true);
86 std::shared_ptr<WStandardItemModel> orientation
87 = std::make_shared<WStandardItemModel>(0,1);
88 addEntry(orientation,
"Vertical");
89 addEntry(orientation,
"Horizontal");
91 std::shared_ptr<WStandardItemModel> legendLocation
92 = std::make_shared<WStandardItemModel>(0,1);
93 addEntry(legendLocation,
"Outside");
94 addEntry(legendLocation,
"Inside");
96 std::shared_ptr<WStandardItemModel> legendSide
97 = std::make_shared<WStandardItemModel>(0,1);
98 addEntry(legendSide,
"Top");
99 addEntry(legendSide,
"Right");
100 addEntry(legendSide,
"Bottom");
101 addEntry(legendSide,
"Left");
103 std::shared_ptr<WStandardItemModel> legendAlignment
104 = std::make_shared<WStandardItemModel>(0,1);
105 addEntry(legendAlignment,
"AlignLeft");
106 addEntry(legendAlignment,
"AlignCenter");
107 addEntry(legendAlignment,
"AlignRight");
108 addEntry(legendAlignment,
"AlignTop");
109 addEntry(legendAlignment,
"AlignMiddle");
110 addEntry(legendAlignment,
"AlignBottom");
112 std::unique_ptr<WTable> chartConfig
113 = cpp14::make_unique<WTable>();
114 chartConfig->setMargin(WLength::Auto, Side::Left | Side::Right);
117 chartConfig->elementAt(row, 0)->addWidget(cpp14::make_unique<WText>(
"Title:"));
118 titleEdit_ = chartConfig->elementAt(row,1)->addWidget(cpp14::make_unique<WLineEdit>());
122 chartConfig->elementAt(row, 0)->addWidget(cpp14::make_unique<WText>(
"Width:"));
123 chartWidthEdit_ = chartConfig->elementAt(row,1)->addWidget(cpp14::make_unique<WLineEdit>());
131 chartConfig->elementAt(row, 0)->addWidget(cpp14::make_unique<WText>(
"Height:"));
132 chartHeightEdit_ = chartConfig->elementAt(row,1)->addWidget(cpp14::make_unique<WLineEdit>());
140 chartConfig->elementAt(row, 0)->addWidget(cpp14::make_unique<WText>(
"Orientation:"));
147 chartConfig->elementAt(row, 0)->addWidget(cpp14::make_unique<WText>(
"Legend location:"));
148 legendLocationEdit_ = chartConfig->elementAt(row,1)->addWidget(cpp14::make_unique<WComboBox>());
154 chartConfig->elementAt(row, 0)->addWidget(cpp14::make_unique<WText>(
"Legend side:"));
155 legendSideEdit_ = chartConfig->elementAt(row,1)->addWidget(cpp14::make_unique<WComboBox>());
161 chartConfig->elementAt(row, 0)->addWidget(cpp14::make_unique<WText>(
"Legend alignment:"));
162 legendAlignmentEdit_ = chartConfig->elementAt(row,1)->addWidget(cpp14::make_unique<WComboBox>());
168 chartConfig->elementAt(row, 0)->addWidget(cpp14::make_unique<WText>(
"Border:"));
169 borderEdit_ = chartConfig->elementAt(row,1)->addWidget(cpp14::make_unique<WCheckBox>());
174 for (
int i = 0; i < chartConfig->rowCount(); ++i) {
175 chartConfig->elementAt(i, 0)->setStyleClass(
"tdhead");
176 chartConfig->elementAt(i, 1)->setStyleClass(
"tddata");
179 WPanel *p = list->
addWidget(
"Chart properties", std::move(chartConfig));
180 p->
setMargin(WLength::Auto, Side::Left | Side::Right);
181 p->
resize(1080, WLength::Auto);
182 p->
setMargin(20, Side::Top | Side::Bottom);
186 std::shared_ptr<WStandardItemModel> types
187 = std::make_shared<WStandardItemModel>(0,1);
188 addEntry(types,
"Points");
189 addEntry(types,
"Line");
190 addEntry(types,
"Curve");
191 addEntry(types,
"Bar");
192 addEntry(types,
"Line Area");
193 addEntry(types,
"Curve Area");
194 addEntry(types,
"Stacked Bar");
195 addEntry(types,
"Stacked Line Area");
196 addEntry(types,
"Stacked Curve Area");
198 std::shared_ptr<WStandardItemModel> markers
199 = std::make_shared<WStandardItemModel>(0,1);
200 addEntry(markers,
"None");
201 addEntry(markers,
"Square");
202 addEntry(markers,
"Circle");
203 addEntry(markers,
"Cross");
204 addEntry(markers,
"X cross");
205 addEntry(markers,
"Triangle");
206 addEntry(markers,
"Pipe");
207 addEntry(markers,
"Star");
208 addEntry(markers,
"Inverted triangle");
209 addEntry(markers,
"Asterisk");
210 addEntry(markers,
"Diamond");
212 std::shared_ptr<WStandardItemModel> axes
213 = std::make_shared<WStandardItemModel>(0,1);
214 addEntry(axes,
"1st Y axis");
215 addEntry(axes,
"2nd Y axis");
217 std::shared_ptr<WStandardItemModel> labels
218 = std::make_shared<WStandardItemModel>(0,1);
219 addEntry(labels,
"None");
220 addEntry(labels,
"X");
221 addEntry(labels,
"Y");
222 addEntry(labels,
"X: Y");
224 std::unique_ptr<WTable> seriesConfig
225 = cpp14::make_unique<WTable>();
226 WTable *seriesConfigPtr = seriesConfig.get();
227 seriesConfig->
setMargin(WLength::Auto, Side::Left | Side::Right);
228 ::addHeader(seriesConfigPtr,
"Name");
229 ::addHeader(seriesConfigPtr,
"Enabled");
230 ::addHeader(seriesConfigPtr,
"Type");
231 ::addHeader(seriesConfigPtr,
"Marker");
232 ::addHeader(seriesConfigPtr,
"Y axis");
233 ::addHeader(seriesConfigPtr,
"Legend");
234 ::addHeader(seriesConfigPtr,
"Shadow");
235 ::addHeader(seriesConfigPtr,
"Value labels");
237 seriesConfig->rowAt(0)->setStyleClass(
"trhead");
239 for (
int j = 1; j < chart->
model()->columnCount(); ++j) {
242 seriesConfig->elementAt(j,0)->addWidget(cpp14::make_unique<WText>(chart->
model()->headerData(j)));
244 sc.
enabledEdit = seriesConfig->elementAt(j,1)->addWidget(cpp14::make_unique<WCheckBox>());
247 sc.
typeEdit = seriesConfig->elementAt(j,2)->addWidget(cpp14::make_unique<WComboBox>());
252 sc.
markerEdit = seriesConfig->elementAt(j,3)->addWidget(cpp14::make_unique<WComboBox>());
257 sc.
axisEdit = seriesConfig->elementAt(j,4)->addWidget(cpp14::make_unique<WComboBox>());
262 sc.
legendEdit = seriesConfig->elementAt(j, 5)->addWidget(cpp14::make_unique<WCheckBox>());
265 sc.
shadowEdit = seriesConfig->elementAt(j,6)->addWidget(cpp14::make_unique<WCheckBox>());
268 sc.
labelsEdit = seriesConfig->elementAt(j,7)->addWidget(cpp14::make_unique<WComboBox>());
273 int si = seriesIndexOf(chart, j);
298 seriesConfig->rowAt(j)->setStyleClass(
"trdata");
301 p = list->
addWidget(
"Series properties", std::move(seriesConfig));
303 p->
setMargin(WLength::Auto, Side::Left | Side::Right);
304 p->
resize(1080, WLength::Auto);
305 p->
setMargin(20, Side::Top | Side::Bottom);
309 std::shared_ptr<WStandardItemModel> yScales
310 = std::make_shared<WStandardItemModel>(0,1);
311 addEntry(yScales,
"Linear scale");
312 addEntry(yScales,
"Log scale");
314 std::shared_ptr<WStandardItemModel> xScales
315 = std::make_shared<WStandardItemModel>(0,1);
316 addEntry(xScales,
"Categories");
317 addEntry(xScales,
"Linear scale");
318 addEntry(xScales,
"Log scale");
319 addEntry(xScales,
"Date scale");
321 std::unique_ptr<WTable> axisConfig
322 = cpp14::make_unique<WTable>();
323 axisConfig->setMargin(WLength::Auto, Side::Left | Side::Right);
324 WTable *axisConfigPtr = axisConfig.get();
326 ::addHeader(axisConfigPtr,
"Axis");
327 ::addHeader(axisConfigPtr,
"Visible");
328 ::addHeader(axisConfigPtr,
"Scale");
329 ::addHeader(axisConfigPtr,
"Automatic");
330 ::addHeader(axisConfigPtr,
"Minimum");
331 ::addHeader(axisConfigPtr,
"Maximum");
332 ::addHeader(axisConfigPtr,
"Gridlines");
333 ::addHeader(axisConfigPtr,
"Label angle");
334 ::addHeader(axisConfigPtr,
"Title");
335 ::addHeader(axisConfigPtr,
"Title orientation");
336 ::addHeader(axisConfigPtr,
"Tick direction");
337 ::addHeader(axisConfigPtr,
"Location");
339 axisConfig->rowAt(0)->setStyleClass(
"trhead");
341 for (
int i = 0; i < 3; ++i) {
342 const char *axisName[] = {
"X axis",
"1st Y axis",
"2nd Y axis" };
348 axisConfig->elementAt(j,0)->addWidget(cpp14::make_unique<WText>(
WString(axisName[i], CharEncoding::UTF8)));
350 sc.
visibleEdit = axisConfig->elementAt(j,1)->addWidget(cpp14::make_unique<WCheckBox>());
354 sc.
scaleEdit = axisConfig->elementAt(j,2)->addWidget(cpp14::make_unique<WComboBox>());
371 sc.
minimumEdit = axisConfig->elementAt(j,4)->addWidget(cpp14::make_unique<WLineEdit>());
378 sc.
maximumEdit = axisConfig->elementAt(j,5)->addWidget(cpp14::make_unique<WLineEdit>());
385 sc.
autoEdit = axisConfig->elementAt(j,3)->addWidget(cpp14::make_unique<WCheckBox>());
393 sc.
gridLinesEdit = axisConfig->elementAt(j,6)->addWidget(cpp14::make_unique<WCheckBox>());
396 sc.
labelAngleEdit = axisConfig->elementAt(j,7)->addWidget(cpp14::make_unique<WLineEdit>());
401 sc.
titleEdit = axisConfig->elementAt(j,8)->addWidget(cpp14::make_unique<WLineEdit>());
405 sc.
titleOrientationEdit = axisConfig->elementAt(j,9)->addWidget(cpp14::make_unique<WComboBox>());
411 sc.
tickDirectionEdit = axisConfig->elementAt(j,10)->addWidget(cpp14::make_unique<WComboBox>());
417 sc.
locationEdit = axisConfig->elementAt(j,11)->addWidget(cpp14::make_unique<WComboBox>());
428 axisConfig->rowAt(j)->setStyleClass(
"trdata");
433 p = list->
addWidget(
"Axis properties", std::move(axisConfig));
434 p->
setMargin(WLength::Auto, Side::Left | Side::Right);
435 p->
resize(1080, WLength::Auto);
436 p->
setMargin(20, Side::Top | Side::Bottom);
442 if (!WApplication::instance()->environment().javaScript()) {
443 auto *b = this->
addWidget(cpp14::make_unique<WPushButton>());
444 b->setText(
"Update chart");
446 b->setMargin(WLength::Auto, Side::Left | Side::Right);
458 bool haveLegend =
false;
459 std::vector<std::unique_ptr<WDataSeries>> series;
461 for (
int i = 1; i <
chart_->
model()->columnCount(); ++i) {
465 std::unique_ptr<WDataSeries> s
466 = cpp14::make_unique<WDataSeries>(i);
485 s->setFillRange(
fill_);
489 s->setFillRange(
fill_);
497 s->setFillRange(
fill_);
502 s->setFillRange(
fill_);
511 s->setCustomMarker(pp);
521 s->setLegendEnabled(
true);
524 s->setLegendEnabled(
false);
544 series.push_back(std::move(s));
550 for (
int i = 0; i < 3; ++i) {
603 bool greg_year_validation =
604 (min > gregDaysMin &&
609 if(!greg_year_validation){
670 Side side = Side::Right;
678 case 0: side = Side::Top;
break;
679 case 1: side = Side::Right;
break;
680 case 2: side = Side::Bottom;
break;
681 case 3: side = Side::Left;
break;
684 if (side == Side::Left || side == Side::Right) {
693 case 0: alignment = AlignmentFlag::Left;
break;
694 case 1: alignment = AlignmentFlag::Center;
break;
695 case 2: alignment = AlignmentFlag::Right;
break;
696 case 3: alignment = AlignmentFlag::Top;
break;
697 case 4: alignment = AlignmentFlag::Middle;
break;
698 case 5: alignment = AlignmentFlag::Bottom;
break;
716 bool valid = w->
validate() == ValidationState::Valid;
718 if (!WApplication::instance()->environment().javaScript()) {
729 if (dynamic_cast<WLineEdit *>(w))
void setVisible(bool visible)
ChartConfig(Wt::Chart::WCartesianChart *chart)
Constructor.
Wt::WCheckBox * borderEdit_
void lineTo(const WPointF &point)
MarkerType marker() const
virtual void setText(const WString &text)
bool isLegendEnabled() const
Wt::Chart::FillRangeType fill_
Wt::WComboBox * scaleEdit
Wt::WLineEdit * titleEdit_
void setGridLinesEnabled(bool enabled)
Wt::Chart::WCartesianChart * chart_
void addItem(const WString &text)
void setTickDirection(TickDirection direction)
void connectSignals(Wt::WFormWidget *w)
void setLocation(AxisValue value)
const WString & text() const
void setLegendStyle(const WFont &font, const WPen &border, const WBrush &background)
Wt::WCheckBox * enabledEdit
Wt::WComboBox * locationEdit
void setType(ChartType type)
Struct that holds the controls for one series.
Wt::WLineEdit * titleEdit
AxisValue location() const
void setSeries(std::vector< std::unique_ptr< WDataSeries >> series)
void setLegendLocation(LegendLocation location, Side side, AlignmentFlag alignment)
void setModel(const std::shared_ptr< WAbstractItemModel > model)
Wt::Signals::connection connect(const F &function)
Wt::WCheckBox * visibleEdit
Wt::WComboBox * markerEdit
Wt::WLineEdit * chartWidthEdit_
Struct that holds the controls for one axis.
WTableCell * elementAt(int row, int column)
Wt::WPanel * addWidget(const Wt::WString &text, std::unique_ptr< Wt::WWidget > w)
Wt::WComboBox * chartOrientationEdit_
Wt::WComboBox * legendLocationEdit_
std::vector< SeriesControl > seriesControls_
Controls for series.
void setCurrentIndex(int index)
void setScale(AxisScale scale)
WDataSeries & series(int modelColumn)
WFlags< AxisValue > autoLimits() const
Wt::WLineEdit * minimumEdit
std::shared_ptr< WAbstractChartModel > model() const
void setMaxLength(int length)
void setTitleOrientation(const Orientation &orientation)
FillRangeType fillRange() const
void setAutoLimits(WFlags< AxisValue > locations)
Wt::WComboBox * legendSideEdit_
std::vector< AxisControl > axisControls_
Controls for axes.
Wt::WCheckBox * shadowEdit
Wt::WComboBox * labelsEdit
void setValueFill(Wt::Chart::FillRangeType fill)
Wt::WComboBox * tickDirectionEdit
Wt::WLineEdit * labelAngleEdit
void moveTo(const WPointF &point)
void setOrientation(Orientation orientation)
void setBorderPen(const WPen &pen)
Wt::WCheckBox * legendEdit
void setRange(double minimum, double maximum)
Wt::WCheckBox * gridLinesEdit
void setLegendEnabled(bool enabled)
static const WLocale & currentLocale()
Wt::WComboBox * titleOrientationEdit
Wt::WComboBox * legendAlignmentEdit_
Wt::WLineEdit * maximumEdit
void setTitle(const WString &title)
void setLabelAngle(double angle)
void setLegendColumns(int columns, const WLength &width)
static bool validate(Wt::WFormWidget *w)
Wt::WLineEdit * chartHeightEdit_
double toDouble(const WString &value) const
void setTitle(const WString &title)
const WShadow & shadow() const