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 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 {
|
||||
// Handle negative or invalid values
|
||||
if (bytes < 0 || isNaN(bytes) || !isFinite(bytes)) {
|
||||
@@ -156,10 +171,15 @@ Singleton {
|
||||
Timer {
|
||||
interval: Config.dashboard.resourceUpdateInterval
|
||||
repeat: true
|
||||
running: root.refCount > 0
|
||||
running: true
|
||||
triggeredOnStart: true
|
||||
|
||||
onTriggered: {
|
||||
if (root.refCount <= 0) {
|
||||
root.resetSampling();
|
||||
return;
|
||||
}
|
||||
|
||||
netDevFile.reload();
|
||||
const content = netDevFile.text();
|
||||
if (!content)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import ZShell.Internal
|
||||
import qs.Modules.Resources
|
||||
import qs.Helpers
|
||||
import qs.Components
|
||||
import qs.Config
|
||||
@@ -8,6 +9,8 @@ import qs.Config
|
||||
CustomRect {
|
||||
id: root
|
||||
|
||||
required property Wrapper wrapper
|
||||
|
||||
color: DynamicColors.tPalette.m3surfaceContainer
|
||||
implicitHeight: 220
|
||||
implicitWidth: 300
|
||||
@@ -47,6 +50,7 @@ CustomRect {
|
||||
SparklineItem {
|
||||
id: sparkline
|
||||
|
||||
property bool initialized: false
|
||||
property real smoothMax: targetMax
|
||||
property real targetMax: 1024
|
||||
|
||||
@@ -59,12 +63,23 @@ CustomRect {
|
||||
line2Color: DynamicColors.palette.m3tertiary
|
||||
line2FillAlpha: 0.2
|
||||
maxValue: smoothMax
|
||||
slideProgress: 1
|
||||
|
||||
Behavior on smoothMax {
|
||||
enabled: sparkline.initialized
|
||||
|
||||
Anim {
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
sparkline.targetMax = Math.max(NetworkUsage.downloadBuffer.maximum, NetworkUsage.uploadBuffer.maximum, 1024);
|
||||
|
||||
sparkline.smoothMax = Qt.binding(() => sparkline.targetMax);
|
||||
|
||||
sparkline.initialized = true;
|
||||
}
|
||||
|
||||
Connections {
|
||||
function onValuesChanged(): void {
|
||||
sparkline.targetMax = Math.max(NetworkUsage.downloadBuffer.maximum, NetworkUsage.uploadBuffer.maximum, 1024);
|
||||
|
||||
@@ -9,6 +9,8 @@ import qs.Config
|
||||
Item {
|
||||
id: root
|
||||
|
||||
required property Wrapper wrapper
|
||||
|
||||
implicitHeight: content.implicitHeight + Appearance.padding.normal * 2
|
||||
implicitWidth: content.implicitWidth
|
||||
|
||||
@@ -98,6 +100,7 @@ Item {
|
||||
active: Config.dashboard.performance.showNetwork
|
||||
|
||||
sourceComponent: NetworkCard {
|
||||
wrapper: root.wrapper
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ Item {
|
||||
anchors.centerIn: parent
|
||||
|
||||
sourceComponent: Content {
|
||||
wrapper: root
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "sparklineitem.hpp"
|
||||
|
||||
#include <qmath.h>
|
||||
#include <qpainter.h>
|
||||
#include <qpainterpath.h>
|
||||
#include <qpen.h>
|
||||
@@ -33,19 +34,45 @@ void SparklineItem::drawLine(QPainter* painter, CircularBuffer* buffer, const QC
|
||||
const qreal w = width();
|
||||
const qreal h = height();
|
||||
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 startX = w - (len - 1) * stepX - stepX * m_slideProgress + stepX;
|
||||
|
||||
// Build line path
|
||||
QPainterPath linePath;
|
||||
linePath.moveTo(startX, h - (buffer->at(0) / m_maxValue) * h);
|
||||
for (int i = 1; i < len; ++i) {
|
||||
const qreal strokePad = qCeil(m_lineWidth / 2);
|
||||
const qreal curvePad = 3.0;
|
||||
const qreal topPad = strokePad + curvePad;
|
||||
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 y = h - (buffer->at(i) / m_maxValue) * h;
|
||||
linePath.lineTo(x, y);
|
||||
const qreal value = qBound<qreal>(0.0, buffer->at(i), m_maxValue);
|
||||
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);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
pen.setJoinStyle(Qt::RoundJoin);
|
||||
@@ -53,10 +80,9 @@ void SparklineItem::drawLine(QPainter* painter, CircularBuffer* buffer, const QC
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
painter->drawPath(linePath);
|
||||
|
||||
// Fill under the line
|
||||
QPainterPath fillPath = linePath;
|
||||
fillPath.lineTo(startX + (len - 1) * stepX, h);
|
||||
fillPath.lineTo(startX, h);
|
||||
fillPath.lineTo(startX + (len - 1) * stepX, fillBottom);
|
||||
fillPath.lineTo(startX, fillBottom);
|
||||
fillPath.closeSubpath();
|
||||
|
||||
QColor fillColor = color;
|
||||
|
||||
Reference in New Issue
Block a user