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(
const 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 void addEntry(
const std::shared_ptr<WAbstractItemModel>& model,
const WString &value) {
45 model->insertRows(model->rowCount(), 1);
46 model->setData(model->rowCount()-1, 0, cpp17::any(value));
49 bool getDouble(
WLineEdit *edit,
double& value) {
59 for (
unsigned i = 0; i < chart->
series().size(); ++i)
69 return Wt::utf8(
"X Axis {1}").
arg(axisId + 1);
71 return Wt::utf8(
"Y axis {1}").
arg(axisId + 1);
86 std::shared_ptr<WIntValidator> sizeValidator
87 = std::make_shared<WIntValidator>(200,2000);
88 sizeValidator->setMandatory(
true);
98 std::shared_ptr<WStandardItemModel> orientation
99 = std::make_shared<WStandardItemModel>(0,1);
100 addEntry(orientation,
"Vertical");
101 addEntry(orientation,
"Horizontal");
103 std::shared_ptr<WStandardItemModel> legendLocation
104 = std::make_shared<WStandardItemModel>(0,1);
105 addEntry(legendLocation,
"Outside");
106 addEntry(legendLocation,
"Inside");
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");
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");
124 std::unique_ptr<WTable> chartConfig
125 = std::make_unique<WTable>();
126 chartConfig->setMargin(WLength::Auto, Side::Left | Side::Right);
129 chartConfig->elementAt(row, 0)->addWidget(std::make_unique<WText>(
"Title:"));
130 titleEdit_ = chartConfig->elementAt(row,1)->addWidget(std::make_unique<WLineEdit>());
134 chartConfig->elementAt(row, 0)->addWidget(std::make_unique<WText>(
"Width:"));
135 chartWidthEdit_ = chartConfig->elementAt(row,1)->addWidget(std::make_unique<WLineEdit>());
143 chartConfig->elementAt(row, 0)->addWidget(std::make_unique<WText>(
"Height:"));
144 chartHeightEdit_ = chartConfig->elementAt(row,1)->addWidget(std::make_unique<WLineEdit>());
152 chartConfig->elementAt(row, 0)->addWidget(std::make_unique<WText>(
"Orientation:"));
159 chartConfig->elementAt(row, 0)->addWidget(std::make_unique<WText>(
"Legend location:"));
160 legendLocationEdit_ = chartConfig->elementAt(row,1)->addWidget(std::make_unique<WComboBox>());
166 chartConfig->elementAt(row, 0)->addWidget(std::make_unique<WText>(
"Legend side:"));
167 legendSideEdit_ = chartConfig->elementAt(row,1)->addWidget(std::make_unique<WComboBox>());
173 chartConfig->elementAt(row, 0)->addWidget(std::make_unique<WText>(
"Legend alignment:"));
180 chartConfig->elementAt(row, 0)->addWidget(std::make_unique<WText>(
"Border:"));
181 borderEdit_ = chartConfig->elementAt(row,1)->addWidget(std::make_unique<WCheckBox>());
186 for (
int i = 0; i < chartConfig->rowCount(); ++i) {
187 chartConfig->elementAt(i, 0)->setStyleClass(
"tdhead");
188 chartConfig->elementAt(i, 1)->setStyleClass(
"tddata");
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);
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");
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");
224 xAxesModel_ = std::make_shared<WStandardItemModel>(0, 1);
227 yAxesModel_ = std::make_shared<WStandardItemModel>(0, 1);
231 std::shared_ptr<WStandardItemModel> labels
232 = std::make_shared<WStandardItemModel>(0,1);
233 addEntry(labels,
"None");
234 addEntry(labels,
"X");
235 addEntry(labels,
"Y");
236 addEntry(labels,
"X: Y");
238 std::unique_ptr<WTable> seriesConfig
239 = std::make_unique<WTable>();
240 WTable *seriesConfigPtr = seriesConfig.get();
241 seriesConfig->
setMargin(WLength::Auto, Side::Left | Side::Right);
242 ::addHeader(seriesConfigPtr,
"Name");
243 ::addHeader(seriesConfigPtr,
"Enabled");
244 ::addHeader(seriesConfigPtr,
"Type");
245 ::addHeader(seriesConfigPtr,
"Marker");
246 ::addHeader(seriesConfigPtr,
"X axis");
247 ::addHeader(seriesConfigPtr,
"Y axis");
248 ::addHeader(seriesConfigPtr,
"Legend");
249 ::addHeader(seriesConfigPtr,
"Shadow");
250 ::addHeader(seriesConfigPtr,
"Value labels");
252 seriesConfig->rowAt(0)->setStyleClass(
"trhead");
254 for (
int j = 1; j < chart->
model()->columnCount(); ++j) {
257 seriesConfig->elementAt(j,0)->addWidget(std::make_unique<WText>(chart->
model()->headerData(j)));
259 sc.
enabledEdit = seriesConfig->elementAt(j,1)->addWidget(std::make_unique<WCheckBox>());
262 sc.
typeEdit = seriesConfig->elementAt(j,2)->addWidget(std::make_unique<WComboBox>());
267 sc.
markerEdit = seriesConfig->elementAt(j,3)->addWidget(std::make_unique<WComboBox>());
282 sc.
legendEdit = seriesConfig->elementAt(j, 6)->addWidget(std::make_unique<WCheckBox>());
285 sc.
shadowEdit = seriesConfig->elementAt(j, 7)->addWidget(std::make_unique<WCheckBox>());
288 sc.
labelsEdit = seriesConfig->elementAt(j, 8)->addWidget(std::make_unique<WComboBox>());
293 int si = seriesIndexOf(chart, j);
318 seriesConfig->rowAt(j)->setStyleClass(
"trdata");
321 p = list->
addWidget(
"Series properties", std::move(seriesConfig));
323 p->
setMargin(WLength::Auto, Side::Left | Side::Right);
324 p->
resize(1160, WLength::Auto);
325 p->
setMargin(20, Side::Top | Side::Bottom);
329 yScales_ = std::make_shared<WStandardItemModel>(0, 1);
333 xScales_ = std::make_shared<WStandardItemModel>(0, 1);
339 auto axisConfig = std::make_unique<WContainerWidget>();
363 axisConfig->addNew<
WPushButton>(Wt::utf8(
"Add X axis"));
366 axisConfig->addNew<
WPushButton>(Wt::utf8(
"Clear X axes"));
369 axisConfig->addNew<
WPushButton>(utf8(
"Add Y axis"));
372 axisConfig->addNew<
WPushButton>(utf8(
"Clear Y axes"));
375 p = list->
addWidget(
"Axis properties", std::move(axisConfig));
376 p->
setMargin(WLength::Auto, Side::Left | Side::Right);
377 p->
resize(1160, WLength::Auto);
378 p->
setMargin(20, Side::Top | Side::Bottom);
384 if (!WApplication::instance()->environment().javaScript()) {
385 auto *b = this->
addWidget(std::make_unique<WPushButton>());
386 b->setText(
"Update chart");
388 b->setMargin(WLength::Auto, Side::Left | Side::Right);
400 bool haveLegend =
false;
401 std::vector<std::unique_ptr<WDataSeries>> series;
403 for (
int i = 1; i <
chart_->
model()->columnCount(); ++i) {
407 std::unique_ptr<WDataSeries> s
408 = std::make_unique<WDataSeries>(i);
427 s->setFillRange(
fill_);
431 s->setFillRange(
fill_);
439 s->setFillRange(
fill_);
444 s->setFillRange(
fill_);
453 s->setCustomMarker(pp);
462 s->setLegendEnabled(
true);
465 s->setLegendEnabled(
false);
485 series.push_back(std::move(s));
544 bool greg_year_validation =
545 (min > gregDaysMin &&
550 if(!greg_year_validation){
611 Side side = Side::Right;
619 case 0: side = Side::Top;
break;
620 case 1: side = Side::Right;
break;
621 case 2: side = Side::Bottom;
break;
622 case 3: side = Side::Left;
break;
625 if (side == Side::Left || side == Side::Right) {
634 case 0: alignment = AlignmentFlag::Left;
break;
635 case 1: alignment = AlignmentFlag::Center;
break;
636 case 2: alignment = AlignmentFlag::Right;
break;
637 case 3: alignment = AlignmentFlag::Top;
break;
638 case 4: alignment = AlignmentFlag::Middle;
break;
639 case 5: alignment = AlignmentFlag::Bottom;
break;
657 bool valid = w->
validate() == ValidationState::Valid;
659 if (!WApplication::instance()->environment().javaScript()) {
797 for (std::size_t i = 0; i <
chart_->
series().size(); ++i) {
811 for (std::size_t i = 0; i <
chart_->
series().size(); ++i) {
827 for (std::size_t i = 0; i <
chart_->
series().size(); ++i) {
832 for (
int i = 0; i < xAxisCount; ++i) {
844 for (std::size_t i = 0; i <
chart_->
series().size(); ++i) {
849 for (
int i = 0; i < yAxisCount; ++i) {
std::vector< SeriesControl > seriesControls_
Controls for series.
void addAxis(Wt::Chart::Axis axis, int axisId)
Wt::WComboBox * legendAlignmentEdit_
Wt::WComboBox * legendLocationEdit_
std::shared_ptr< Wt::WValidator > angleValidator_
Wt::WComboBox * legendSideEdit_
void removeXAxis(const Wt::Chart::WAxis *axis)
std::shared_ptr< Wt::WValidator > anyNumberValidator_
void setValueFill(Wt::Chart::FillRangeType fill)
Wt::WLineEdit * chartWidthEdit_
Wt::WLineEdit * titleEdit_
void removeYAxis(const Wt::Chart::WAxis *axis)
std::shared_ptr< Wt::WStandardItemModel > xAxesModel_
static bool validate(Wt::WFormWidget *w)
void connectSignals(Wt::WFormWidget *w)
Wt::Chart::WCartesianChart * chart_
std::vector< AxisControl > axisControls_
Controls for axes.
ChartConfig(Wt::Chart::WCartesianChart *chart)
Constructor.
std::shared_ptr< Wt::WStandardItemModel > xScales_
Wt::Chart::FillRangeType fill_
Wt::WCheckBox * borderEdit_
Wt::WLineEdit * chartHeightEdit_
std::shared_ptr< Wt::WStandardItemModel > yAxesModel_
Wt::WComboBox * chartOrientationEdit_
std::shared_ptr< Wt::WStandardItemModel > yScales_
Wt::WPanel * addWidget(const Wt::WString &text, std::unique_ptr< Wt::WWidget > w)
std::shared_ptr< WAbstractChartModel > model() const
void setTitle(const WString &title)
WFlags< AxisValue > autoLimits() const
void setAutoLimits(WFlags< AxisValue > locations)
void setVisible(bool visible)
void setLocation(AxisValue value)
void setGridLinesEnabled(bool enabled)
void setRange(double minimum, double maximum)
void setScale(AxisScale scale)
void setTickDirection(TickDirection direction)
AxisValue location() const
void setTitleOrientation(const Orientation &orientation)
void setTitle(const WString &title)
void setLabelAngle(double angle)
void setType(ChartType type)
int addYAxis(std::unique_ptr< WAxis > waxis)
void setLegendEnabled(bool enabled)
int addXAxis(std::unique_ptr< WAxis > waxis)
std::unique_ptr< WAxis > removeXAxis(int xAxisId)
std::unique_ptr< WAxis > removeYAxis(int yAxisId)
void setLegendStyle(const WFont &font, const WPen &border, const WBrush &background)
WDataSeries & series(int modelColumn)
void setLegendColumns(int columns, const WLength &width)
void setOrientation(Orientation orientation)
void setBorderPen(const WPen &pen)
void setSeries(std::vector< std::unique_ptr< WDataSeries > > series)
void setLegendLocation(LegendLocation location, Side side, AlignmentFlag alignment)
MarkerType marker() const
const WShadow & shadow() const
void bindToXAxis(int xAxis)
FillRangeType fillRange() const
void bindToYAxis(int yAxis)
bool isLegendEnabled() const
Wt::Signals::connection connect(F function)
void setCurrentIndex(int index)
void addItem(const WString &text)
void setModel(const std::shared_ptr< WAbstractItemModel > model)
const WString & text() const
void setMaxLength(int length)
virtual void setText(const WString &text)
double toDouble(const WString &value) const
static const WLocale & currentLocale()
void moveTo(const WPointF &point)
void lineTo(const WPointF &point)
WString & arg(const std::wstring &value)
void setStyleClass(const WString &style)
virtual WTableRow * insertRow(int row, std::unique_ptr< WTableRow > tableRow=nullptr)
virtual std::unique_ptr< WTableRow > removeRow(int row)
WTableCell * elementAt(int row, int column)
WTableRow * rowAt(int row)
Struct that holds the controls for one axis.
Wt::WLineEdit * maximumEdit
Wt::WComboBox * tickDirectionEdit
Wt::WLineEdit * titleEdit
Wt::WLineEdit * labelAngleEdit
Wt::WComboBox * titleOrientationEdit
Wt::WCheckBox * gridLinesEdit
Wt::WLineEdit * minimumEdit
Wt::WComboBox * locationEdit
Wt::WComboBox * scaleEdit
Wt::WCheckBox * visibleEdit
Struct that holds the controls for one series.
Wt::WComboBox * markerEdit
Wt::WComboBox * labelsEdit
Wt::WCheckBox * enabledEdit
Wt::WCheckBox * legendEdit
Wt::WCheckBox * shadowEdit
Wt::WComboBox * xAxisEdit
Wt::WComboBox * yAxisEdit