Passed
Push — master ( b7e2ed...a132c8 )
by Victor
01:54
created

index.php (2 issues)

1
<?php
2
require_once 'vendor/autoload.php';
3
4
use Vctls\IntervalGraph\IntervalGraph;
5
6
/**
7
 * Generate random dates.
8
 * @param int $min
9
 * @param int $max
10
 * @return DateTime
11
 */
12
function rdm($min = 1514764800, $max = 1577750400)
13
{
14
    return (new DateTime)->setTimestamp(mt_rand($min, $max));
15
}
16
17
$today = new DateTime('today');
18
19
$base = [$today, new DateTime('today + 5 days')];
20
$date1 = [$today, new DateTime('today + 4 days'), 7 / 10];
21
$date2 = [new DateTime('today + 1 day'), new DateTime('today + 5 days'), 3 / 10];
22
$date3 = [new DateTime('today + 2 day'), new DateTime('today + 3 days'), 3 / 10];
23
$overlapped1 = new IntervalGraph([$base, $date1]);
24
$overlapped2 = new IntervalGraph([$base, $date2]);
25
$overlapped3 = new IntervalGraph([$base, $date3]);
26
$overlapped = new IntervalGraph([$base, $date1, $date2, $date3]);
27
28
$withNull1 = new IntervalGraph([$base, [new DateTime('today'), new DateTime('today + 3 days'), 4 / 10],]);
29
$withNull2 = new IntervalGraph([$base, [new DateTime('today + 1 day'), new DateTime('today + 2 days')],]);
30
$withNull3 = new IntervalGraph([$base, [new DateTime('today + 2 day'), new DateTime('today + 3 days'), 4 / 10],]);
31
$withNull4 = new IntervalGraph([$base, [new DateTime('today + 4 day'), new DateTime('today + 5 days'), 5 / 10],]);
32
$withNullIntervals = new IntervalGraph([
33
    [$today, new DateTime('today + 3 days'), 4 / 10],
34
    [new DateTime('today + 1 day'), new DateTime('today + 2 days')],
35
    [new DateTime('today + 2 day'), new DateTime('today + 3 days'), 4 / 10],
36
    [new DateTime('today + 4 day'), new DateTime('today + 5 days'), 5 / 10],
37
]);
38
39
$longIntervals = [
40
    [$today, new DateTime('today + 3 days'), 2 / 10],
41
    [new DateTime('today + 1 day'), new DateTime('today + 4 days'), 2 / 10],
42
    [new DateTime('today + 2 day'), new DateTime('today + 5 days'), 3 / 10],
43
    [new DateTime('today + 3 day'), new DateTime('today + 6 days'), 5 / 10],
44
    [new DateTime('today + 4 day'), new DateTime('today + 7 days'), 4 / 10],
45
    [new DateTime('today + 5 day'), new DateTime('today + 8 days'), 2 / 10],
46
    [new DateTime('today + 6 day'), new DateTime('today + 9 days'), 2 / 10],
47
];
48
49
$longDateFormat = function (\DateTime $bound){
50
    return $bound->format('Y-m-d H:i:s');
51
};
52
53
$long = (new IntervalGraph($longIntervals))->setBoundToStringFunction($longDateFormat);
54
55
/*
56
 * CUSTOM VALUE TYPES
57
 */
58
59
// An aggregate function for arrays representing fractions with the same denominator.
60
$agg = function ($a, $b) {
61
    if ($a === null && $b === null) return null;
62
    return [$a[0] + $b[0], $b[1]];
63
};
64
65
// A toNumeric function…
66
$toNumeric = function ($a) {return $a === null ? null : (int)($a[0] / $a[1] * 100);};
67
68
// A toString function…
69
$toString = function ($a) {return $a === null ? null : ($a[0] . '/' . $a[1]);};
70
71
$fractions = [
72
    [$today, new DateTime('today + 3 days'), [2, 10]],
73
    [new DateTime('today + 1 day'), new DateTime('today + 4 days'), [2, 10]],
74
    [new DateTime('today + 2 day'), new DateTime('today + 5 days'), [3, 10]],
75
    [new DateTime('today + 3 day'), new DateTime('today + 6 days'), [5, 10]],
76
    [new DateTime('today + 4 day'), new DateTime('today + 7 days'), [4, 10]],
77
    [new DateTime('today + 5 day'), new DateTime('today + 8 days'), [2, 10]],
78
    [new DateTime('today + 6 day'), new DateTime('today + 9 days'), [2, 10]],
79
];
80
$fractim = (new IntervalGraph($fractions))->setAggregateFunction($agg)
81
    ->setValueToNumericFunction($toNumeric)
82
    ->setValueToStringFunction($toString);
83
$fract = $fractim->draw();
84
85
/* /CUSTOM VALUE TYPES */
86
87
/*
88
 * TRUNCATED INTERVALS
89
 */
