1<?php
2
3/**
4 * Plugin AVBarChart: Generates a very simple CSS/HTML bar chart
5 *
6 * USAGE: <barchart>MAXVAL|Label1:#,Label2:#,Label3:#</barchart>
7 *
8 * EXAMPLE: <barchart>100|A:55,B:5,C:23,D:38</barchart>
9 *
10 * With Colored Bars: <barchart>100|A:55:#FFCCCC,B:5,C:23#00FF00,D:38</barchart>
11 *
12 * @license    GPL-2.0 (https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html)
13 * @author     Sherri W. (http://syntaxseed.com)
14 */
15
16if (!defined('DOKU_INC')) {
17    define('DOKU_INC', realpath(dirname(__FILE__) . '/../../') . '/');
18}
19if (!defined('DOKU_PLUGIN')) {
20    define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
21}
22
23
24/**
25 * All DokuWiki plugins to extend the parser/rendering mechanism
26 * need to inherit from this class
27 */
28class syntax_plugin_avbarchart extends DokuWiki_Syntax_Plugin
29{
30    // ********* CHART CONFIG SETTINGS *************
31    public $barWidth = 25;         // Pixel width of chart bars.
32    public $barColor = "#ccccff";  // Default color of graph bars.
33    public $fontSize = "8pt;";     // Font size of labels and values.
34    public $maxPxHeight = "200";   // Maximum height of the chart in pixels.
35    // *********************************************
36
37    /**
38     * What kind of syntax are we?
39     */
40    public function getType()
41    {
42        return 'substition';
43    }
44
45    /**
46     * Where to sort in?
47     */
48    public function getSort()
49    {
50        return 999;
51    }
52
53
54    /**
55     * Connect pattern to lexer
56     */
57    public function connectTo($mode)
58    {
59        $this->Lexer->addEntryPattern('\<barchart\>', $mode, 'plugin_avbarchart');
60    }
61
62    public function postConnect()
63    {
64        $this->Lexer->addExitPattern('\</barchart\>', 'plugin_avbarchart');
65    }
66
67
68    /**
69     * Handle the match
70     */
71    public function handle($match, $state, $pos, Doku_Handler $handler)
72    {
73        switch ($state) {
74            case DOKU_LEXER_ENTER:
75                return array($state, '');
76            case DOKU_LEXER_MATCHED:
77                break;
78            case DOKU_LEXER_UNMATCHED:
79
80                $chart = "";
81                list($maxRange, $data1) = preg_split("/\|/", $match);
82                $maxRange = floatval($maxRange);
83
84                if ($maxRange > 0 && !empty($data1)) {
85                    $values = preg_split("/,/", $data1);
86
87                    $chart = "";
88                    foreach ($values as $col) {
89                        if (!empty($col)) {
90                            $inColumn = preg_split("/:/", $col);
91                            $label = $inColumn[0] ?? '';
92                            $amount = $inColumn[1] ?? 0;
93                            $color = $inColumn[2] ?? null;
94
95                            $amount = floatval($amount);
96
97                            if (empty($label)) {
98                                $label = '&nbsp;';
99                            } else {
100                                $label = hsc($label);
101                            }
102
103                            if (empty($color)) {
104                                $color = $this->barColor;
105                            } else {
106                                $color = hsc($color);
107                            }
108
109                            if ($amount >= 0) {
110                                $height = round(($amount / $maxRange * $this->maxPxHeight));
111                                $chart .= "<td valign='bottom' style='border:0;vertical-align:bottom;text-align:center;' align='center'><span style='font-size:" . $this->fontSize . ";'>" . $amount . "</span><br clear='all' /><table style='display:inline;border:0;' cellpadding='1' cellspacing='0'><tr><td height='" . $height . "' width='" . $this->barWidth . "' bgcolor='" . $color . "' valign='bottom'></td></tr></table><br clear='all' /><span style='font-size:" . $this->fontSize . ";'><b>" . $label . "</b></span></td>";
112                            }
113                        }
114                    }
115                }
116
117                $match = $chart;
118                return array($state, $match);
119
120            case DOKU_LEXER_EXIT:
121                return array($state, '');
122            case DOKU_LEXER_SPECIAL:
123                break;
124        }
125        return array();
126    }
127
128
129    /**
130     * Create output
131     */
132    public function render($mode, Doku_Renderer $renderer, $data)
133    {
134        if ($mode == 'xhtml') {
135            list($state, $match) = $data;
136
137            switch ($state) {
138                case DOKU_LEXER_ENTER:
139                    $renderer->doc .= "<table border='0' cellspacing='2' style='border:0;'><tr>";
140                    break;
141
142                case DOKU_LEXER_MATCHED:
143                    break;
144
145                case DOKU_LEXER_UNMATCHED:
146
147                    $renderer->doc .= $match;
148                    break;
149
150                case DOKU_LEXER_EXIT:
151                    $renderer->doc .= "</tr></table>";
152                    break;
153
154                case DOKU_LEXER_SPECIAL:
155                    break;
156            }
157            return true;
158        }
159        return false;
160    }
161} // End class
162