import QtQuick
import QtQuick.Layouts
import org.kde.kirigami as Kirigami
import "../Grafana.js" as G
// Stat: one tile per series with its reduced value, coloured by
// thresholds the way colorMode asks (the text, the tile, or neither),
// over a faint sparkline when graphMode is "area".
Item {
id: stat
property var frame: null
readonly property var panel: frame ? frame.panel : ({})
readonly property var options: panel.options || {}
readonly property string calc: ((options.reduceOptions && options.reduceOptions.calcs) || ["lastNotNull"])[0] || "lastNotNull"
readonly property string colorMode: options.colorMode || "value"
readonly property string textMode: options.textMode || "auto"
readonly property bool sparkline: (options.graphMode || "area") === "area"
readonly property bool horizontal: options.orientation === "horizontal" || (options.orientation !== "vertical" && width > height * 2.5)
readonly property var tiles: {
var out = []
var list = frame ? frame.series : []
var tc = Kirigami.Theme.textColor.toString()
for (var i = 0; i < list.length && i < 24; i++) {
var s = list[i]
var cfg = G.fieldConfig(panel, s)
var v = G.reduce(s.values, calc)
var color = G.seriesColor(cfg, i, v, { min: cfg.min, max: cfg.max }, tc)
out.push({ name: G.displayName(s, cfg), parts: G.formatParts(v, cfg.unit, cfg.decimals),
color: color, values: s.values, times: s.times })
}
return out
}
readonly property int cols: tiles.length <= 1 ? 1 : horizontal ? 1 : Math.ceil(Math.sqrt(tiles.length * width / Math.max(1, height)))
GridLayout {
anchors.fill: parent
columns: Math.max(1, Math.min(stat.cols, stat.tiles.length))
rowSpacing: 2
columnSpacing: 2
Repeater {
model: stat.tiles
delegate: Rectangle {
id: tile
required property var modelData
readonly property bool bg: stat.colorMode === "background" || stat.colorMode === "background_solid"
readonly property color fg: bg ? "white"
: stat.colorMode === "none" ? Kirigami.Theme.textColor
: (modelData.color === "transparent" ? Kirigami.Theme.textColor : modelData.color)
readonly property bool showName: stat.textMode === "name" || stat.textMode === "value_and_name"
|| (stat.textMode === "auto" && stat.tiles.length > 1)
readonly property bool showValue: stat.textMode !== "name" && stat.textMode !== "none"
Layout.fillWidth: true
Layout.fillHeight: true
radius: Kirigami.Units.cornerRadius
color: bg ? modelData.color : "transparent"
gradient: bg && stat.colorMode === "background" ? grad : null
Gradient {
id: grad
GradientStop { position: 0; color: Qt.lighter(tile.modelData.color, 1.15) }
GradientStop { position: 1; color: Qt.darker(tile.modelData.color, 1.15) }
}
Canvas {
id: spark
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: parent.height * 0.45
visible: stat.sparkline && tile.modelData.values.length > 1
onWidthChanged: requestPaint()
onHeightChanged: requestPaint()
Connections {
target: tile
function onModelDataChanged() { spark.requestPaint() }
}
onPaint: {
var ctx = getContext("2d")
ctx.reset()
var vals = tile.modelData.values, times = tile.modelData.times
var lo = Infinity, hi = -Infinity
for (var i = 0; i < vals.length; i++) {
if (vals[i] === null) continue
lo = Math.min(lo, vals[i]); hi = Math.max(hi, vals[i])
}
if (!isFinite(lo) || times.length < 2) return
if (hi === lo) { hi += 1; lo -= 1 }
var t0 = times[0], t1 = times[times.length - 1]
var c = tile.bg ? "#ffffff" : (tile.modelData.color === "transparent" || tile.modelData.color === Kirigami.Theme.textColor.toString()
? Kirigami.Theme.highlightColor.toString() : tile.modelData.color)
ctx.beginPath()
var started = false
for (var j = 0; j < vals.length; j++) {
if (vals[j] === null) continue
var x = (times[j] - t0) / (t1 - t0) * width
var y = height - (vals[j] - lo) / (hi - lo) * height * 0.9
if (!started) { ctx.moveTo(x, height); ctx.lineTo(x, y); started = true }
else ctx.lineTo(x, y)
}
ctx.lineTo(width, height)
ctx.closePath()
ctx.fillStyle = G.withAlpha(c.charAt(0) === "#" ? c : "#888888", 0.18)
ctx.fill()
}
}
ColumnLayout {
anchors.fill: parent
anchors.margins: 2
spacing: 0
Text {
visible: tile.showName
Layout.fillWidth: true
Layout.preferredHeight: parent.height * (tile.showValue ? 0.3 : 1)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
fontSizeMode: Text.Fit
font.pixelSize: 64
minimumPixelSize: 7
elide: Text.ElideRight
color: tile.bg ? "white" : Kirigami.Theme.textColor
opacity: 0.8
text: tile.modelData.name
textFormat: Text.PlainText
}
Text {
visible: tile.showValue
Layout.fillWidth: true
Layout.fillHeight: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
fontSizeMode: Text.Fit
font.pixelSize: 200
minimumPixelSize: 8
font.weight: Font.DemiBold
color: tile.modelData.parts.empty ? Kirigami.Theme.disabledTextColor : tile.fg
textFormat: Text.PlainText
text: tile.modelData.parts.empty ? tile.modelData.parts.text
: tile.modelData.parts.prefix + tile.modelData.parts.text + tile.modelData.parts.suffix
}
}
}
}
}
}
neiam
/grafana-plasmoid
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
7.3 KiB · text
History
35c3541