PluginProbe
E2Pdf – Export Pdf Tool for WordPress / 1.32.23
E2Pdf – Export Pdf Tool for WordPress v1.32.23
1.32.49 1.32.48 1.32.43 1.32.40 1.32.34 1.32.32 1.32.31 1.32.26 1.32.22 1.32.23 1.32.18 1.32.17 1.32.15 trunk 1.00.00 1.00.13 1.01.01 1.02.02 1.03.07 1.04.07 1.05.03 1.06.02 1.07.11 1.08.00 1.08.06 All 72 releases
e2pdf / vendors / svggraph / DisplayAxisLevels.php

DisplayAxisLevels.php in E2Pdf – Export Pdf Tool for WordPress 1.32.23, at vendors/svggraph/DisplayAxisLevels.php

304 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Copyright (C) 2020-2022 Graham Breach
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 /**
19 * For more information, please contact <graham@goat1000.com>
20 */
21
22 namespace Goat1000\SVGGraph;
23
24 /**
25 * An axis with multiple levels of divisions
26 */
27 class DisplayAxisLevels extends DisplayAxis {
28
29 protected $level_count;
30 protected $levels;
31
32 /**
33 * Pass all these to parent constructor
34 */
35 public function __construct(&$graph, &$axis, $axis_no, $orientation, $type,
36 $main, $label_centre)
37 {
38 parent::__construct($graph, $axis, $axis_no, $orientation, $type, $main,
39 $label_centre);
40
41 if(!$this->show_text)
42 {
43 $this->levels = [null];
44 $this->level_count = 1;
45 return;
46 }
47
48 $levels = $graph->getOption(['axis_levels_' . $orientation, $axis_no]);
49 if(!is_array($levels))
50 $levels = array_fill(0, $levels, null);
51 $this->levels = $levels;
52 $this->level_count = count($levels);
53 }
54
55 /**
56 * Returns the extents of the axis, relative to where it will be drawn from
57 * returns BoundingBox
58 */
59 public function measure($with_label = true)
60 {
61 if($this->level_count <= 1)
62 return parent::measure($with_label);
63
64 $bbox = new BoundingBox(0, 0, 0, 0);
65 for($i = 0; $i < $this->level_count; ++$i) {
66 $dbox = $this->getDivisionsBBox($i);
67 $tbox = $this->getTextBBox($i);
68 if($this->orientation == 'h') {
69 $dbox->flipY();
70 if($this->axis_no > 0) {
71 $dbox->offset(0, $bbox->y1);
72 $tbox->offset(0, $bbox->y1);
73 } else {
74 $dbox->offset(0, $bbox->y2);
75 $tbox->offset(0, $bbox->y2);
76 }
77 } else {
78 if($this->axis_no > 0) {
79 $dbox->offset($bbox->x2, 0);
80 $tbox->offset($bbox->x2, 0);
81 } else {
82 $dbox->offset($bbox->x1, 0);
83 $tbox->offset($bbox->x1, 0);
84 }
85 }
86 // store the text box for this level
87 $this->levels[$i]['text_box'] = $tbox;
88
89 $bbox->growBox($tbox);
90 $bbox->growBox($dbox);
91 }
92
93 if($with_label && $this->show_label) {
94 $lpos = $this->getLabelPosition();
95 $bbox->grow($lpos['x'], $lpos['y'], $lpos['x'] + $lpos['width'],
96 $lpos['y'] + $lpos['height']);
97 }
98 $bbox = $this->addOffset($bbox);
99
100 return $bbox;
101 }
102
103 /**
104 * Returns the bounding box of the text
105 */
106 protected function getTextBBox($level)
107 {
108 if($this->level_count <= 1 || !$this->boxed_text)
109 return parent::getTextBBox($level);
110
111 $bbox = new BoundingBox(0, 0, 0, 0);
112 list($x_off, $y_off, $opp) = $this->getTextOffset(0, 0, 0, 0, 0, 0, $level);
113 $t_offset = ($this->orientation == 'h' ? $x_off : $y_off);
114 if($this->axis->reversed())
115 $t_offset = -$t_offset;
116 $length = $this->axis->getLength();
117
118 $points = $this->axis->getGridPoints(0);
119 $lpoints = $this->getPointsForLevel($points, $level);
120 $positions = $this->getTextPositions(0, 0, $x_off, $y_off, $lpoints, null);
121 $pcount = count($positions);
122 for($p = 0; $p < $pcount; ++$p) {
123 $point = $lpoints[$p];
124 if(!$this->pointTextVisible($point, $length, $t_offset))
125 continue;
126 if(!$point->blank($level)) {
127 $pos = $positions[$p];
128 $lbl = $this->measureText($pos['x'], $pos['y'], $point, $opp, $level);
129 $bbox->grow($lbl['x'], $lbl['y'], $lbl['x'] + $lbl['width'],
130 $lbl['y'] + $lbl['height']);
131 }
132 }
133 return $bbox;
134 }
135
136 /**
137 * Draws the axis text labels
138 */
139 public function drawText($x, $y, $gx, $gy, $g_width, $g_height)
140 {
141 if($this->level_count <= 1)
142 return parent::drawText($x, $y, $gx, $gy, $g_width, $g_height);
143
144 list($x_offset, $y_offset, $opposite) = $this->getTextOffset($x, $y,
145 $gx, $gy, $g_width, $g_height, 0);
146
147 $t_offset = ($this->orientation == 'h' ? $x_offset : $y_offset);
148 if($this->axis->reversed())
149 $t_offset = -$t_offset;
150
151 // measure function fills in text locations
152 $this->measure();
153 $labels = '';
154 $anchor = null;
155 $points = $this->axis->getGridPoints(0);
156 $length = $this->axis->getLength();
157
158 for($i = 0; $i < $this->level_count; ++$i) {
159 $count = count($points);
160 if($this->block_label)
161 --$count;
162
163 list($x_offset, $y_offset, $opposite) = $this->getTextOffset($x, $y,
164 $gx, $gy, $g_width, $g_height, $i);
165 $x1 = $x_offset;
166 $y1 = $y_offset;
167
168 $tbox = $this->levels[$i]['text_box'];
169 if($this->orientation == 'h') {
170 if($this->axis_no > 0)
171 $y1 = $y_offset + $tbox->y2;
172 else
173 $y1 = $y_offset + $tbox->y1;
174 switch($this->styles['t_align']) {
175 case 'left':
176 $anchor = 'start';
177 break;
178 case 'right':
179 $anchor = 'end';
180 break;
181 }
182 } else {
183 if($this->axis_no > 0)
184 $x1 = $x_offset + $tbox->x1;
185 else
186 $x1 = $x_offset + $tbox->x2;
187 switch($this->styles['t_align']) {
188 case 'left':
189 if(!$opposite) {
190 $anchor = 'start';
191 $x1 = $tbox->x1;
192 }
193 break;
194 case 'centre':
195 $x1 = ($tbox->x1 + $tbox->x2) / 2;
196 $anchor = 'middle';
197 break;
198 }
199 }
200
201 $lpoints = $this->getPointsForLevel($points, $i);
202 $positions = $this->getTextPositions($x, $y, $x1, $y1, $lpoints, $anchor);
203 $pcount = count($positions);
204 for($p = 0; $p < $pcount; ++$p) {
205 $point = $lpoints[$p];
206 if(!$this->pointTextVisible($point, $length, $t_offset))
207 continue;
208 $pos = $positions[$p];
209 $labels .= $this->getText($pos['x'], $pos['y'], $point, $opposite, $i, $anchor);
210 }
211 }
212 if($labels != '') {
213 $group = [
214 'font-family' => $this->styles['t_font'],
215 'font-size' => $this->styles['t_font_size'],
216 'fill' => $this->styles['t_colour'],
217 ];
218 $weight = $this->styles['t_font_weight'];
219 if($weight != 'normal' && $weight !== null)
220 $group['font-weight'] = $weight;
221
222 $labels = $this->graph->element('g', $group, null, $labels);
223 }
224
225 if($this->show_label)
226 $labels .= $this->getLabel($x, $y, $gx, $gy, $g_width, $g_height);
227
228 return $labels;
229 }
230
231 /**
232 * Draws the axis divisions
233 */
234 public function drawDivisions($x, $y, $g_width, $g_height)
235 {
236 // parent can do simple divisions
237 if($this->level_count <= 1 || !$this->boxed_text)
238 return parent::drawDivisions($x, $y, $g_width, $g_height);
239
240 $path = '';
241 $points = $this->axis->getGridPoints(0);
242 $x_offset = $y_offset = 0;
243
244 // direction of offset depends on h/v and axis number
245 $direction = ($this->orientation == 'v' ? -1 : 1);
246 if($this->axis_no > 0)
247 $direction = -$direction;
248
249 for($i = 0; $i < $this->level_count; ++$i) {
250 $path_info = $this->getDivisionPathInfo(false, $g_width, $g_height, $i);
251 if($path_info === null)
252 continue;
253
254 $lpoints = $this->getPointsForLevel($points, $i);
255 $path .= $this->getDivisionPath($x + $x_offset, $y + $y_offset, $lpoints,
256 $path_info, $i);
257
258 if($this->orientation == 'h')
259 $y_offset += $direction * $path_info['sz'];
260 else
261 $x_offset += $direction * $path_info['sz'];
262 }
263 if($path == '')
264 return '';
265
266 $attr = [
267 'd' => $path,
268 'stroke' => $this->styles['d_colour'],
269 'fill' => 'none',
270 ];
271 return $this->graph->element('path', $attr);
272 }
273
274 /**
275 * Returns the list of points with text for $level
276 */
277 protected function getPointsForLevel($points, $level)
278 {
279 // need first point even if it is blank
280 $lpoints = [$points[0]];
281 $prev = $points[0]->getText($level);
282
283 $last_point = count($points) - 1;
284 $end = $this->boxed_text ? $last_point : $last_point + 1;
285 for($p = 1; $p < $end; ++$p) {
286 if($points[$p]->blank($level))
287 continue;
288
289 $label = $points[$p]->getText($level);
290 if($label == $prev)
291 continue;
292
293 $lpoints[] = $points[$p];
294 $prev = $label;
295 }
296
297 // the last point is the division at the end of the axis
298 if($this->boxed_text)
299 $lpoints[] = $points[$last_point];
300 return $lpoints;
301 }
302 }
303
304