PluginProbe
E2Pdf – Export Pdf Tool for WordPress / 1.32.48
E2Pdf – Export Pdf Tool for WordPress v1.32.48
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 / DonutSliceEdge.php

DonutSliceEdge.php in E2Pdf – Export Pdf Tool for WordPress 1.32.48, at vendors/svggraph/DonutSliceEdge.php

234 lines 6.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Copyright (C) 2021-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 * The DonutSliceEdge class calculates and draws the 3D slice edges
26 */
27 class DonutSliceEdge extends PieSliceEdge {
28
29 protected $ratio = 1.0;
30 protected $outer_a = 0;
31 protected $inner_a = 0;
32
33 /**
34 * $slice is the slice details array
35 * $s_angle is the start angle in radians
36 */
37 public function __construct(&$graph, $type, $slice, $s_angle)
38 {
39 // types: 0 => start flat, 1 => end flat, 2, 3, 4, 5 => curves, -1 => no edge
40 $this->type = -1;
41 $this->slice = $slice;
42 $tau = M_PI * 2.0;
43
44 $start_angle = $slice['angle_start'] + $s_angle;
45 $end_angle = $slice['angle_end'] + $s_angle;
46 $ratio = min(0.99, max(0.01, $graph->getOption('inner_radius')));
47 list($outer_a, $inner_a) = $graph->getSliceGap($end_angle - $start_angle, $ratio);
48 $this->outer_a = $outer_a;
49 $this->inner_a = $inner_a;
50
51 if(isset($slice['single_slice']) && $slice['single_slice'] &&
52 !is_numeric($graph->end_angle)) {
53
54 // full pie, draw full bottom and inner edges only
55 switch($type)
56 {
57 case 2:
58 $start_angle = 0.0;
59 $end_angle = M_PI;
60 break;
61 case 4:
62 $start_angle = M_PI;
63 $end_angle = $tau;
64 break;
65 default:
66 return;
67 }
68 } elseif($graph->getOption('reverse')) {
69 // apply reverse now to save thinking about it later
70 $s = M_PI * 4.0 - $end_angle;
71 $e = M_PI * 4.0 - $start_angle;
72 $start_angle = $s;
73 $end_angle = $e;
74 }
75
76 $this->a1 = fmod($start_angle, $tau);
77 $this->a2 = fmod($end_angle, $tau);
78 if($this->a2 < $this->a1)
79 $this->a2 += $tau;
80
81 switch($type) {
82 case 0:
83 // flat edge at a1
84 $this->a2 = $this->a1;
85 $this->ratio = $ratio;
86 break;
87 case 1:
88 // flat edge at a2
89 $this->a1 = $this->a2;
90 $this->ratio = $ratio;
91 $this->outer_a = -$outer_a;
92 $this->inner_a = -$inner_a;
93 break;
94 case 2:
95 // bottom edge
96 if($this->a1 > M_PI && $this->a2 < $tau)
97 return;
98 // truncate curves to visible area
99 if($this->a1 <= M_PI && $this->a2 >= M_PI)
100 $this->a2 = M_PI;
101 elseif($this->a1 > M_PI && $this->a2 > $tau)
102 $this->a1 = $tau;
103 if($this->a2 > M_PI * 3.0)
104 $this->a2 = M_PI * 3.0;
105 break;
106 case 3:
107 // type 3 edges are where the slice starts bottom, goes through top and ends at bottom
108 if($this->a2 < $tau || $this->a2 > M_PI * 3.0 || $this->a1 >= M_PI)
109 return;
110
111 $this->a1 = $tau;
112 break;
113 case 4:
114 // slices passing through top
115 if($this->a2 <= M_PI)
116 return;
117
118 if($this->a1 < M_PI)
119 $this->a1 = M_PI;
120 if($this->a2 > $tau)
121 $this->a2 = $tau;
122 $this->ratio = $ratio;
123 break;
124 case 5:
125 // slice starts at top, passes through bottom and ends at top
126 if($this->a2 < M_PI * 3.0)
127 return;
128
129 $this->a1 = M_PI * 3.0;
130 $this->ratio = $ratio;
131 break;
132 }
133
134 // ignore tiny curves as floating point artifacts
135 if($type > 1 && abs($this->a1 - $this->a2) < 0.0001)
136 return;
137
138 $this->setupSort();
139 $this->type = $type;
140 }
141
142 /**
143 * Returns the number of edge types this class supports
144 */
145 protected static function getEdgeTypes()
146 {
147 return 5;
148 }
149
150 /**
151 * Returns TRUE when the edge is visible
152 */
153 public function visible()
154 {
155 switch($this->type)
156 {
157 case -1:
158 return false; // type -1 is for non-existent edges
159 case 0:
160 // start on right not visible
161 if($this->a1 < M_PI * 0.5 || $this->a1 > M_PI * 1.5)
162 return false;
163 break;
164 case 1:
165 // end on left not visible
166 $a2 = fmod($this->a2, M_PI * 2.0);
167 if($a2 > M_PI * 0.5 && $a2 < M_PI * 1.5)
168 return false;
169 break;
170 }
171
172 // curves always visible on donut graph
173 return true;
174 }
175
176 /**
177 * Returns TRUE when this is an inner edge
178 */
179 public function inner()
180 {
181 return $this->type > 3;
182 }
183
184 /**
185 * Returns the ratio of inner to outer
186 */
187 public function getInnerRatio()
188 {
189 return $this->ratio;
190 }
191
192 /**
193 * Returns the path for a flat edge
194 */
195 protected function getFlatPath($angle, $x_centre, $y_centre, $depth)
196 {
197 $rx1 = $this->slice['radius_x'] * cos($angle + $this->outer_a);
198 $ry1 = $this->slice['radius_y'] * sin($angle + $this->outer_a);
199 $rx2 = $this->slice['radius_x'] * $this->ratio * cos($angle + $this->inner_a);
200 $ry2 = $this->slice['radius_y'] * $this->ratio * sin($angle + $this->inner_a);
201 $x1 = $x_centre + $rx1;
202 $y1 = $y_centre + $ry1;
203 $x2 = $x_centre + $rx2;
204 $y2 = $y_centre + $ry2;
205 return new PathData('M', $x2, $y2, 'v', $depth, 'L', $x1, $y1 + $depth,
206 'v', -$depth, 'z');
207 }
208
209 /**
210 * Returns the path for the curved edge
211 */
212 protected function getCurvedPath($x_centre, $y_centre, $depth)
213 {
214 $a = $this->ratio < 1.0 ? $this->inner_a : $this->outer_a;
215 $rx = $this->slice['radius_x'] * $this->ratio;
216 $ry = $this->slice['radius_y'] * $this->ratio;
217 $x1 = $x_centre + $rx * cos($this->a1 + $a);
218 $y1 = $y_centre + $ry * sin($this->a1 + $a);
219 $x2 = $x_centre + $rx * cos($this->a2 - $a);
220 $y2 = $y_centre + $ry * sin($this->a2 - $a);
221 $y2d = $y2 + $depth;
222
223 $outer = 0; // edge is never > PI
224 $sweep = 1;
225
226 $path = new PathData('M', $x1, $y1, 'v', $depth, 'A', $rx, $ry, 0,
227 $outer, $sweep, $x2, $y2d, 'v', -$depth);
228 $sweep = $sweep ? 0 : 1;
229 $path->add('A', $rx, $ry, 0, $outer, $sweep, $x1, $y1);
230 return $path;
231 }
232 }
233
234