Commit 92134bac authored by Volker Krause's avatar Volker Krause
Browse files

Implement categorization based on array/map sizes

parent eb8315cb
......@@ -44,8 +44,18 @@ private slots:
{
CategoryAggregationModel model;
ModelTest modelTest(&model);
model.setAggregationValue(QString());
model.setAggregationValue(QLatin1String("applicationVersion.value"));
model.setAggregation(AggregationElement());
AggregationElement aggr;
{
SchemaEntry entry;
entry.setName(QLatin1String("applicationVersion"));
aggr.setSchemaEntry(entry);
SchemaEntryElement elem;
elem.setName(QLatin1String("value"));
aggr.setSchemaEntryElement(elem);
aggr.setType(AggregationElement::Value);
}
model.setAggregation(aggr);
TimeAggregationModel timeModel;
model.setSourceModel(&timeModel);
......@@ -69,7 +79,17 @@ private slots:
{
CategoryAggregationModel model;
ModelTest modelTest(&model);
model.setAggregationValue(QLatin1String("applicationVersion.value"));
AggregationElement aggr;
{
SchemaEntry entry;
entry.setName(QLatin1String("applicationVersion"));
aggr.setSchemaEntry(entry);
SchemaEntryElement elem;
elem.setName(QLatin1String("value"));
aggr.setSchemaEntryElement(elem);
aggr.setType(AggregationElement::Value);
}
model.setAggregation(aggr);
TimeAggregationModel timeModel;
model.setSourceModel(&timeModel);
......
......@@ -60,7 +60,7 @@ QAbstractItemModel* CategoryAggregator::timeAggregationModel()
m_model.reset(new CategoryAggregationModel);
m_model->setSourceModel(sourceModel());
const auto e = aggregation().elements().at(0);
m_model->setAggregationValue(e.schemaEntry().name() + QLatin1Char('.') + e.schemaEntryElement().name());
m_model->setAggregation(e);
QObject::connect(m_model.get(), &QAbstractItemModel::modelReset, [this]() {
updateSingularChart();
updateTimelineChart();
......
......@@ -35,6 +35,11 @@ static const struct {
AggregationElement::AggregationElement() = default;
AggregationElement::~AggregationElement() = default;
bool AggregationElement::isValid() const
{
return !m_entry.name().isEmpty();
}
SchemaEntry AggregationElement::schemaEntry() const
{
return m_entry;
......
......@@ -44,6 +44,8 @@ public:
Type type() const;
void setType(Type t);
bool isValid() const;
SchemaEntry schemaEntry() const;
void setSchemaEntry(const SchemaEntry &entry);
......
......@@ -45,9 +45,9 @@ void CategoryAggregationModel::setSourceModel(QAbstractItemModel* model)
recompute();
}
void CategoryAggregationModel::setAggregationValue(const QString &aggrValue)
void CategoryAggregationModel::setAggregation(const AggregationElement& aggr)
{
m_aggrValue = aggrValue;
m_aggr = aggr;
recompute();
}
......@@ -119,7 +119,7 @@ void CategoryAggregationModel::recompute()
m_data = nullptr;
m_maxValue = 0;
if (rowCount <= 0 || m_aggrValue.isEmpty()) {
if (rowCount <= 0 || !m_aggr.isValid()) {
endResetModel();
return;
}
......@@ -129,7 +129,7 @@ void CategoryAggregationModel::recompute()
QSet<QString> categories;
const auto allSamples = m_sourceModel->index(0, 0).data(TimeAggregationModel::AllSamplesRole).value<QVector<Sample>>();
foreach (const auto &s, allSamples)
categories.insert(s.value(m_aggrValue).toString());
categories.insert(sampleValue(s).toString());
m_categories.reserve(categories.size());
foreach (const auto &cat, categories)
m_categories.push_back(cat);
......@@ -142,7 +142,7 @@ void CategoryAggregationModel::recompute()
for (int row = 0; row < rowCount; ++row) {
const auto samples = m_sourceModel->index(row, 0).data(TimeAggregationModel::SamplesRole).value<QVector<Sample>>();
foreach (const auto &sample, samples) {
const auto catIt = std::lower_bound(m_categories.constBegin(), m_categories.constEnd(), sample.value(m_aggrValue).toString());
const auto catIt = std::lower_bound(m_categories.constBegin(), m_categories.constEnd(), sampleValue(sample).toString());
Q_ASSERT(catIt != m_categories.constEnd());
const auto idx = colCount * row + std::distance(m_categories.constBegin(), catIt);
m_data[idx]++;
......@@ -155,7 +155,18 @@ void CategoryAggregationModel::recompute()
m_maxValue = std::max(m_maxValue, m_data[row * colCount + colCount - 1]);
}
endResetModel();
}
QVariant CategoryAggregationModel::sampleValue(const Sample& s) const
{
switch (m_aggr.type()) {
case AggregationElement::Value:
return s.value(m_aggr.schemaEntry().name() + QLatin1String(".") + m_aggr.schemaEntryElement().name());
case AggregationElement::Size:
const auto l = s.value(m_aggr.schemaEntry().name());
return l.value<QVariantList>().size();
break;
}
return {};
}
......@@ -18,12 +18,16 @@
#ifndef USERFEEDBACK_CONSOLE_CATEGORYAGGREGATIONMODEL_H
#define USERFEEDBACK_CONSOLE_CATEGORYAGGREGATIONMODEL_H
#include <core/aggregationelement.h>
#include <QAbstractTableModel>
#include <QVector>
namespace UserFeedback {
namespace Console {
class Sample;
/** Aggregate by time and one string category value (e.g. version. platform, etc). */
class CategoryAggregationModel : public QAbstractTableModel
{
......@@ -33,7 +37,7 @@ public:
~CategoryAggregationModel();
void setSourceModel(QAbstractItemModel *model);
void setAggregationValue(const QString &aggrValue);
void setAggregation(const AggregationElement &aggr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
......@@ -42,9 +46,10 @@ public:
private:
void recompute();
QVariant sampleValue(const Sample &s) const;
QAbstractItemModel *m_sourceModel = nullptr;
QString m_aggrValue;
AggregationElement m_aggr;
QVector<QString> m_categories;
int *m_data = nullptr;
int m_maxValue;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment