forked from qt-creator/qt-creator
AppStatisticMonitor: Use QCharts instead of self made
Change-Id: I4de07dd104dec9e1c68e5daf00a55ab7f8a3f72e Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -1,4 +1,8 @@
|
|||||||
|
find_package(Qt6 COMPONENTS Charts QUIET)
|
||||||
|
|
||||||
add_qtc_plugin(AppStatisticsMonitor
|
add_qtc_plugin(AppStatisticsMonitor
|
||||||
|
CONDITION TARGET Qt6::Charts
|
||||||
|
DEPENDS Qt6::Charts
|
||||||
SKIP_TRANSLATION
|
SKIP_TRANSLATION
|
||||||
PLUGIN_DEPENDS Core ProjectExplorer
|
PLUGIN_DEPENDS Core ProjectExplorer
|
||||||
SOURCES
|
SOURCES
|
||||||
|
@@ -3,6 +3,9 @@ QtcPlugin {
|
|||||||
|
|
||||||
Depends { name: "Core" }
|
Depends { name: "Core" }
|
||||||
Depends { name: "ProjectExplorer" }
|
Depends { name: "ProjectExplorer" }
|
||||||
|
Depends { name: "Qt.charts"; required: false }
|
||||||
|
|
||||||
|
condition: Qt.charts.present
|
||||||
|
|
||||||
files: [
|
files: [
|
||||||
"appstatisticsmonitorplugin.cpp",
|
"appstatisticsmonitorplugin.cpp",
|
||||||
|
@@ -5,11 +5,19 @@
|
|||||||
|
|
||||||
#include <utils/theme/theme.h>
|
#include <utils/theme/theme.h>
|
||||||
|
|
||||||
|
#include <QAbstractAxis>
|
||||||
|
#include <QChartView>
|
||||||
|
#include <QDebug>
|
||||||
#include <QPaintEvent>
|
#include <QPaintEvent>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPen>
|
#include <QPen>
|
||||||
#include <QPointF>
|
#include <QPointF>
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
#include <QSplineSeries>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QValueAxis>
|
||||||
|
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace AppStatisticsMonitor::Internal {
|
namespace AppStatisticsMonitor::Internal {
|
||||||
|
|
||||||
@@ -17,6 +25,100 @@ static const int padding = 40;
|
|||||||
static const int numPadding = 10;
|
static const int numPadding = 10;
|
||||||
static const QRectF dataRangeDefault = QRectF(0, 0, 5, 1);
|
static const QRectF dataRangeDefault = QRectF(0, 0, 5, 1);
|
||||||
|
|
||||||
|
AppStatisticsMonitorChart::AppStatisticsMonitorChart(
|
||||||
|
const QString &name, QGraphicsItem *parent, Qt::WindowFlags wFlags)
|
||||||
|
: QChart(QChart::ChartTypeCartesian, parent, wFlags)
|
||||||
|
, m_series(new QLineSeries(this))
|
||||||
|
, m_axisX(new QValueAxis())
|
||||||
|
, m_axisY(new QValueAxis())
|
||||||
|
, m_point(0, 0)
|
||||||
|
, m_chartView(new QChartView(this))
|
||||||
|
, m_name(name)
|
||||||
|
{
|
||||||
|
m_chartView->setMinimumHeight(200);
|
||||||
|
m_chartView->setMinimumWidth(400);
|
||||||
|
const QBrush brushTitle(creatorColor(Theme::Token_Text_Muted));
|
||||||
|
const QBrush brush(creatorColor(Theme::Token_Background_Default));
|
||||||
|
const QPen penBack(creatorColor(Theme::Token_Text_Muted));
|
||||||
|
const QPen penAxis(creatorColor(Theme::Token_Text_Muted));
|
||||||
|
|
||||||
|
setTitleBrush(brushTitle);
|
||||||
|
setBackgroundBrush(brush);
|
||||||
|
setBackgroundPen(penBack);
|
||||||
|
m_axisX->setLinePen(penAxis);
|
||||||
|
m_axisY->setLinePen(penAxis);
|
||||||
|
m_axisX->setLabelsColor(creatorColor(Theme::Token_Text_Muted));
|
||||||
|
m_axisY->setLabelsColor(creatorColor(Theme::Token_Text_Muted));
|
||||||
|
QPen pen(creatorColor(Theme::Token_Accent_Default));
|
||||||
|
pen.setWidth(2);
|
||||||
|
m_series->setPen(pen);
|
||||||
|
|
||||||
|
setTitle(m_name + " " + QString::number(m_point.y(), 'g', 4) + "%");
|
||||||
|
m_chartView->setRenderHint(QPainter::Antialiasing);
|
||||||
|
m_chartView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||||
|
addSeries(m_series);
|
||||||
|
|
||||||
|
addAxis(m_axisX, Qt::AlignBottom);
|
||||||
|
addAxis(m_axisY, Qt::AlignLeft);
|
||||||
|
m_series->attachAxis(m_axisX);
|
||||||
|
m_series->attachAxis(m_axisY);
|
||||||
|
m_axisX->applyNiceNumbers();
|
||||||
|
m_axisY->applyNiceNumbers();
|
||||||
|
legend()->hide();
|
||||||
|
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
QChartView *AppStatisticsMonitorChart::chartView()
|
||||||
|
{
|
||||||
|
return m_chartView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppStatisticsMonitorChart::addNewPoint(const QPointF &point)
|
||||||
|
{
|
||||||
|
m_point = point;
|
||||||
|
if (m_axisY->max() < m_point.y())
|
||||||
|
m_axisY->setRange(0, qRound(m_point.y()) + 1);
|
||||||
|
m_axisX->setRange(0, qRound(m_point.x()) + 1);
|
||||||
|
|
||||||
|
setTitle(m_name + " " + QString::number(m_point.y(), 'g', 4) + "%");
|
||||||
|
m_series->append(m_point);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppStatisticsMonitorChart::loadNewProcessData(const QList<double> &data)
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
QList<QPointF> points{{0, 0}};
|
||||||
|
int i = 0;
|
||||||
|
double max_y = 0;
|
||||||
|
|
||||||
|
for (double e : qAsConst(data)) {
|
||||||
|
points.push_back({double(++i), e});
|
||||||
|
max_y = qMax(max_y, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_axisY->setRange(0, qRound(max_y) + 1);
|
||||||
|
m_axisX->setRange(0, data.size() + 1);
|
||||||
|
|
||||||
|
m_series->clear();
|
||||||
|
m_series->append(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppStatisticsMonitorChart::clear()
|
||||||
|
{
|
||||||
|
m_axisX->setRange(0, 5);
|
||||||
|
m_axisY->setRange(0, 1);
|
||||||
|
m_series->clear();
|
||||||
|
m_series->append(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double AppStatisticsMonitorChart::lastPointX() const
|
||||||
|
{
|
||||||
|
return m_point.x();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------- Chart -----------------------
|
||||||
|
|
||||||
Chart::Chart(const QString &name, QWidget *parent)
|
Chart::Chart(const QString &name, QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, m_name(name)
|
, m_name(name)
|
||||||
@@ -31,7 +133,7 @@ void Chart::addNewPoint(const QPointF &point)
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chart::loadNewProcessData(QList<double> data)
|
void Chart::loadNewProcessData(const QList<double> &data)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
for (long i = 0; i < data.size(); ++i) {
|
for (long i = 0; i < data.size(); ++i) {
|
||||||
@@ -59,7 +161,7 @@ void Chart::paintEvent(QPaintEvent *event)
|
|||||||
Q_UNUSED(event);
|
Q_UNUSED(event);
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
|
|
||||||
painter.fillRect(rect(), Utils::creatorColor(Utils::Theme::Token_Background_Default));
|
painter.fillRect(rect(), creatorColor(Theme::Token_Background_Default));
|
||||||
|
|
||||||
// add the name of the chart in the middle of the widget width and on the top
|
// add the name of the chart in the middle of the widget width and on the top
|
||||||
painter.drawText(
|
painter.drawText(
|
||||||
@@ -74,10 +176,10 @@ void Chart::paintEvent(QPaintEvent *event)
|
|||||||
double xPos = padding + (x - dataRange.left()) * m_xScale;
|
double xPos = padding + (x - dataRange.left()) * m_xScale;
|
||||||
if (xPos < padding || xPos > width() - padding)
|
if (xPos < padding || xPos > width() - padding)
|
||||||
continue;
|
continue;
|
||||||
painter.setPen(Utils::creatorColor(Utils::Theme::Token_Foreground_Default));
|
painter.setPen(creatorColor(Theme::Token_Foreground_Default));
|
||||||
painter.drawLine(xPos, padding, xPos, height() - padding);
|
painter.drawLine(xPos, padding, xPos, height() - padding);
|
||||||
|
|
||||||
painter.setPen(Utils::creatorColor(Utils::Theme::Token_Text_Muted));
|
painter.setPen(creatorColor(Theme::Token_Text_Muted));
|
||||||
painter.drawText(xPos, height() - numPadding, QString::number(x));
|
painter.drawText(xPos, height() - numPadding, QString::number(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,18 +188,18 @@ void Chart::paintEvent(QPaintEvent *event)
|
|||||||
if (yPos < padding || yPos > height() - padding)
|
if (yPos < padding || yPos > height() - padding)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
painter.setPen(Utils::creatorColor(Utils::Theme::Token_Foreground_Default));
|
painter.setPen(creatorColor(Theme::Token_Foreground_Default));
|
||||||
painter.drawLine(padding, yPos, width() - padding, yPos);
|
painter.drawLine(padding, yPos, width() - padding, yPos);
|
||||||
|
|
||||||
painter.setPen(Utils::creatorColor(Utils::Theme::Token_Text_Muted));
|
painter.setPen(creatorColor(Theme::Token_Text_Muted));
|
||||||
painter.drawText(numPadding, yPos, QString::number(y));
|
painter.drawText(numPadding, yPos, QString::number(y));
|
||||||
}
|
}
|
||||||
|
|
||||||
painter.setPen(Utils::creatorColor(Utils::Theme::Token_Foreground_Default));
|
painter.setPen(creatorColor(Theme::Token_Foreground_Default));
|
||||||
painter.drawLine(padding, height() - padding, width() - padding, height() - padding); // X axis
|
painter.drawLine(padding, height() - padding, width() - padding, height() - padding); // X axis
|
||||||
painter.drawLine(padding, height() - padding, padding, padding); // Y axis
|
painter.drawLine(padding, height() - padding, padding, padding); // Y axis
|
||||||
|
|
||||||
QPen pen(Utils::creatorColor(Utils::Theme::Token_Accent_Default));
|
QPen pen(creatorColor(Theme::Token_Accent_Default));
|
||||||
pen.setWidth(2);
|
pen.setWidth(2);
|
||||||
painter.setPen(pen);
|
painter.setPen(pen);
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
@@ -2,21 +2,51 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QChart>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QPaintEvent>
|
#include <QPaintEvent>
|
||||||
#include <QPointF>
|
#include <QPointF>
|
||||||
#include <QRectF>
|
#include <QRectF>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QChartView;
|
||||||
|
class QLineSeries;
|
||||||
|
class QValueAxis;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace AppStatisticsMonitor::Internal {
|
namespace AppStatisticsMonitor::Internal {
|
||||||
|
|
||||||
|
class AppStatisticsMonitorChart : public QChart
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AppStatisticsMonitorChart(
|
||||||
|
const QString &name, QGraphicsItem *parent = nullptr, Qt::WindowFlags wFlags = {});
|
||||||
|
|
||||||
|
void addNewPoint(const QPointF &point);
|
||||||
|
void loadNewProcessData(const QList<double> &data);
|
||||||
|
double lastPointX() const;
|
||||||
|
void clear();
|
||||||
|
QChartView *chartView();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLineSeries *m_series;
|
||||||
|
QStringList m_titles;
|
||||||
|
QValueAxis *m_axisX;
|
||||||
|
QValueAxis *m_axisY;
|
||||||
|
QPointF m_point;
|
||||||
|
|
||||||
|
QChartView *m_chartView;
|
||||||
|
QString m_name;
|
||||||
|
};
|
||||||
|
|
||||||
class Chart : public QWidget
|
class Chart : public QWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Chart(const QString &name, QWidget *parent = nullptr);
|
Chart(const QString &name, QWidget *parent = nullptr);
|
||||||
|
|
||||||
void addNewPoint(const QPointF &point);
|
void addNewPoint(const QPointF &point);
|
||||||
void loadNewProcessData(QList<double> data);
|
void loadNewProcessData(const QList<double> &data);
|
||||||
double lastPointX() const;
|
double lastPointX() const;
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#include <projectexplorer/projectexplorer.h>
|
#include <projectexplorer/projectexplorer.h>
|
||||||
#include <projectexplorer/runcontrol.h>
|
#include <projectexplorer/runcontrol.h>
|
||||||
|
|
||||||
|
#include <QChartView>
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QGraphicsItem>
|
#include <QGraphicsItem>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
@@ -24,15 +25,15 @@ class AppStatisticsMonitorView : public QWidget
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit AppStatisticsMonitorView(
|
explicit AppStatisticsMonitorView(
|
||||||
AppStatisticsMonitorManager *appStatisticManager, QWidget *parent = nullptr);
|
AppStatisticsMonitorManager *appStatisticManager);
|
||||||
|
|
||||||
~AppStatisticsMonitorView() override;
|
~AppStatisticsMonitorView() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QComboBox *m_comboBox;
|
QComboBox *m_comboBox;
|
||||||
|
|
||||||
Chart *m_memChart;
|
std::unique_ptr<AppStatisticsMonitorChart> m_chartMem;
|
||||||
Chart *m_cpuChart;
|
std::unique_ptr<AppStatisticsMonitorChart> m_chartCpu;
|
||||||
|
|
||||||
AppStatisticsMonitorManager *m_manager;
|
AppStatisticsMonitorManager *m_manager;
|
||||||
};
|
};
|
||||||
@@ -114,25 +115,21 @@ QHash<qint64, QString> AppStatisticsMonitorManager::pidNameMap() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AppStatisticsMonitorView
|
// AppStatisticsMonitorView
|
||||||
AppStatisticsMonitorView::AppStatisticsMonitorView(AppStatisticsMonitorManager *dapManager, QWidget *)
|
AppStatisticsMonitorView::AppStatisticsMonitorView(AppStatisticsMonitorManager *appManager)
|
||||||
: m_manager(dapManager)
|
: m_manager(appManager)
|
||||||
{
|
{
|
||||||
auto layout = new QVBoxLayout;
|
auto layout = new QVBoxLayout;
|
||||||
auto form = new QFormLayout;
|
auto form = new QFormLayout;
|
||||||
setLayout(layout);
|
setLayout(layout);
|
||||||
|
|
||||||
m_comboBox = new QComboBox();
|
m_comboBox = new QComboBox(this);
|
||||||
form->addRow(m_comboBox);
|
form->addRow(m_comboBox);
|
||||||
|
|
||||||
m_memChart = new Chart("Memory consumption ");
|
m_chartMem = std::make_unique<AppStatisticsMonitorChart>(tr("Memory consumption"));
|
||||||
m_memChart->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
m_chartCpu = std::make_unique<AppStatisticsMonitorChart>(tr("CPU consumption"));
|
||||||
m_memChart->clear();
|
|
||||||
form->addRow(m_memChart);
|
|
||||||
|
|
||||||
m_cpuChart = new Chart("CPU consumption ");
|
form->addRow(m_chartMem->chartView());
|
||||||
m_cpuChart->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
form->addRow(m_chartCpu->chartView());
|
||||||
m_cpuChart->clear();
|
|
||||||
form->addRow(m_cpuChart);
|
|
||||||
|
|
||||||
layout->addLayout(form);
|
layout->addLayout(form);
|
||||||
|
|
||||||
@@ -142,16 +139,19 @@ AppStatisticsMonitorView::AppStatisticsMonitorView(AppStatisticsMonitorManager *
|
|||||||
}
|
}
|
||||||
m_comboBox->setCurrentIndex(m_comboBox->count() - 1);
|
m_comboBox->setCurrentIndex(m_comboBox->count() - 1);
|
||||||
|
|
||||||
m_memChart->clear();
|
m_chartCpu->clear();
|
||||||
m_cpuChart->clear();
|
m_chartMem->clear();
|
||||||
|
|
||||||
auto updateCharts = [this](int index) {
|
auto updateCharts = [this](int index) {
|
||||||
m_manager->setCurrentDataProvider(m_comboBox->itemData(index).toLongLong());
|
m_manager->setCurrentDataProvider(m_comboBox->itemData(index).toLongLong());
|
||||||
if (m_manager->currentDataProvider() != nullptr) {
|
if (m_manager->currentDataProvider() != nullptr) {
|
||||||
m_memChart->loadNewProcessData(
|
const QList<double> &memConsumptionHistory
|
||||||
m_manager->currentDataProvider()->memoryConsumptionHistory());
|
= m_manager->currentDataProvider()->memoryConsumptionHistory();
|
||||||
m_cpuChart->loadNewProcessData(
|
const QList<double> &cpuConsumptionHistory
|
||||||
m_manager->currentDataProvider()->cpuConsumptionHistory());
|
= m_manager->currentDataProvider()->cpuConsumptionHistory();
|
||||||
|
|
||||||
|
m_chartMem->loadNewProcessData(memConsumptionHistory);
|
||||||
|
m_chartCpu->loadNewProcessData(cpuConsumptionHistory);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -170,16 +170,17 @@ AppStatisticsMonitorView::AppStatisticsMonitorView(AppStatisticsMonitorManager *
|
|||||||
if (pid != m_comboBox->currentData()) {
|
if (pid != m_comboBox->currentData()) {
|
||||||
m_comboBox->addItem(name + " : " + QString::number(pid), pid);
|
m_comboBox->addItem(name + " : " + QString::number(pid), pid);
|
||||||
|
|
||||||
m_memChart->clear();
|
m_chartMem->clear();
|
||||||
m_cpuChart->clear();
|
m_chartCpu->clear();
|
||||||
|
|
||||||
m_comboBox->setCurrentIndex(m_comboBox->count() - 1);
|
m_comboBox->setCurrentIndex(m_comboBox->count() - 1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(m_manager, &AppStatisticsMonitorManager::appStoped, this, [this](qint64 pid) {
|
connect(m_manager, &AppStatisticsMonitorManager::appStoped, this, [this](qint64 pid) {
|
||||||
m_memChart->addNewPoint({m_memChart->lastPointX() + 1, 0});
|
m_chartMem->addNewPoint({m_chartMem->lastPointX() + 1, 0});
|
||||||
m_cpuChart->addNewPoint({m_cpuChart->lastPointX() + 1, 0});
|
m_chartCpu->addNewPoint({m_chartCpu->lastPointX() + 1, 0});
|
||||||
|
|
||||||
const int indx = m_comboBox->findData(pid);
|
const int indx = m_comboBox->findData(pid);
|
||||||
if (indx != -1)
|
if (indx != -1)
|
||||||
m_comboBox->removeItem(indx);
|
m_comboBox->removeItem(indx);
|
||||||
@@ -188,10 +189,10 @@ AppStatisticsMonitorView::AppStatisticsMonitorView(AppStatisticsMonitorManager *
|
|||||||
connect(m_manager, &AppStatisticsMonitorManager::newDataAvailable, this, [this] {
|
connect(m_manager, &AppStatisticsMonitorManager::newDataAvailable, this, [this] {
|
||||||
const IDataProvider *currentDataProvider = m_manager->currentDataProvider();
|
const IDataProvider *currentDataProvider = m_manager->currentDataProvider();
|
||||||
if (currentDataProvider != nullptr) {
|
if (currentDataProvider != nullptr) {
|
||||||
m_memChart->addNewPoint(
|
m_chartMem->addNewPoint(
|
||||||
{(double) currentDataProvider->memoryConsumptionHistory().size(),
|
{(double) currentDataProvider->memoryConsumptionHistory().size(),
|
||||||
currentDataProvider->memoryConsumptionLast()});
|
currentDataProvider->memoryConsumptionLast()});
|
||||||
m_cpuChart->addNewPoint(
|
m_chartCpu->addNewPoint(
|
||||||
{(double) currentDataProvider->cpuConsumptionHistory().size(),
|
{(double) currentDataProvider->cpuConsumptionHistory().size(),
|
||||||
currentDataProvider->cpuConsumptionLast()});
|
currentDataProvider->cpuConsumptionLast()});
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user