Completed
Push — develop ( 25e717...7d6742 )
by John
02:19
created

GraphNode::getModifier()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Alpha\Util\Graph;
4
5
use Alpha\Exception\IllegalArguementException;
6
7
/**
8
 * Maintains the geometry for a tree node.
9
 *
10
 * @since 1.0
11
 *
12
 * @author John Collins <[email protected]>
13
 * @license http://www.opensource.org/licenses/bsd-license.php The BSD License
14
 * @copyright Copyright (c) 2019, John Collins (founder of Alpha Framework).
15
 * All rights reserved.
16
 *
17
 * <pre>
18
 * Redistribution and use in source and binary forms, with or
19
 * without modification, are permitted provided that the
20
 * following conditions are met:
21
 *
22
 * * Redistributions of source code must retain the above
23
 *   copyright notice, this list of conditions and the
24
 *   following disclaimer.
25
 * * Redistributions in binary form must reproduce the above
26
 *   copyright notice, this list of conditions and the
27
 *   following disclaimer in the documentation and/or other
28
 *   materials provided with the distribution.
29
 * * Neither the name of the Alpha Framework nor the names
30
 *   of its contributors may be used to endorse or promote
31
 *   products derived from this software without specific
32
 *   prior written permission.
33
 *
34
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
35
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
36
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
37
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
39
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
45
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
 * </pre>
48
 */
