// Pomodoros per day: magnitude over time, so bars, one hue, baseline at zero. // The goal line is the only reference mark; days that cleared it take a darker // step of the same ramp, which keeps "did I hit it" readable without a second // colour. import QtQuick import QtQuick.Controls import QtQuick.Layouts import ".." Item { id: chart property var days: [] property int goal: 8 property int barHeight: 108 Layout.fillWidth: true implicitHeight: barHeight + 16 readonly property int maxValue: { var top = goal for (var i = 0; i < days.length; i++) top = Math.max(top, days[i].pomodoros) return Math.max(top, 1) } Rectangle { anchors.left: parent.left anchors.right: parent.right y: chart.barHeight - (chart.goal / chart.maxValue) * chart.barHeight height: 1 color: Theme.rule visible: chart.goal > 0 } RowLayout { anchors.left: parent.left anchors.right: parent.right height: chart.barHeight spacing: 2 Repeater { model: chart.days delegate: Item { required property var modelData Layout.fillWidth: true Layout.fillHeight: true Rectangle { anchors.bottom: parent.bottom width: parent.width height: Math.max(modelData.pomodoros > 0 ? (modelData.pomodoros / chart.maxValue) * chart.barHeight : 2, 2) radius: 3 color: modelData.pomodoros === 0 ? Theme.rule : (modelData.goal_met ? Theme.sequential[4] : Theme.sequential[2]) ToolTip.visible: hover.hovered ToolTip.text: modelData.date + " · " + modelData.pomodoros + " pomodoros · " + modelData.focus_minutes + " min" HoverHandler { id: hover } Behavior on height { NumberAnimation { duration: 220 } } } } } } RowLayout { anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right Label { text: chart.days.length ? chart.days[0].date.substring(5) : "" font.pixelSize: 10; color: Theme.faint; font.family: Theme.sansFamily } Item { Layout.fillWidth: true } Label { text: chart.days.length ? chart.days[chart.days.length - 1].date.substring(5) : "" font.pixelSize: 10; color: Theme.faint; font.family: Theme.sansFamily } } }