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 / HorizontalGridGraph.php

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

273 lines 8.4 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 abstract class HorizontalGridGraph extends GridGraph {
25
26 public function __construct($w, $h, array $settings, array $fixed_settings = [])
27 {
28 // convert _x and _y labels to _v and _h
29 if(!empty($settings['label_x']) && empty($settings['label_v']))
30 $settings['label_v'] = $settings['label_x'];
31 if(!empty($settings['label_y']) && empty($settings['label_h']))
32 $settings['label_h'] = $settings['label_y'];
33
34 // unset these so GridGraph doesn't use them
35 unset($settings['label_x'], $settings['label_y']);
36
37 parent::__construct($w, $h, $settings, $fixed_settings);
38 }
39
40 /**
41 * Swap the axis returned
42 */
43 protected function getDisplayAxis($axis, $axis_no, $orientation, $type)
44 {
45 return parent::getDisplayAxis($axis, $axis_no, $orientation,
46 $type === 'x' ? 'y' : 'x');
47 }
48
49 /**
50 * Returns the factory for an X-axis
51 */
52 protected function getXAxisFactory()
53 {
54 return new AxisFactory(false, $this->settings, false, false, false);
55 }
56
57 /**
58 * Returns the factory for a Y-axis
59 */
60 protected function getYAxisFactory()
61 {
62 $y_bar = $this->getOption('label_centre');
63 return new AxisFactory($this->getOption('datetime_keys'), $this->settings,
64 true, $y_bar, true);
65 }
66
67 /**
68 * Creates and returns an X-axis
69 */
70 protected function createXAxis($factory, $length, $ends, $i, $min_space, $grid_division)
71 {
72 $max_h = $ends['v_max'][$i];
73 $min_h = $ends['v_min'][$i];
74 if(!is_numeric($max_h) || !is_numeric($min_h))
75 throw new \Exception('Non-numeric min/max');
76
77 $min_unit = $this->getOption(['minimum_units_y', $i]);
78 $units_after = (string)$this->getOption(['units_y', $i]);
79 $units_before = (string)$this->getOption(['units_before_y', $i]);
80 $decimal_digits = $this->getOption(['decimal_digits_y', $i],
81 'decimal_digits');
82 $text_callback = $this->getOption(['axis_text_callback_y', $i],
83 'axis_text_callback');
84 $log = $this->getOption(['log_axis_y', $i]);
85 $log_base = $this->getOption(['log_axis_y_base', $i]);
86 $ticks = $this->getOption(['axis_ticks_y', $i]);
87 $values = $levels = null;
88
89 if($min_h == $max_h) {
90 if($min_unit > 0) {
91 $inc = $min_unit;
92 } else {
93 $fallback = $this->getOption('axis_fallback_max');
94 $inc = $fallback > 0 ? $fallback : 1;
95 }
96 $max_h += $inc;
97 }
98
99 $x_axis = $factory->get($length, $min_h, $max_h, $min_unit,
100 $min_space, $grid_division, $units_before, $units_after,
101 $decimal_digits, $text_callback, $values, $log, $log_base, $levels, $ticks);
102 $x_axis->setTightness($this->getOption(['axis_tightness_y', $i]));
103 return $x_axis;
104 }
105
106 /**
107 * Creates and returns a Y-axis
108 */
109 protected function createYAxis($factory, $length, $ends, $i, $min_space, $grid_division)
110 {
111 $max_v = $ends['k_max'][$i];
112 $min_v = $ends['k_min'][$i];
113 if(!is_numeric($max_v) || !is_numeric($min_v))
114 throw new \Exception('Non-numeric min/max');
115
116 $min_unit = 1;
117 $text_callback = $this->getOption(['axis_text_callback_x', $i],
118 'axis_text_callback');
119 $decimal_digits = $this->getOption(['decimal_digits_x', $i],
120 'decimal_digits');
121 $units_after = (string)$this->getOption(['units_x', $i]);
122 $units_before = (string)$this->getOption(['units_before_x', $i]);
123 $values = $this->multi_graph ? $this->multi_graph : $this->values;
124 $levels = $this->getOption(['axis_levels_h', $i]);
125 $log = $this->getOption(['log_axis_x', $i]);
126 $log_base = $this->getOption(['log_axis_x_base', $i]);
127 $ticks = $this->getOption('axis_ticks_x');
128
129 return $factory->get($length, $min_v, $max_v, $min_unit,
130 $min_space, $grid_division, $units_before, $units_after,
131 $decimal_digits, $text_callback, $values, $log, $log_base, $levels, $ticks);
132 }
133
134 /**
135 * Calculates the position of grid lines
136 */
137 protected function calcGrid()
138 {
139 parent::calcGrid();
140
141 $this->grid_limit = 0.01 + $this->g_height;
142 if($this->getOption('label_centre')) {
143 $y_axis = $this->y_axes[$this->main_y_axis];
144 $this->grid_limit -= $y_axis->unit() / 2;
145 }
146 }
147
148 /**
149 * Returns the subdivisions for a Y-axis
150 */
151 protected function getSubDivsY($axis)
152 {
153 $a = $this->y_axes[$axis];
154 $offset = $a->reversed() ? $this->height - $this->pad_bottom : $this->pad_top;
155 return $a->getGridSubdivisions($this->getOption('minimum_subdivision'), 1,
156 $offset, $this->getOption(['subdivision_v', $axis]));
157 }
158
159 /**
160 * Returns the subdivisions for an X-axis
161 */
162 protected function getSubDivsX($axis)
163 {
164 $a = $this->x_axes[$axis];
165 $offset = $a->reversed() ? $this->width - $this->pad_right : $this->pad_left;
166 return $a->getGridSubdivisions($this->getOption('minimum_subdivision'),
167 $this->getOption(['minimum_units_y', $axis]), $offset,
168 $this->getOption(['subdivision_h', $axis]));
169 }
170
171 /**
172 * Returns fixed min and max option for an axis
173 */
174 protected function getFixedAxisOptions($axis, $index)
175 {
176 $a = $axis == 'y' ? 'h' : 'v';
177 $min = $this->getOption(['axis_min_' . $a, $index]);
178 $max = $this->getOption(['axis_max_' . $a, $index]);
179 return [$min, $max];
180 }
181
182 /**
183 * Returns the crosshairs code
184 */
185 protected function getCrossHairs()
186 {
187 if(!$this->getOption('crosshairs'))
188 return '';
189
190 $ch = new CrossHairs($this, $this->pad_left, $this->pad_top,
191 $this->g_width, $this->g_height, $this->x_axes[$this->main_x_axis],
192 $this->y_axes[$this->main_y_axis], $this->values->associativeKeys(),
193 true, $this->encoding);
194
195 if($ch->enabled())
196 return $ch->getCrossHairs();
197 return '';
198 }
199
200 /**
201 * Returns the grid position for a bar or point, or NULL if not on grid
202 * $item = data item
203 * $index = integer position in array
204 */
205 protected function gridPosition($item, $index)
206 {
207 $axis = $this->y_axes[$this->main_y_axis];
208 $offset = $axis->position($index, $item);
209 $zero = -0.01; // catch values close to 0
210
211 if($offset >= $zero && floor($offset) <= $this->grid_limit)
212 return $axis->reversed() ? $this->height - $this->pad_bottom - $offset :
213 $this->pad_top + $offset;
214
215 return null;
216 }
217
218 /**
219 * Returns the SVG fragment for grid background stripes
220 */
221 protected function getGridStripes()
222 {
223 if(!$this->getOption('grid_back_stripe'))
224 return '';
225
226 // use array of colours if available, otherwise stripe a single colour
227 $colours = $this->getOption('grid_back_stripe_colour');
228 if(!is_array($colours))
229 $colours = [null, $colours];
230 $opacity = $this->getOption('grid_back_stripe_opacity');
231
232 $bars = '';
233 $c = 0;
234 $num_colours = count($colours);
235
236 $rect = [
237 'y' => new Number($this->pad_top),
238 'height' => new Number($this->g_height),
239 ];
240 if($opacity != 1)
241 $rect['fill-opacity'] = $opacity;
242 $points = $this->getGridPointsX($this->main_x_axis);
243 $first = array_shift($points);
244 $last_pos = $first->position;
245 foreach($points as $grid_point) {
246 $cc = $colours[$c % $num_colours];
247 if($cc !== null) {
248 $rect['x'] = $last_pos;
249 $rect['width'] = $grid_point->position - $last_pos;
250 $rect['fill'] = new Colour($this, $cc);
251 $bars .= $this->element('rect', $rect);
252 }
253 $last_pos = $grid_point->position;
254 ++$c;
255 }
256 return $this->element('g', [], null, $bars);
257 }
258
259 /**
260 * Converts guideline options to more useful member variables
261 */
262 protected function calcGuidelines()
263 {
264 $this->calcAverages();
265 $guidelines = $this->getOption('guideline');
266 if(empty($guidelines) && $guidelines !== 0)
267 return;
268
269 $this->guidelines = new Guidelines($this, true,
270 $this->values->associativeKeys(), $this->getOption('datetime_keys'));
271 }
272 }
273