start with stacked time charts
authorMilian Wolff <mail@milianw.de>
Wed, 9 Sep 2015 18:41:56 +0000 (20:41 +0200)
committerMilian Wolff <mail@milianw.de>
Wed, 9 Sep 2015 18:41:56 +0000 (20:41 +0200)
gui/chartmodel.cpp
gui/chartmodel.h
gui/chartproxy.cpp
gui/chartwidget.cpp
gui/mainwindow.cpp
gui/parser.cpp

index 6c12a3a..bc4f348 100644 (file)
 
 #include <QPen>
 #include <QBrush>
+#include <QDebug>
 
 #include "modeltest.h"
 
+namespace {
+QColor colorForColumn(int column, int columnCount)
+{
+    return QColor::fromHsv((1. - double(column + 1) / columnCount) * 255, 255, 255);
+}
+}
+
 ChartModel::ChartModel(QObject* parent)
     : QAbstractTableModel(parent)
 {
@@ -39,11 +47,11 @@ ChartModel::~ChartModel() = default;
 QVariant ChartModel::headerData(int section, Qt::Orientation orientation, int role) const
 {
     Q_ASSERT(orientation != Qt::Horizontal || section < columnCount());
-    if (section == 0 && orientation == Qt::Horizontal) {
-        if ( role == KChart::DatasetPenRole ) {
-            return QPen(Qt::red);
-        } else if ( role == KChart::DatasetBrushRole ) {
-            return QBrush(Qt::red);
+    if (orientation == Qt::Horizontal) {
+        if (role == KChart::DatasetPenRole) {
+            return QVariant::fromValue(QPen(colorForColumn(section, columnCount())));
+        } else if (role == KChart::DatasetBrushRole) {
+            return QVariant::fromValue(QBrush(colorForColumn(section, columnCount())));
         }
     }
     return {};
@@ -68,12 +76,14 @@ QVariant ChartModel::data(const QModelIndex& index, int role) const
 //         }
         return QVariant::fromValue(attributes);
     }
+
+    const auto idx = index.column() / 4;
+    const auto column = index.column() % 4;
+
     if ( role == KChart::DatasetPenRole ) {
-        static const auto pen = QVariant::fromValue(QPen(Qt::red));
-        return pen;
+        return QVariant::fromValue(QPen(colorForColumn(index.column(), columnCount())));
     } else if ( role == KChart::DatasetBrushRole ) {
-        static const auto brush = QVariant::fromValue(QBrush(Qt::red));
-        return brush;
+        return QVariant::fromValue(QBrush(colorForColumn(index.column(), columnCount())));
     }
 
     if ( role != Qt::DisplayRole && role != Qt::ToolTipRole ) {
@@ -81,24 +91,27 @@ QVariant ChartModel::data(const QModelIndex& index, int role) const
     }
 
     if ( role == Qt::ToolTipRole ) {
+        // TODO
         return {};
     }
 
-    const auto& data= m_data.at(index.row());
-    if (index.column() == 0) {
+    const auto& data = m_data.at(index.row());
+    if (column == TimeStampColumn) {
         return data.timeStamp;
-    } else if (index.column() == 1) {
-        return data.leaked;
-    } else if (index.column() == 2) {
-        return data.allocations;
+    }
+
+    if (column == LeakedColumn) {
+        return idx < data.leaked.size() ? data.leaked[idx].cost : 0;
+    } else if (column == AllocationsColumn) {
+        return idx < data.allocations.size() ? data.allocations[idx].cost : 0;
     } else {
-        return data.allocated;
+        return idx < data.allocated.size() ? data.allocated[idx].cost : 0;
     }
 }
 
 int ChartModel::columnCount(const QModelIndex& /*parent*/) const
 {
-    return 4;
+    return m_data.isEmpty() ? 0 : NUM_COLUMNS * m_data.last().allocated.size();
 }
 
 int ChartModel::rowCount(const QModelIndex& parent) const
index c292043..17c678d 100644 (file)
 
 struct ChartRow
 {
+    QString function;
+    quint64 cost;
+};
+Q_DECLARE_TYPEINFO(ChartRow, Q_MOVABLE_TYPE);
+
+struct ChartRows
+{
     quint64 timeStamp;
-    quint64 leaked;
-    quint64 allocations;
-    quint64 allocated;
+    QVector<ChartRow> leaked;
+    QVector<ChartRow> allocations;
+    QVector<ChartRow> allocated;
 };
+Q_DECLARE_TYPEINFO(ChartRows, Q_MOVABLE_TYPE);
 
-Q_DECLARE_TYPEINFO(ChartRow, Q_MOVABLE_TYPE);
-using ChartData = QVector<ChartRow>;
+using ChartData = QVector<ChartRows>;
 Q_DECLARE_METATYPE(ChartData)
 
 class ChartModel : public QAbstractTableModel
@@ -42,6 +49,14 @@ public:
     explicit ChartModel(QObject* parent = nullptr);
     virtual ~ChartModel();
 
+    enum Columns {
+        TimeStampColumn,
+        LeakedColumn,
+        AllocationsColumn,
+        AllocatedColumn,
+        NUM_COLUMNS
+    };
+
     QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
     QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
     int rowCount(const QModelIndex& parent = QModelIndex()) const override;
index e83702f..2f8ce09 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include "chartproxy.h"
+#include "chartmodel.h"
 
 ChartProxy::ChartProxy(const QString& label, int column, QObject* parent)
     : QSortFilterProxyModel(parent)
@@ -38,5 +39,6 @@ QVariant ChartProxy::headerData(int section, Qt::Orientation orientation, int ro
 
 bool ChartProxy::filterAcceptsColumn(int sourceColumn, const QModelIndex& /*sourceParent*/) const
 {
-    return sourceColumn == 0 || sourceColumn == m_column;
+    const auto column = sourceColumn % 4;
+    return column == ChartModel::TimeStampColumn || column == m_column;
 }
index ba87014..d9523c0 100644 (file)
@@ -84,6 +84,7 @@ ChartWidget::ChartWidget(QWidget* parent)
     setLayout(layout);
 
     m_plotter->setAntiAliasing(true);
+    m_plotter->setType(KChart::Plotter::Stacked);
 
     KColorScheme scheme(QPalette::Active, KColorScheme::Window);
     QPen foreground(scheme.foreground().color());
index 92bdff9..0aa556a 100644 (file)
@@ -50,15 +50,15 @@ MainWindow::MainWindow(QWidget* parent)
     m_ui->loadingProgress->setMinimum(0);
     m_ui->loadingProgress->setMaximum(0);
 
-    auto leakedProxy = new ChartProxy(i18n("Memory Leaked"), 1, this);
+    auto leakedProxy = new ChartProxy(i18n("Memory Leaked"), ChartModel::LeakedColumn, this);
     leakedProxy->setSourceModel(m_chartModel);
     m_ui->leakedTab->setModel(leakedProxy);
 
-    auto allocationsProxy = new ChartProxy(i18n("Memory Allocations"), 2, this);
+    auto allocationsProxy = new ChartProxy(i18n("Memory Allocations"), ChartModel::AllocationsColumn, this);
     allocationsProxy->setSourceModel(m_chartModel);
     m_ui->allocationsTab->setModel(allocationsProxy);
 
-    auto allocatedProxy = new ChartProxy(i18n("Memory Allocated"), 3, this);
+    auto allocatedProxy = new ChartProxy(i18n("Memory Allocated"), ChartModel::AllocatedColumn, this);
     allocatedProxy->setSourceModel(m_chartModel);
     m_ui->allocatedTab->setModel(allocatedProxy);
 
index 36993c8..fda1511 100644 (file)
@@ -38,13 +38,41 @@ struct ParserData final : public AccumulatedTraceData
 {
     ParserData()
     {
-        chartData.push_back({0, 0, 0, 0});
+        chartData.push_back({0, {{i18n("total"), 0}}, {{i18n("total"), 0}}, {{i18n("total"), 0}}});
     }
 
     void handleTimeStamp(uint64_t /*newStamp*/, uint64_t oldStamp)
     {
         maxLeakedSinceLastTimeStamp = max(maxLeakedSinceLastTimeStamp, leaked);
-        chartData.push_back({oldStamp, maxLeakedSinceLastTimeStamp, totalAllocations, totalAllocated});
+        ChartRows data;
+        data.timeStamp = oldStamp;
+        data.leaked.push_back({i18n("total"), maxLeakedSinceLastTimeStamp});
+        data.allocations.push_back({i18n("total"), totalAllocations});
+        data.allocated.push_back({i18n("total"), totalAllocated});
+
+        auto allocs = allocations;
+        sort(allocs.begin(), allocs.end(), [] (const Allocation& left, const Allocation& right) {
+            return left.leaked < right.leaked;
+        });
+        for (size_t i = 0; i < min(size_t(10), allocs.size()); ++i) {
+            QString function;
+            data.leaked.push_back({function, allocs[i].leaked});
+        }
+        sort(allocs.begin(), allocs.end(), [] (const Allocation& left, const Allocation& right) {
+            return left.allocations < right.allocations;
+        });
+        for (size_t i = 0; i < min(size_t(10), allocs.size()); ++i) {
+            QString function;
+            data.allocations.push_back({function, allocs[i].allocations});
+        }
+        sort(allocs.begin(), allocs.end(), [] (const Allocation& left, const Allocation& right) {
+            return left.allocated < right.allocated;
+        });
+        for (size_t i = 0; i < min(size_t(10), allocs.size()); ++i) {
+            QString function;
+            data.allocated.push_back({function, allocs[i].allocated});
+        }
+        chartData.push_back(data);
         maxLeakedSinceLastTimeStamp = 0;
     }