histogram (QWT) improved (correct x-scale labels, total data shown, etc); refactoring
authorAlexey Chernobaev <achernobaev@dev.rtsoft.ru>
Thu, 15 Mar 2018 00:56:27 +0000 (03:56 +0300)
committerAlexey Chernobaev <achernobaev@dev.rtsoft.ru>
Thu, 15 Mar 2018 00:56:27 +0000 (03:56 +0300)
src/analyze/gui/chartwidget.cpp
src/analyze/gui/chartwidgetqwtplot.cpp
src/analyze/gui/histogramwidgetqwtplot.cpp
src/analyze/gui/histogramwidgetqwtplot.h

index 3d41b9f44e63c08765b4127ffa3a9305cce6e887..34877be4551a8a7cfd6578d2b0bff45cec7bc660 100644 (file)
@@ -196,15 +196,15 @@ void ChartWidget::setModel(ChartModel* model, bool minimalMode)
         setToolTip(i18n("<qt>Shows the number of instances allocated from specific functions over time.</qt>"));
         break;
     case ChartModel::Allocated:
-        setToolTip(i18n("<qt>Displays total memory allocated over time. "
+        setToolTip(i18n("<qt>Displays the total memory allocated over time. "
                         "This value ignores deallocations and just measures heap "
                         "allocation throughput.</qt>"));
         break;
     case ChartModel::Allocations:
-        setToolTip(i18n("<qt>Shows number of memory allocations over time.</qt>"));
+        setToolTip(i18n("<qt>Shows the number of memory allocations over time.</qt>"));
         break;
     case ChartModel::Temporary:
-        setToolTip(i18n("<qt>Shows number of temporary memory allocations over time. "
+        setToolTip(i18n("<qt>Shows the number of temporary memory allocations over time. "
                         "A temporary allocation is one that is followed immediately by its "
                         "corresponding deallocation, without other allocations happening "
                         "in-between.</qt>"));
index ba9c41a3021f311f4c1b0a0de16fe374d99d0db1..badf0c71bb84a2505a885b2acdbf3d4e90486f2c 100644 (file)
@@ -200,11 +200,12 @@ void ChartWidgetQwtPlot::rebuild(bool resetZoomAndPan)
         return;
     }
 
-    int columns = m_model->columnCount();
-    int rows = m_model->rowCount();
-
     insertLegend(hasOption(ShowLegend) ? new QwtLegend() : nullptr);
 
+    auto grid = new QwtPlotGrid();
+    grid->setPen(QPen(Qt::lightGray));
+    grid->attach(this);
+
     setAxisTitle(QwtPlot::xBottom, m_model->headerData(0).toString());
     setAxisTitle(QwtPlot::yRight, m_model->headerData(1).toString());
     setAxisScaleDraw(QwtPlot::xBottom, new TimeScaleDraw());
@@ -213,14 +214,12 @@ void ChartWidgetQwtPlot::rebuild(bool resetZoomAndPan)
         setAxisScaleDraw(QwtPlot::yRight, new SizeScaleDraw());
     }
 
-    auto grid = new QwtPlotGrid();
-    grid->attach(this);
-
     int column = 1;
     if (!hasOption(ShowTotal))
     {
         column += 2;
     }
+    int columns = m_model->columnCount();
     for (; column < columns; column += 2)
     {
         auto adapter = new ChartModel2QwtSeriesData(m_model, column);
@@ -252,6 +251,7 @@ void ChartWidgetQwtPlot::rebuild(bool resetZoomAndPan)
 
     if (hasOption(ShowVLines))
     {
+        int rows = m_model->rowCount();
         for (int row = 1; row < rows; ++row)
         {
             auto marker = new QwtPlotMarker();
index 8d61a2209e7cdfc4006c259f1cec120ddd5c2963..917b8145990160628f333216c04d60be4af10ccb 100644 (file)
@@ -3,11 +3,31 @@
 #include "noklib.h"
 
 #include <qwt_column_symbol.h>
+#include <qwt_plot_grid.h>
 #include <qwt_plot_multi_barchart.h>
+#include <qwt_scale_draw.h>
+
+class HistogramScaleDraw: public QwtScaleDraw
+{
+public:
+    HistogramScaleDraw(QVector<QString>& rowNames) : m_rowNames(rowNames) { }
+
+    virtual QwtText label(double value) const
+    {
+        qint64 index = (qint64)value;
+        if ((index >= 0) && (index < m_rowNames.size()))
+        {
+            return m_rowNames[index];
+        }
+        return QwtScaleDraw::label(value);
+    }
+
+private:
+    QVector<QString> m_rowNames;
+};
 
 HistogramWidgetQwtPlot::HistogramWidgetQwtPlot(QWidget *parent)
-    : QwtPlot(parent),
-      m_barChart(nullptr)
+    : QwtPlot(parent), m_model(nullptr)
 {
     setCanvasBackground(Qt::white);
     enableAxis(QwtPlot::yRight);
@@ -19,25 +39,42 @@ HistogramWidgetQwtPlot::HistogramWidgetQwtPlot(QWidget *parent)
 void HistogramWidgetQwtPlot::rebuild(bool resetZoomAndPan)
 {
     detachItems();
-    m_barChart = nullptr;
 
     if (!m_model)
     {
         return;
     }
 
-    m_barChart = new QwtPlotMultiBarChart();
-    m_barChart->setSpacing(40); // TODO!! use dynamic spacing
-    m_barChart->setStyle(QwtPlotMultiBarChart::Stacked);
+    auto grid = new QwtPlotGrid();
+    grid->setPen(QPen(Qt::lightGray));
+    grid->attach(this);
 
-    int columns = m_model->columnCount();
-    int rows = m_model->rowCount();
+    setAxisAutoScale(QwtPlot::yRight);
 
-    int maxColumn = 0;
+    auto totalBarChart = new QwtPlotMultiBarChart();
+    totalBarChart->setStyle(QwtPlotMultiBarChart::Stacked);
+    totalBarChart->setLayoutHint(0.33);
+    totalBarChart->setLayoutPolicy(QwtPlotMultiBarChart::ScaleSamplesToAxes);
+
+    auto barChart = new QwtPlotMultiBarChart();
+    barChart->setStyle(QwtPlotMultiBarChart::Stacked);
+    barChart->setLayoutHint(totalBarChart->layoutHint());
+    barChart->setLayoutPolicy(QwtPlotMultiBarChart::ScaleSamplesToAxes);
+
+    QVector<QString> rowNames;
+    QVector<QVector<double>> totalSeries;
     QVector<QVector<double>> series;
+    int rows = m_model->rowCount();
+    int columns = m_model->columnCount();
+    int maxColumn = 0;
     for (int row = 0; row < rows; ++row)
     {
-        QString rowName = m_model->headerData(row, Qt::Vertical).toString();
+        rowNames.append(m_model->headerData(row, Qt::Vertical).toString());
+
+        QVector<double> totalValues;
+        totalValues.append(m_model->data(m_model->index(row, 0)).toDouble());
+        totalSeries.append(totalValues);
+
         QVector<double> values;
         for (int column = 1; column < columns; ++column)
         {
@@ -55,18 +92,32 @@ void HistogramWidgetQwtPlot::rebuild(bool resetZoomAndPan)
         series.append(values);
     }
 
-    for (int column = 1; column <= maxColumn; ++column)
+    for (int column = 0; column <= maxColumn; ++column)
     {
         auto symbol = new QwtColumnSymbol(QwtColumnSymbol::Box);
         symbol->setLineWidth(2);
         symbol->setPalette(QPalette(m_model->getColumnColor(column)));
-        m_barChart->setSymbol(column - 1, symbol);
+        if (column > 0)
+        {
+            barChart->setSymbol(column - 1, symbol);
+        }
+        else
+        {
+            totalBarChart->setSymbol(0, symbol);
+        }
     }
 
-    m_barChart->setSamples(series);
+    totalBarChart->setSamples(totalSeries);
+    barChart->setSamples(series);
 
-    setAxisAutoScale(QwtPlot::yRight);
-    m_barChart->setAxes(QwtPlot::xBottom, QwtPlot::yRight);
+    auto bottomScale = new HistogramScaleDraw(rowNames);
+    bottomScale->enableComponent(QwtScaleDraw::Backbone, false);
+    bottomScale->enableComponent(QwtScaleDraw::Ticks, false);
+    setAxisScaleDraw(QwtPlot::xBottom, bottomScale);
+
+    totalBarChart->setAxes(QwtPlot::xBottom, QwtPlot::yRight);
+    barChart->setAxes(QwtPlot::xBottom, QwtPlot::yRight);
 
-    m_barChart->attach(this);
+    totalBarChart->attach(this);
+    barChart->attach(this);
 }
index 86934a3bfb87c16c8aa468847c6f7c497825b6d0..8d24250d0c89ff5087aabc3698f47440249a3986 100644 (file)
@@ -4,7 +4,6 @@
 #include <qwt_plot.h>
 
 class HistogramModel;
-class QwtPlotMultiBarChart;
 
 class HistogramWidgetQwtPlot : public QwtPlot
 {
@@ -16,8 +15,6 @@ public:
     void rebuild(bool resetZoomAndPan);
 
 private:
-    QwtPlotMultiBarChart *m_barChart;
-
     HistogramModel *m_model;
 };