Project

General

Profile

Bug #4080 » test_20150506a_WCartesianChart_axis_titles.C

Bruce Toll, 05/08/2015 02:54 PM

 
#include <Wt/WApplication>
#include <Wt/WBootstrapTheme>
#include <Wt/WCheckBox>
#include <Wt/WComboBox>
#include <Wt/WDialog>
#include <Wt/WLabel>
#include <Wt/WLineEdit>
#include <Wt/WPushButton>
#include <Wt/WStandardItem>
#include <Wt/WStandardItemModel>
#include <Wt/WStringListModel>
#include <Wt/WText>
#include <Wt/WVBoxLayout>
#include <Wt/Chart/WCartesianChart>

using namespace Wt;

class LineEdit : public WLineEdit
{
public:
LineEdit() = default;

LineEdit(const WString &content, const WString &labelText, const WString &styleClass,
const WString &wrapperClass, WContainerWidget *parent) : WLineEdit(content)
{
if (!wrapperClass.empty())
(parent = new WContainerWidget(parent))->setStyleClass(wrapperClass);
if (!labelText.empty())
(new WLabel(labelText, parent))->setBuddy(this);
parent->addWidget(this);
setStyleClass(styleClass);
}
};

class TestApplication : public WApplication
{
public:
TestApplication(const WEnvironment& env);
~TestApplication() { }

private:
void updateChartItems(Chart::WCartesianChart *chart);
WBootstrapTheme theme_;
WStandardItemModel *chartModel_;
LineEdit *titleFontFixed_, *xAxisTitle_, *yAxisTitle_;
LineEdit *p1x_, *p1y_, *p2x_, *p2y_;
WComboBox *titleFontCombo_;
int chartInstance_ = {0};

struct FontString {
WFont::Size value;
std::string text;
};
std::vector<FontString> fontStringVector = {
{WFont::XXSmall, "XXSmall"}, {WFont::XSmall, "XSmall"},
{WFont::Small, "Small"}, {WFont::Medium, "Medium"},
{WFont::Large, "Large"}, {WFont::XLarge, "XLarge"},
{WFont::XXLarge, "XXLarge"}, {WFont::Smaller, "Smaller"},
{WFont::Larger, "Larger"}, {WFont::FixedSize, "FixedSize"}
};
};

void TestApplication::updateChartItems(Chart::WCartesianChart *chart)
{
auto newTitleFontSize = boost::any_cast<WFont::Size>(
titleFontCombo_->model()->data(titleFontCombo_->currentIndex(), 0, UserRole + 1));

for (auto ax: {Chart::XAxis, Chart::YAxis, Chart::Y2Axis}) {
WFont titleFont(chart->axis(ax).titleFont());
if (newTitleFontSize == WFont::FixedSize)
titleFont.setSize(WLength(titleFontFixed_->text().narrow()));
else
titleFont.setSize(newTitleFontSize);
chart->axis(ax).setTitleFont(titleFont);
}
chart->axis(Chart::XAxis).setTitle(xAxisTitle_->text());
chart->axis(Chart::YAxis).setTitle(yAxisTitle_->text());
chart->axis(Chart::Y2Axis).setTitle(yAxisTitle_->text());
chartModel_->setItem(0, 0, new WStandardItem(p1x_->text()));
chartModel_->setItem(0, 1, new WStandardItem(p1y_->text()));
chartModel_->setItem(1, 0, new WStandardItem(p2x_->text()));
chartModel_->setItem(1, 1, new WStandardItem(p2y_->text()));
}

