Using two Models in WCartesianChart
Added by Christian Meyer over 2 years ago
Hi there
Is there any Example about using two Models?
I can't seem to get the second to show...
I found here https://redmine.webtoolkit.eu/boards/2/topics/16703
that it should be possible ...
The Examples are all using a new Column for the Data, but as the primary source for me is a QueryModel, how would I go about that?
And given the Info from the Post linked above, there would be just 2 Rows in the Second Model to create a Line, this Line would be broken up anyway.
Might be special case as I map to DateTime on xAxis...
Idea is to have a bunch of Points with WDateTime field, which works fine with a QueryModel.
Showing a Line in a certain TimeRange with two Points does not happen for me...
here's my code if someone has a chance to look it through?
auto timeQuery = trackPtr->dataPoints.find()
.where("datetime BETWEEN ? AND ?")
.bind(tPtr->getStartTime())
.bind(endTime);
// dataModel is QueryModel
dataModel->setQuery(timeQuery);
dataModel->addColumn("datetime"); // type WDateTime
dataModel->addColumn("value"); // type int
tChart->setModel(dataModel);
tChart->setAutoLayoutEnabled(true);
tChart->setXSeriesColumn(0);
tChart->xAxis(0).setScale(Wt::Chart::AxisScale::DateTime);
auto dataSeries =
std::make_unique<Wt::Chart::WDataSeries>(1, Wt::Chart::SeriesType::Point, 0);
dataSeries->setPen(Wt::WPen(Wt::StandardColor::Red));
tChart->addSeries(std::move(dataSeries));
// The dataSeries shows up Fine and uses dataModel
// Probably overkill, but currently not sure how to create this differently
// or for that matter apparently correctly
auto startItem = std::make_unique<Wt::WStandardItem>();
{
auto startDateItem = std::make_unique<Wt::WStandardItem>();
startDateItem->setData(tPtr->getStartTime());
auto startValueItem = std::make_unique<Wt::WStandardItem>();
startValueItem->setData(tPtr->getTargetValue());
startItem->setChild(0, 0, std::move(startDateItem));
startItem->setChild(0, 1, std::move(startValueItem));
}
auto endItem = std::make_unique<Wt::WStandardItem>();
{
auto endDateItem = std::make_unique<Wt::WStandardItem>();
if(tPtr->getTargetTime().isValid())
endDateItem->setData(tPtr->getTargetTime());
else
endDateItem->setData(Wt::WDateTime::currentDateTime(), Wt::ItemDataRole::User);
auto endValueItem = std::make_unique<Wt::WStandardItem>();
endValueItem->setData(tPtr->getTargetValue());
endItem->setChild(0, 0, std::move(endDateItem));
endItem->setChild(0, 1, std::move(endValueItem));
}
targetModel->appendRow(std::move(startItem));
targetModel->appendRow(std::move(endItem));
Wt::log("targetSeries") << "Items: " << targetModel->rowCount();
// Shows 2 Items, as expected;
auto targetSeries = std::make_unique<Wt::Chart::WDataSeries>(1, Wt::Chart::SeriesType::Point, 1); // or ::Line
targetSeries->setModel(
std::make_shared<Wt::Chart::WStandardChartProxyModel>(targetModel));
targetSeries->setPen(Wt::WPen(Wt::StandardColor::Blue));
targetSeries->setXSeriesColumn(0);
tChart->addSeries(std::move(targetSeries));
// These two Points do not show up! Not even if they are alone in the Chart!
// I would like to Paint a Line with this Series
I have no Idea where to look anymore.
In the examples is nothing that would help me.
Thanks!
Replies (2)
RE: Using two Models in WCartesianChart - Added by Roel Standaert over 2 years ago
Hello Christian,
I think you're not creating your model correctly. WStandardItemModel
can create tree table structures, and that's what you're doing here. Your code creates a model that's structured like this:
startItem
/ (empty)startDateItem
/startValueItem
endItem
/ (empty)endDateItem
/endValueItem
Instead, you want to create a table structure like this:
startDateItem
/startValueItem
endDateItem
/endValueItem
You could do that like this:
{
auto startDateItem = std::make_unique<Wt::WStandardItem>();
startDateItem->setData(tPtr->getStartTime());
auto startValueItem = std::make_unique<Wt::WStandardItem>();
startValueItem->setData(tPtr->getTargetValue());
targetModel->appendRow({std::move(startDateItem), std::move(startValueItem)});
}
{
auto endDateItem = std::make_unique<Wt::WStandardItem>();
if(tPtr->getTargetTime().isValid())
endDateItem->setData(tPtr->getTargetTime());
else
endDateItem->setData(Wt::WDateTime::currentDateTime(), Wt::ItemDataRole::User);
auto endValueItem = std::make_unique<Wt::WStandardItem>();
endValueItem->setData(tPtr->getTargetValue());
targetModel->appendRow({std::move(endDateItem), std::move(endValueItem)});
}
Regards,
Roel
RE: Using two Models in WCartesianChart - Added by Christian Meyer over 2 years ago
Thank you for your fast Reply!
I tried it but could not even compile...
Error: static assertion failed: result type must be constructible from value type of input range
here: targetModel->appendRow({std::move(startDateItem), std::move(startValueItem)});
I tried creating a std::vector
- with Initializer List
- and
push_back
/emplace_back
in the items before doingappendRow
-> same Error so maybe the way to append a row is not the best?
I tried
targetModel->invisibleRootItem()->setChild(0, 0, std::move(startDateItem));
targetModel->invisibleRootItem()->setChild(0, 1, std::move(startValueItem));
This compiled, but still did not show up in the chart...
UNTIL
I tried to show the Model in a WTableView
.
The row and columnCount was correct, but nothing to be seen ...
Then I tried to add Wt::ItemDataRole::Display
to the setData
calls ... and oh wonder ...
Both TableView and Chart had the Data!
THANK YOU SO MUCH!
That did drive me crazy the last few days.
Cheers