aboutsummaryrefslogtreecommitdiff
path: root/src/graphs/TimeLabels.qml
blob: bebeca5a8b65df08a26c48d017d1fa7f9151e930 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/*
 * Copyright (C) 2023 Arseniy Movshev <dodoradio@outlook.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

import QtQuick 2.15
import org.asteroid.controls 1.0

Item {
    id: root
    property real startTime: 0
    property real endTime: 0
    property int minLabels: 3 //these min and max numbers of labels are only guidelines for the algorithm, and don't actually set hard limits.
    property int maxLabels: 8
    property int startValueDivision
    onStartTimeChanged: update()
    onEndTimeChanged: update()
    onMinLabelsChanged: update()
    onMaxLabelsChanged: update()
    Component.onCompleted: update()
    function update() {
        listModel.clear()
        var delta = endTime - startTime
        var interval = 0
        if (delta < 60 * maxLabels) { // check 1 minute
            if (delta < 60 * minLabels) {
                interval = 30 //label every 30s otherwise
            } else {
                interval = 60
            }
            startValueDivision = interval * Math.ceil(startTime / interval)
            // iterate and populate the list
            var currentTime = startValueDivision
            var i = 0;
            var date
            while (currentTime < endTime) {
                date = new Date(currentTime*1000)
                var value = date.getHours().toString() + ":" + date.getMinutes().toString()
                var x  = (currentTime - startTime) / delta
                listModel.append({"value": value, "x": x})
                currentTime = currentTime + interval
                i++
            }

        } else if (delta < 600 * maxLabels) { // check 10 minutes
            if (delta < 600 * minLabels) {
                interval = 300 //label every 5m otherwise
            } else {
                interval = 600
            }
            startValueDivision = interval * Math.ceil(startTime / interval)
            // iterate and populate the list
            var currentTime = startValueDivision
            var i = 0;
            var date
            while (currentTime < endTime) {
                date = new Date(currentTime*1000)
                var value = date.getHours().toString() + ":" + date.getMinutes().toString()
                var x  = (currentTime - startTime) / delta
                listModel.append({"value": value, "x": x})
                currentTime = currentTime + interval
                i++
            }

        } else if (delta < 7200 * maxLabels) { // check every 2 hours
            if (delta > 3600 * maxLabels) {
                interval = 7200 //label every 2h if 1h doesn't work - this is an ugly workaround so that a full day still gets some sort of divisions
            } else if (delta < 3600 * minLabels) {
                interval = 1800 //label every 30m otherwise
            } else {
                interval = 3600
            }
            startValueDivision = interval * Math.ceil(startTime / interval)
            // iterate and populate the list
            var currentTime = startValueDivision
            var i = 0;
            var date
            while (currentTime < endTime) {
                date = new Date(currentTime*1000)
                var value = date.getHours().toString() + ":" + date.getMinutes().toString()
                var x  = (currentTime - startTime) / delta
                listModel.append({"value": value, "x": x})
                currentTime = currentTime + interval
                i++
            }

        } else if (delta < 86400 * maxLabels) { // check days
            if (delta < 86400 * minLabels) {
                interval = 43200 //label every 12h otherwise
            } else {
                interval = 86400
            }
            startValueDivision = interval * Math.ceil(startTime / interval)
            // iterate and populate the list
            var currentTime = startValueDivision
            var i = 0;
            var date
            while (currentTime < endTime) {
                date = new Date(currentTime*1000)
                var value = date.getDate().toString() /* we should add am and pm here for 12h mode*/
                var x = ((currentTime - startTime) / delta)
                listModel.append({"value": value, "x": x})
                currentTime = currentTime + interval
                i++
            }

        } else if (delta < 604800 * maxLabels) { // check weeks
            interval = 604800
            startValueDivision = interval * Math.ceil(startTime / interval)
            // iterate and populate the list
            var currentTime = startValueDivision
            var i = 0;
            var date
            while (currentTime < endTime) {
                date = new Date(currentTime*1000)
                var value = date.getDate().toString()
                var x = ((currentTime - startTime) / delta)
                listModel.append({"value": value, "x": x})
                currentTime = currentTime + interval
                i++
            }
        } else { // handle months
            console.log("viewing more than several days of data isn't implemented yet. please pester dodoradio about this.")
        }
        // this is slightly crude - we assume that the min and max label numbers will be set in such a way that halving gets us a reasonable interval.
        // we also ignore everything over a number of weeks, as this needs a bit more thought that I don't want to deal with right now. this graph code is stalling too much other development.
    }
    Repeater {
        model: ListModel { id: listModel }
        delegate: Label {
            text: model.value
            font.pixelSize: Dims.w(5)
            x: model.x*root.width - width/2
            verticalAlignment: Text.AlignVCenter
        }
    }
}