90
try {
91
    $date1 = (clone $today)->add(new DateInterval('PT60H'));
92
    $date2 = (clone $today)->add(new DateInterval('PT108H'));
93
    $date3 = (clone $date2)->add(new DateInterval('PT60H'));
94
} catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
95
}
96
97
$truncated = ($fractim->setIntervals(IntervalGraph::truncate($fractions, $date1, $date2)))
0 ignored issues
show
It seems like $date2 can also be of type array<integer,integer|DateTime>; however, parameter $end of Vctls\IntervalGraph\IntervalGraph::truncate() does only seem to accept null|DateTime, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

97
$truncated = ($fractim->setIntervals(IntervalGraph::truncate($fractions, $date1, /** @scrutinizer ignore-type */ $date2)))
Loading history...
98
    ->setBoundToStringFunction($longDateFormat);
99
/* /TRUNCATED INTERVALS */
100
101
$withDates = new IntervalGraph([
102
    [$date1, $date1],
103
    [$today, new DateTime('today + 4 days'), 7 / 10],
104
    [$date2, $date2],
105
    [new DateTime('today + 1 day'), new DateTime('today + 5 days'), 3 / 10],
106
    [new DateTime('today + 2 day'), new DateTime('today + 3 days'), 3 / 10],
107
    [$date3, $date3],
108
]);
109
110
$intvGraphs = [];
111
foreach (range(0, 20) as $t) {
112
    $intervals = [];
113
    $j = (int)rand(3, 6);
114
    for ($i = 0; $i < $j; $i++) {
115
        $intervals[] = [rdm(), rdm(), rand(1, 9) / 10];
116
    }
117
    $intvGraphs[] = new IntervalGraph($intervals);
118
}
119
120
?>
121
<html>
122
<head>
123
    <title>Php IntervalGraph demo</title>
124
    <link rel="stylesheet" href="styles.css">
125
    <script type="application/javascript" src="app.js"></script>
126
</head>
127
<body style="font-family: sans-serif;">
128
<header>
129
    <h1>PHP Interval Graph demo</h1>
130
</header>
131
<p>
132
    PHP Interval Graph is a small utility to manipulate and
133
    display arrays of intervals.
134
</p>
135
<a href="https://github.com/vctls/php-interval-graph">
136
    https://github.com/vctls/php-interval-graph
137
</a>
138
<h2>How it works</h2>
139
<p>
140
    Here are three overlapping date intervals.
141
    Each one has a linked rate, displayed as a percentage when hovering it.
142
    <br>They are all displayed over the same period of time, which has no rate.
143
</p>
144
<div style="margin-bottom: 2px"><?= $overlapped1 ?></div>
145
<div style="margin-bottom: 2px"><?= $overlapped2 ?></div>
146
<div style="margin-bottom: 2px"><?= $overlapped3 ?></div>
147
148
<p>
149
    Gathered on the same graph, they are displayed as follows.
150
</p>
151
<?= $overlapped ?>
152
153
<h2>More examples</h2>
154
<p>
155
    Overlapping intervals with a couple null intervals.<br>
156
    The first null interval overlaps a non null one.
157
    This cuts the non null interval, while the weight remains the same.<br>
158
    The second null interval is implicit.
159
    It is simply the gap between the two last intervals.
160
</p>
161
<div style="margin-bottom: 2px"><?= $withNull1 ?></div>
162
<div style="margin-bottom: 2px"><?= $withNull2 ?></div>
163
<div style="margin-bottom: 2px"><?= $withNull3 ?></div>
164
<div style="margin-bottom: 2px"><?= $withNull4 ?></div>
165
<br>
166
<?= $withNullIntervals ?>
167
168
169
<h2>Custom value types</h2>
170
<p>
171
    The following graph takes arrays of two values
172
    and displays them as fractions.<br>
173
    In order to use custom value types, you need to set the custom functions
174
    that will aggregate the values, convert them to numeric values and strings.
175
</p>
176
<?= $fract ?>
177
178
<p>
179
    The same graph, truncated between <?= $date1->format('Y-m-d H:i:s') ?>
180
    and <?= $date2->format('Y-m-d H:i:s') ?>.
181
    <?= $truncated ?>
182
</p>
183
184
<p>
185
    A graph with three isolated dates, shown as black bars.
186
    <br>One of the dates goes beyond all intervals.
187
    <?= $withDates ?>
188
</p>
189
<p>
190
    A bunch of random graphs, this time generated through JavaScript:
191
    <br>
192
</p>
193
<div id="random"></div>
194
<script>
195
    'use strict';
196
    const graphs = JSON.parse('<?= json_encode($intvGraphs) ?>');
197
    const el = document.getElementById('random');
198
199
    try {
200
        graphs.forEach(function (graph) {
201
            let html = document.createRange().createContextualFragment(intvg(graph));
202
            el.appendChild(html);
203
        });
204
    } catch (e) {
205
        el.innerHTML = 'The JavaScript function uses ES6 string literals. Sorry not sorry, IE.';
206
    }
207
</script>
208
</body>
209
</html>