rounded sparkline graph, fixed network usage accumulation spikes
This commit is contained in:
@@ -39,6 +39,21 @@ Singleton {
|
|||||||
readonly property real uploadSpeed: _uploadSpeed
|
readonly property real uploadSpeed: _uploadSpeed
|
||||||
readonly property real uploadTotal: _uploadTotal
|
readonly property real uploadTotal: _uploadTotal
|
||||||
|
|
||||||
|
function resetSampling(): void {
|
||||||
|
netDevFile.reload();
|
||||||
|
|
||||||
|
const content = netDevFile.text();
|
||||||
|
if (!content)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const data = root.parseNetDev(content);
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
root._prevRxBytes = data.rx;
|
||||||
|
root._prevTxBytes = data.tx;
|
||||||
|
root._prevTimestamp = now;
|
||||||
|
}
|
||||||
|
|
||||||
function formatBytes(bytes: real): var {
|
function formatBytes(bytes: real): var {
|
||||||
// Handle negative or invalid values
|
// Handle negative or invalid values
|
||||||
if (bytes < 0 || isNaN(bytes) || !isFinite(bytes)) {
|
if (bytes < 0 || isNaN(bytes) || !isFinite(bytes)) {
|
||||||
@@ -156,10 +171,15 @@ Singleton {
|
|||||||
Timer {
|
Timer {
|
||||||
interval: Config.dashboard.resourceUpdateInterval
|
interval: Config.dashboard.resourceUpdateInterval
|
||||||
repeat: true
|
repeat: true
|
||||||
running: root.refCount > 0
|
running: true
|
||||||
triggeredOnStart: true
|
triggeredOnStart: true
|
||||||
|
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
|
if (root.refCount <= 0) {
|
||||||
|
root.resetSampling();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
netDevFile.reload();
|
netDevFile.reload();
|
||||||
const content = netDevFile.text();
|
const content = netDevFile.text();
|
||||||
if (!content)
|
if (!content)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
import ZShell.Internal
|
import ZShell.Internal
|
||||||
|
import qs.Modules.Resources
|
||||||
import qs.Helpers
|
import qs.Helpers
|
||||||
import qs.Components
|
import qs.Components
|
||||||
import qs.Config
|
import qs.Config
|
||||||
@@ -8,6 +9,8 @@ import qs.Config
|
|||||||
CustomRect {
|
CustomRect {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
required property Wrapper wrapper
|
||||||
|
|
||||||
color: DynamicColors.tPalette.m3surfaceContainer
|
color: DynamicColors.tPalette.m3surfaceContainer
|
||||||
implicitHeight: 220
|
implicitHeight: 220
|
||||||
implicitWidth: 300
|
implicitWidth: 300
|
||||||
@@ -47,6 +50,7 @@ CustomRect {
|
|||||||
SparklineItem {
|
SparklineItem {
|
||||||
id: sparkline
|
id: sparkline
|
||||||
|
|
||||||
|
property bool initialized: false
|
||||||
property real smoothMax: targetMax
|
property real smoothMax: targetMax
|
||||||
property real targetMax: 1024
|
property real targetMax: 1024
|
||||||
|
|
||||||
@@ -59,12 +63,23 @@ CustomRect {
|
|||||||
line2Color: DynamicColors.palette.m3tertiary
|
line2Color: DynamicColors.palette.m3tertiary
|
||||||
line2FillAlpha: 0.2
|
line2FillAlpha: 0.2
|
||||||
maxValue: smoothMax
|
maxValue: smoothMax
|
||||||
|
slideProgress: 1
|
||||||
|
|
||||||
Behavior on smoothMax {
|
Behavior on smoothMax {
|
||||||
|
enabled: sparkline.initialized
|
||||||
|
|
||||||
Anim {
|
Anim {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
sparkline.targetMax = Math.max(NetworkUsage.downloadBuffer.maximum, NetworkUsage.uploadBuffer.maximum, 1024);
|
||||||
|
|
||||||
|
sparkline.smoothMax = Qt.binding(() => sparkline.targetMax);
|
||||||
|
|
||||||
|
sparkline.initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onValuesChanged(): void {
|
function onValuesChanged(): void {
|
||||||
sparkline.targetMax = Math.max(NetworkUsage.downloadBuffer.maximum, NetworkUsage.uploadBuffer.maximum, 1024);
|
sparkline.targetMax = Math.max(NetworkUsage.downloadBuffer.maximum, NetworkUsage.uploadBuffer.maximum, 1024);
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import qs.Config
|
|||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
required property Wrapper wrapper
|
||||||
|
|
||||||
implicitHeight: content.implicitHeight + Appearance.padding.normal * 2
|
implicitHeight: content.implicitHeight + Appearance.padding.normal * 2
|
||||||
implicitWidth: content.implicitWidth
|
implicitWidth: content.implicitWidth
|
||||||
|
|
||||||
@@ -98,6 +100,7 @@ Item {
|
|||||||
active: Config.dashboard.performance.showNetwork
|
active: Config.dashboard.performance.showNetwork
|
||||||
|
|
||||||
sourceComponent: NetworkCard {
|
sourceComponent: NetworkCard {
|
||||||
|
wrapper: root.wrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ Item {
|
|||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
sourceComponent: Content {
|
sourceComponent: Content {
|
||||||
|
wrapper: root
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "sparklineitem.hpp"
|
#include "sparklineitem.hpp"
|
||||||
|
|
||||||
|
#include <qmath.h>
|
||||||
#include <qpainter.h>
|
#include <qpainter.h>
|
||||||
#include <qpainterpath.h>
|
#include <qpainterpath.h>
|
||||||
#include <qpen.h>
|
#include <qpen.h>
|
||||||
@@ -33,19 +34,45 @@ void SparklineItem::drawLine(QPainter* painter, CircularBuffer* buffer, const QC
|
|||||||
const qreal w = width();
|
const qreal w = width();
|
||||||
const qreal h = height();
|
const qreal h = height();
|
||||||
const int len = buffer->count();
|
const int len = buffer->count();
|
||||||
|
if (len < 2 || m_maxValue <= 0.0)
|
||||||
|
return;
|
||||||
|
|
||||||
const qreal stepX = w / static_cast<qreal>(m_historyLength - 1);
|
const qreal stepX = w / static_cast<qreal>(m_historyLength - 1);
|
||||||
const qreal startX = w - (len - 1) * stepX - stepX * m_slideProgress + stepX;
|
const qreal startX = w - (len - 1) * stepX - stepX * m_slideProgress + stepX;
|
||||||
|
|
||||||
// Build line path
|
const qreal strokePad = qCeil(m_lineWidth / 2);
|
||||||
QPainterPath linePath;
|
const qreal curvePad = 3.0;
|
||||||
linePath.moveTo(startX, h - (buffer->at(0) / m_maxValue) * h);
|
const qreal topPad = strokePad + curvePad;
|
||||||
for (int i = 1; i < len; ++i) {
|
const qreal bottomPad = strokePad;
|
||||||
|
const qreal plotTop = topPad;
|
||||||
|
const qreal plotBottom = h - bottomPad;
|
||||||
|
const qreal fillBottom = h;
|
||||||
|
const qreal plotH = qMax<qreal>(1.0, plotBottom - plotTop);
|
||||||
|
|
||||||
|
QVector<QPointF> points;
|
||||||
|
points.reserve(len);
|
||||||
|
|
||||||
|
for (int i = 0; i < len; ++i) {
|
||||||
const qreal x = startX + i * stepX;
|
const qreal x = startX + i * stepX;
|
||||||
const qreal y = h - (buffer->at(i) / m_maxValue) * h;
|
const qreal value = qBound<qreal>(0.0, buffer->at(i), m_maxValue);
|
||||||
linePath.lineTo(x, y);
|
const qreal y = plotTop + (1.0 - (value / m_maxValue)) * plotH;
|
||||||
|
points.append(QPointF(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
QPainterPath linePath;
|
||||||
|
linePath.moveTo(points[0]);
|
||||||
|
|
||||||
|
for (int i = 0; i < points.size() - 1; ++i) {
|
||||||
|
const QPointF& p0 = points[i];
|
||||||
|
const QPointF& p1 = points[i + 1];
|
||||||
|
|
||||||
|
const qreal ctrlX = (p0.x() + p1.x()) * 0.5;
|
||||||
|
const QPointF c1(ctrlX, p0.y());
|
||||||
|
const QPointF c2(ctrlX, p1.y());
|
||||||
|
|
||||||
|
linePath.cubicTo(c1, c2, p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stroke the line
|
|
||||||
QPen pen(color, m_lineWidth);
|
QPen pen(color, m_lineWidth);
|
||||||
pen.setCapStyle(Qt::RoundCap);
|
pen.setCapStyle(Qt::RoundCap);
|
||||||
pen.setJoinStyle(Qt::RoundJoin);
|
pen.setJoinStyle(Qt::RoundJoin);
|
||||||
@@ -53,10 +80,9 @@ void SparklineItem::drawLine(QPainter* painter, CircularBuffer* buffer, const QC
|
|||||||
painter->setBrush(Qt::NoBrush);
|
painter->setBrush(Qt::NoBrush);
|
||||||
painter->drawPath(linePath);
|
painter->drawPath(linePath);
|
||||||
|
|
||||||
// Fill under the line
|
|
||||||
QPainterPath fillPath = linePath;
|
QPainterPath fillPath = linePath;
|
||||||
fillPath.lineTo(startX + (len - 1) * stepX, h);
|
fillPath.lineTo(startX + (len - 1) * stepX, fillBottom);
|
||||||
fillPath.lineTo(startX, h);
|
fillPath.lineTo(startX, fillBottom);
|
||||||
fillPath.closeSubpath();
|
fillPath.closeSubpath();
|
||||||
|
|
||||||
QColor fillColor = color;
|
QColor fillColor = color;
|
||||||
|
|||||||
Reference in New Issue
Block a user