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