49
class GraphNode
50
{
51
    /**
52
     * The id of the node.
53
     *
54
     * @var int
55
     *
56
     * @since 1.0
57
     */
58
    private $id = 0;
59
60
    /**
61
     * The height of the node.
62
     *
63
     * @var int
64
     *
65
     * @since 1.0
66
     */
67
    private $height = 0;
68
69
    /**
70
     * The width of the node.
71
     *
72
     * @var int
73
     *
74
     * @since 1.0
75
     */
76
    private $width = 0;
77
78
    /**
79
     * The x position of the node.
80
     *
81
     * @var int
82
     *
83
     * @since 1.0
84
     */
85
    private $x = 0;
86
87
    /**
88
     * The y position of the node.
89
     *
90
     * @var int
91
     *
92
     * @since 1.0
93
     */
94
    private $y = 0;
95
96
    /**
97
     * The node to the left of this one.
98
     *
99
     * @var Alpha\Util\Graph\GraphNode
100
     *
101
     * @since 1.0
102
     */
103
    private $leftNode;
104
105
    /**
106
     * The node to the right of this one.
107
     *
108
     * @var Alpha\Util\Graph\GraphNode
109
     *
110
     * @since 1.0
111
     */
112
    private $rightNode;
113
114
    /**
115
     * An array of child nodes of this node.
116
     *
117
     * @var array
118
     *
119
     * @since 1.0
120
     */
121
    private $children = array();
122
123
    /**
124
     * The margin offset of the current node.
125
     *
126
     * @var int
127
     *
128
     * @since 1.0
129
     */
130
    private $offset = 0;
131
132
    /**
133
     * Optional positional modifier.
134
     *
135
     * @var int
136
     *
137
     * @since 1.0
138
     */
139
    private $modifier = 0;
140
141
    /**
142
     * Parent node of this node (if any).
143
     *
144
     * @var Alpha\Util\Graph\GraphNode
145
     *
146
     * @since 1.0
147
     */
148
    private $parentNode;
149
150
    /**
151
     * The text message to display on the node.
152
     *
153
     * @var string
154
     *
155
     * @since 1.0
156
     */
157
    private $message;
158
159
    /**
160
     * A 2D array of the coordinates of the endpoints for connectots on this node.
161
     *
162
     * @var array
163
     *
164
     * @since 1.0
165
     */
166
    private $links = array();
167
168
    /**
169
     * An array containing the R,G,B values for the colour of this node.
170
     *
171
     * @var array
172
     *
173
     * @since 1.0
174
     */
175
    private $nodeColour = array();
176
177
    /**
178
     * If the node is clickable in an image map, use this property to hold the target URL.
179
     *
180
     * @var string
181
     *
182
     * @since 1.0
183
     */
184
    private $URL;
185
186
    /**
187
     * Constructor.
188
     *
189
     * @param int    $id
190
     * @param int    $width
191
     * @param int    $height
192
     * @param string $message
193
     * @param array  $nodeColour
194
     * @param string $URL
195
     */
196
    public function __construct($id, $width, $height, $message = '', $nodeColour = array(), $URL = null)
197
    {
198
        $this->id = $id;
199
        $this->width = $width;
200
        $this->height = $height;
201
        $this->message = $message;
202
        $this->nodeColour = $nodeColour;
203
        $this->URL = $URL;
204
    }
205
206
    /**
207
     * Get the node colour array.
208
     *
209
     * @return array
210
     *
211
     * @since 1.0
212
     */
213
    public function getNodeColour()
214
    {
215
        return $this->nodeColour;
216
    }
217
218
    /**
219
     * Set the node colour array.
220
     *
221
     * @param array $nodeColour
222
     *
223
     * @throws Alpha\Exception\IllegalArguementException
224
     *
225
     * @since 1.0
226
     */
227
    public function setNodeColour($nodeColour)
228
    {
229
        if (is_array($nodeColour) && count($nodeColour) == 3) {
230
            $this->nodeColour = $nodeColour;
231
        } else {
232
            throw new IllegalArguementException('The nodeColour value passed ['.$nodeColour.'] is not a valid array!');
233
        }
234
    }
235
236
    /**
237
     * Get the node URL.
238
     *
239
     * @return string
240
     *
241
     * @since 1.0
242
     */
243
    public function getURL()
244
    {
245
        return $this->URL;
246
    }
247
248
    /**
249
     * Set the node URL.
250
     *
251
     * @param string $URL
252
     *
253
     * @since 1.0
254
     */
255
    public function setURL($URL)
256
    {
257
        $this->URL = $URL;
258
    }
259
260
    /**
261
     * Get the node text message.
262
     *
263
     * @return string
264
     *
265
     * @since 1.0
266
     */
267
    public function getMessage()
268
    {
269
        return $this->message;
270
    }
271
272
    /**
273
     * Set the node text message.
274
     *
275
     * @param string $message
276
     *
277
     * @since 1.0
278
     */
279
    public function setMessage($message)
280
    {
281
        $this->message = $message;
282
    }
283
284
    /**
285
     * Get the node offset.
286
     *
287
     * @return integer
288
     *
289
     * @since 1.0
290
     */
291
    public function getOffset()
292
    {
293
        return $this->offset;
294
    }
295
296
    /**
297
     * Set the node offset.
298
     *
299
     * @param int $offset
300
     *
301
     * @since 1.0
302
     */
303
    public function setOffset($offset)
304
    {
305
        $this->offset = $offset;
306
    }
307
308
    /**
309
     * Get the node modifier.
310
     *
311
     * @return int
312
     *
313
     * @since 1.0
314
     */
315
    public function getModifier()
316
    {
317
        return $this->modifier;
318
    }
319
320
    /**
321
     * Set the node modifier.
322
     *
323
     * @param int $modifier
324
     *
325
     * @since 1.0
326
     */
327
    public function setModifier($modifier)
328
    {
329
        $this->modifier = $modifier;
330
    }
331
332
    /**
333
     * Get the number of child nodes attached to this node.
334
     *
335
     * @return int
336
     *
337
     * @since 1.0
338
     */
339
    public function childCount()
340
    {
341
        return count($this->children);
342
    }
343
344
    /**
345
     * Get the parent node of this node (if any).
346
     *
347
     * @return Alpha\Util\Graph\GraphNode
348
     *
349
     * @since 1.0
350
     */
351
    public function getParentNode()
352
    {
353
        return $this->parentNode;
354
    }
355
356
    /**
357
     * Set the parent node.
358
     *
359
     * @param Alpha\Util\Graph\GraphNode $node
360
     *
361
     * @throws Alpha\Exception\IllegalArguementException
362
     *
363
     * @since 1.0
364
     */
365
    public function setParentNode($node)
366
    {
367
        if ($node instanceof self) {
368
            $this->parentNode = $node;
369
        } else {
370
            throw new IllegalArguementException('The node object passed to setParentNode is not a valid GraphNode instance!');
371
        }
372
    }
373
374
    /**
375
     * Get the node to the left of this one (if any).
376
     *
377
     * @return Alpha\Util\Graph\GraphNode
378
     *
379
     * @since 1.0
380
     */
381
    public function getLeftSibling()
382
    {
383
        if ($this->leftNode) {
384
            return $this->leftNode;
385
        } else {
386
            return;
387
        }
388
    }
389
390
    /**
391
     * Sets the node to the left of this node.
392
     *
393
     * @param Alpha\Util\Graph\GraphNode $node
394
     *
395
     * @throws Alpha\Exception\IllegalArguementException
396
     *
397
     * @since 1.0
398
     */
399
    public function setLeftSibling($node)
400
    {
401
        if ($node instanceof self) {
402
            $this->leftNode = $node;
403
        } else {
404
            throw new IllegalArguementException('The node object passed to setLeftSibling is not a valid GraphNode instance!');
405
        }
406
    }
407
408
    /**
409
     * Get the node to the right of this one (if any).
410
     *
411
     * @return Alpha\Util\Graph\GraphNode
412
     *
413
     * @since 1.0
414
     */
415
    public function getRightSibling()
416
    {
417
        if ($this->rightNode) {
418
            return $this->rightNode;
419
        } else {
420
            return;
421
        }
422
    }
423
424
    /**
425
     * Sets the node to the right of this node.
426
     *
427
     * @param Alpha\Util\Graph\GraphNode $node
428
     *
429
     * @throws Alpha\Exception\IllegalArguementException
430
     *
431
     * @since 1.0
432
     */
433
    public function setRightSibling($node)
434
    {
435
        if ($node instanceof self) {
436
            $this->rightNode = $node;
437
        } else {
438
            throw new IllegalArguementException('The node object passed to setRightSibling is not a valid GraphNode instance!');
439
        }
440
    }
441
442
    /**
443
     * Gets the child node at the index provided, or returns false if none is found.
444
     *
445
     * @param int $i
446
     *
447
     * @return mixed
448
     *
449
     * @since 1.0
450
     */
451
    public function getChildAt($i)
452
    {
453
        if (isset($this->children[$i])) {
454
            return $this->children[$i];
455
        } else {
456
            return false;
457
        }
458
    }
459
460
    /**
461
     * Calculates and returns the midpoint X coordinate of the children of this node.
462
     *
463
     * @return double
464
     *
465
     * @since 1.0
466
     */
467
    public function getChildrenCenter()
468
    {
469
        $node = $this->getChildAt(0);
470
        $node1 = $this->getChildAt(count($this->children)-1);
471
472
        return $node->getOffset()+(($node1->getOffset()-$node->getOffset())+$node1->getWidth())/2;
473
    }
474
475
    /**
476
     * Returns the array of child GraphNode objects.
477
     *
478
     * @return array
479
     *
480
     * @since 1.0
481
     */
482
    public function getChildren()
483
    {
484
        return $this->children;
485
    }
486
487
    /**
488
     * Add a new node to the children array of this node.
489
     *
490
     * @param GraphNode $node
491
     *
492
     * @throws ALpha\Exception\IllegalArguementException
493
     *
494
     * @since 1.0
495
     */
496
    public function addChild($node)
497
    {
498
        if ($node instanceof self) {
499
            array_push($this->children, $node);
500
        } else {
501
            throw new IllegalArguementException('The node object passed to addChild is not a valid GraphNode instance!');
502
        }
503
    }
504
505
    /**
506
     * Returns the links array.
507
     *
508
     * @return array
509
     *
510
     * @since 1.0
511
     */
512
    public function getLinks()
513
    {
514
        return $this->links;
515
    }
516
517
    /**
518
     * Sets up the array of connector endpoints.
519
     *
520
     * @since 1.0
521
     */
522
    public function setUpLinks()
523
    {
524
        $xa = $this->x+($this->width/2);
525
        $ya = $this->y+$this->height;
526
527
        foreach ($this->children as $child) {
528
            $xd = $xc = $child->getX()+($child->getWidth()/2);
529
            $yd = $child->getY();
530
            $xb = $xa;
531
            $yb = $yc = $ya+($yd-$ya)/2;
532
            $this->links[$child->id]['xa'] = $xa;
533
            $this->links[$child->id]['ya'] = $ya;
534
            $this->links[$child->id]['xb'] = $xb;
535
            $this->links[$child->id]['yb'] = $yb;
536
            $this->links[$child->id]['xc'] = $xc;
537
            $this->links[$child->id]['yc'] = $yc;
538
            $this->links[$child->id]['xd'] = $xd;
539
            $this->links[$child->id]['yd'] = $yd;
540
        }
541
    }
542
543
    /**
544
     * Returns the node height.
545
     *
546
     * @return int
547
     *
548
     * @since 1.0
549
     */
550
    public function getHeight()
551
    {
552
        return $this->height;
553
    }
554
555
    /**
556
     * Returns the node width.
557
     *
558
     * @return int
559
     *
560
     * @since 1.0
561
     */
562
    public function getWidth()
563
    {
564
        return $this->width;
565
    }
566
567
    /**
568
     * Returns the node X-coordinate.
569
     *
570
     * @return int
571
     *
572
     * @since 1.0
573
     */
574
    public function getX()
575
    {
576
        return $this->x;
577
    }
578
579
    /**
580
     * Returns the node Y-coordinate.
581
     *
582
     * @return int
583
     *
584
     * @since 1.0
585
     */
586
    public function getY()
587
    {
588
        return $this->y;
589
    }
590
591
    /**
592
     * Sets the node X-coordinate.
593
     *
594
     * @param int $x
595
     *
596
     * @since 1.0
597
     */
598
    public function setX($x)
599
    {
600
        $this->x = $x;
601
    }
602
603
    /**
604
     * Sets the node Y-coordinate.
605
     *
606
     * @param int $y
607
     *
608
     * @since 1.0
609
     */
610
    public function setY($y)
611
    {
612
        $this->y = $y;
613
    }
614
615
    /**
616
     * Returns the node ID.
617
     *
618
     * @return int
619
     *
620
     * @since 3.1
621
     */
622
    public function getID()
623
    {
624
        return $this->id;
625
    }
626
}
627