TestApplication::TestApplication(const WEnvironment& env) : WApplication(env)
{
setTitle("WCartesianChart Axis Labels");
theme_.setVersion(WBootstrapTheme::Version3);
setTheme(&theme_);
styleSheet().addRule(".form-control", "margin-bottom: 10px;");

root()->setStyleClass("container-fluid");
root()->setMinimumSize(900, 0);
auto outerWell = new WContainerWidget(root());
outerWell->setStyleClass("col-xs-4 well well-sm");
auto form = new WContainerWidget(new WContainerWidget(outerWell));

auto chartPositionerHolder = new WContainerWidget(root());
chartPositionerHolder->setStyleClass("col-xs-8");
auto chartPositioner = new WContainerWidget(chartPositionerHolder);
chartPositioner->setPositionScheme(Relative);

auto top = new WContainerWidget(form);
top->setStyleClass("col-xs-12");

new WText("<h5>Press 'Create Chart' to add new chart based on checkbox options. "
"Use input fields to update charts. Tick label length can be changed by "
"adjusting end point coordinates. Resize dialogs to view positioning issues. "
"Try labels with narrow and wide glyphs, e.g. 'iii...' and 'WWW...'.</h5>", top);

auto horizontalCheckBox = new WCheckBox("Horiz. Chart", top);
horizontalCheckBox->setStyleClass("checkbox-inline");
auto verticalYCheckBox = new WCheckBox("Vert. Y-Axis Title", top);
verticalYCheckBox->setStyleClass("checkbox-inline");
verticalYCheckBox->setChecked(true);
auto autoLayoutCheckBox = new WCheckBox("Auto Layout", top);
autoLayoutCheckBox->setStyleClass("checkbox-inline");
autoLayoutCheckBox->setChecked(true);

auto openDialogButton = new WPushButton("Create Chart", top);
openDialogButton->setStyleClass("btn-primary btn-block");
openDialogButton->setMargin(20, Bottom);

auto fontStringListModel = new WStringListModel(this);
int row = 0;
for (auto v: fontStringVector) {
fontStringListModel->addString(v.text);
fontStringListModel->setData(row++, 0, v.value, UserRole + 1);
}
auto titleFontComboHolder = new WContainerWidget(form);
titleFontComboHolder->setStyleClass("col-xs-8");
titleFontCombo_ = new WComboBox();
titleFontCombo_->setModel(fontStringListModel);
titleFontCombo_->setCurrentIndex(3);
(new WLabel("Axis Title Font Size", titleFontComboHolder))->setBuddy(titleFontCombo_);
titleFontComboHolder->addWidget(titleFontCombo_);
titleFontFixed_ = new LineEdit("16", "Fixed Size", "", "col-xs-4", form);
titleFontFixed_->setEnabled(false);

xAxisTitle_ = new LineEdit("x-axis", "x-axis label", "", "col-xs-12", form);
yAxisTitle_ = new LineEdit("y-axis", "y-axis label", "", "col-xs-12", form);
p1x_ = new LineEdit("0", "point 1 x", "form-control", "col-xs-6", form);
p1y_ = new LineEdit("0", "point 1 y", "form-control", "col-xs-6", form);
p2x_ = new LineEdit("1000", "point 2 x", "form-control", "col-xs-6", form);
p2y_ = new LineEdit("2000", "point 2 y", "form-control", "col-xs-6", form);

chartModel_ = new WStandardItemModel(2, 2, this);

titleFontCombo_->changed().connect(std::bind([=] {
titleFontFixed_->setEnabled(titleFontCombo_->currentText() == "FixedSize");
}));

openDialogButton->clicked().connect(std::bind([=] {
std::string dialogTitle = horizontalCheckBox->checkState() ? "Horizontal" : "Vertical";
dialogTitle += autoLayoutCheckBox->checkState() ? " Auto Layout" : " Manual Layout";

auto dialog = new WDialog(dialogTitle);
dialog->setModal(false);
dialog->setResizable(true);
dialog->setClosable(true);
dialog->rejectWhenEscapePressed(true);
dialog->setSelectable(false);
dialog->setMinimumSize(300, 300);
dialog->contents()->setLayout(new WVBoxLayout());

Chart::WCartesianChart *chart = new Chart::WCartesianChart(Chart::ScatterPlot);
chart->setOrientation(horizontalCheckBox->checkState() ? Horizontal : Vertical);
if (autoLayoutCheckBox->checkState())
chart->setAutoLayoutEnabled(true);
else {
chart->setPlotAreaPadding(90, Left | Right);
chart->setPlotAreaPadding(70, Top | Bottom);
}
dynamic_cast<WVBoxLayout *>(dialog->contents()->layout())->addWidget(chart, 1);
chart->setTitle("Test Chart " + boost::lexical_cast<std::string>(++chartInstance_));
chart->setModel(chartModel_);
updateChartItems(chart);
chart->setXSeriesColumn(0);
chart->addSeries(Chart::WDataSeries(1, Chart::LineSeries));
chart->addSeries(Chart::WDataSeries(1, Chart::LineSeries)); // for Y2Axis

auto verticalYAxis = verticalYCheckBox->checkState() ? Vertical : Horizontal;
for (auto ax: {Chart::YAxis, Chart::Y2Axis}) {
chart->axis(ax).setLabelFormat("%.0f");
chart->axis(ax).setTitleOrientation(verticalYAxis);
}
chart->axis(Chart::XAxis).setLabelFormat("%.0f");
chart->axis(Chart::Y2Axis).setVisible(true);
chart->series(1).bindToAxis(Chart::Y2Axis);

for (auto edit: {p1x_, p1y_, p2x_, p2y_, xAxisTitle_, yAxisTitle_}) {
edit->textInput().connect(std::bind(&TestApplication::updateChartItems, this, chart));
}
titleFontCombo_->changed().connect(std::bind(&TestApplication::updateChartItems, this, chart));
titleFontFixed_->changed().connect(std::bind(&TestApplication::updateChartItems, this, chart));
dialog->contents()->setSelectable(false);
dialog->setCanReceiveFocus(true);
chartPositioner->resize(0, ((chartInstance_) % 7) * 40);
chartPositioner->setOffsets(((chartInstance_) % 7) * 40, Left);
dialog->positionAt(chartPositioner, Vertical);
dialog->show();
}));
}

int main(int argc, char **argv)
{
return WRun(argc, argv, [](const WEnvironment& env) {return new TestApplication(env);});
}
(1-1/2)