Project

General

Profile

Bug #4875 » test_20160422a_tooltip_cpu.C

Bruce Toll, 04/23/2016 02:50 AM

 
#include <Wt/WApplication>
#include <Wt/WStandardItemModel>
#include <Wt/WText>
#include <Wt/Chart/WCartesianChart>
#include <Wt/Dbo/Dbo>
#include <Wt/Dbo/backend/Sqlite3>
#include <Wt/Dbo/QueryModel>
#include <Wt/WDateTime>
#include <Wt/Dbo/WtSqlTraits>
#include <Wt/WCircleArea>

using namespace Wt;

constexpr int POINT_COUNT = 2000;
constexpr int NUM_DATE_TIMES = 20;

class DataPoint {
public:
int x;
int y;
std::string tooltip;
WDateTime dateTimes[NUM_DATE_TIMES];

template<class Action>
void persist(Action& a)
{
Dbo::field(a, x, "x");
Dbo::field(a, y, "y");
Dbo::field(a, tooltip, "tooltip");
for (int i = 0; i < NUM_DATE_TIMES; ++i) {
Dbo::field(a, dateTimes[i],
std::string("dt") + boost::lexical_cast<std::string>(i));
}
}
};

using DataPointPtr = Dbo::ptr<DataPoint>;

class DataPointQueryModel : public Dbo::QueryModel<DataPointPtr>
{
public:
DataPointQueryModel(WObject *parent = 0) :
Dbo::QueryModel<DataPointPtr>(parent) { }

boost::any data(const WModelIndex& index, int role) const
{
if (role == ToolTipRole && index.column() == 3)
return resultRow(index.row())->tooltip;
/*
* NOTE: The LinkRole is not currently supported for WCartesianCharts....
*/
else if (role == LinkRole && index.column() == 3)
return "https://duckduckgo.com";
else
return Dbo::QueryModel<DataPointPtr>::data(index, role);
}
};

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

private:
Chart::WCartesianChart *chart_ = nullptr;
std::unique_ptr<Dbo::Session> session_;
std::unique_ptr<Dbo::backend::Sqlite3> sqlite3_;
};

TestApplication::TestApplication(const WEnvironment& env) : WApplication(env)
{
sqlite3_.reset(new Dbo::backend::Sqlite3(":memory:"));
session_.reset(new Dbo::Session);
session_->setConnection(*sqlite3_);
session_->mapClass<DataPoint>("data_point");
session_->createTables();

setTitle("WCartesianChart ToolTips CPU Usage Test");

new WText("<h5>Move mouse over chart and observe logged output for cpu time. Worst case is pausing mouse where there is no marker</h5>", root());

/*
* NOTE: An implementation based on map areas (wt 3.3.5) supports custom pointers when over a marker
*/
styleSheet().addRule(".test_chart area[shape=circle]", "cursor: pointer;");

{
Dbo::Transaction transaction(*session_);
for (int i = 0; i < POINT_COUNT; ++i) {
DataPoint *dp = new DataPoint();
dp->x = rand() % 1000;
dp->y = rand() % 1000;
dp->tooltip = std::string("Point number: ") + boost::lexical_cast<std::string>(i + 1);

for (int j = 0; j < NUM_DATE_TIMES; ++j)
dp->dateTimes[j] = WDateTime::currentDateTime();

session_->add(dp);
}
}

{
Dbo::Transaction transaction(*session_);
auto chartModel = new DataPointQueryModel(this);
chartModel->setQuery(session_->find<DataPoint>());
chartModel->addAllFieldsAsColumns();

/*
* NOTE: Enabling a large setBatchSize helps performance significantly
*/
// chartModel->setBatchSize(POINT_COUNT + 1);

chart_ = new Chart::WCartesianChart(Chart::ScatterPlot, root());
chart_->addStyleClass("test_chart");
chart_->resize(1100, 500);
chart_->setAutoLayoutEnabled();
chart_->setZoomEnabled();
chart_->setPanEnabled();
chart_->setModel(chartModel);
chart_->setXSeriesColumn(2);
chart_->addSeries(Chart::WDataSeries(3, Chart::PointSeries));
}
}

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