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

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

169 lines 5.5 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 trait DonutGraphTrait {
25
26 /**
27 * Returns the outer and inner angle adjustments for the slice gap
28 */
29 public function getSliceGap($angle, $ratio)
30 {
31 $gap_angle = $this->getOption('donut_slice_gap');
32 $outer_a = $inner_a = 0;
33 if($gap_angle > 0) {
34 $a = deg2rad($gap_angle);
35 if($a < $angle * 0.5) {
36 $outer_a = 0.5 * $a;
37 $inner_a = $outer_a / $ratio;
38 }
39 }
40 return [$outer_a, $inner_a];
41 }
42
43 /**
44 * Override the parent to draw doughnut slice
45 */
46 protected function getSlice($item, $angle_start, $angle_end, $radius_x,
47 $radius_y, &$attr, $single_slice, $colour_index)
48 {
49 $ratio = min(0.99, max(0.01, $this->getOption('inner_radius')));
50 $angle = $angle_end - $angle_start;
51
52 list($outer_a, $inner_a) = $this->getSliceGap($angle, $ratio);
53 $x_start = $y_start = $x_end = $y_end = 0;
54 $angle_start += $this->s_angle;
55 $angle_end += $this->s_angle;
56 $this->calcSlice($angle_start + $outer_a, $angle_end - $outer_a,
57 $radius_x, $radius_y, $x_start, $y_start, $x_end, $y_end);
58 $xc = $this->x_centre;
59 $yc = $this->y_centre;
60 $rx1 = $radius_x * $ratio;
61 $ry1 = $radius_y * $ratio;
62
63 if($single_slice && $this->full_angle >= M_PI * 2.0) {
64 $x1_start = $xc + $rx1;
65 $x1_end = $xc - $rx1;
66 $y1_start = $y1_end = $yc;
67 $x2_start = $xc + $radius_x;
68 $x2_end = $xc - $radius_x;
69 $y2_start = $y2_end = $yc;
70 // path with ellipses made of arcs
71 $path = new PathData('M', $x1_start, $y1_start);
72 $path->add('A', $rx1, $ry1, 0, 0, 0, $x1_end, $y1_end);
73 $path->add('A', $rx1, $ry1, 0, 0, 0, $x1_start, $y1_start);
74 $path->add('M', $x2_start, $y2_start);
75 $path->add('A', $radius_x, $radius_y, 0, 0, 0, $x2_end, $y2_end);
76 $path->add('A', $radius_x, $radius_y, 0, 0, 0, $x2_start, $y2_start);
77 $attr['d'] = $path;
78 $attr['fill-rule'] = 'evenodd';
79 } else {
80 $outer = ($angle > M_PI ? 1 : 0);
81 $sweep = ($this->getOption('reverse') ? 0 : 1);
82
83 // inner radius reduced by gap
84 $as = $angle_start + $inner_a;
85 $ae = $angle_end - $inner_a;
86 if($ae < $as)
87 $ae = $as = ($ae + $as) / 2; // not enough space, so come to a point
88
89 $this->calcSlice($as, $ae, $rx1, $ry1, $x1_start, $y1_start, $x1_end, $y1_end);
90 $isweep = $sweep ? 0 : 1;
91 $path = new PathData('M', $x1_end, $y1_end);
92 $path->add('A', $rx1, $ry1, 0, $outer, $isweep, $x1_start, $y1_start);
93 $path->add('L', $x_start, $y_start);
94 $path->add('A', $radius_x, $radius_y, 0, $outer, $sweep, $x_end, $y_end, 'z');
95 $attr['d'] = $path;
96 }
97 return $this->element('path', $attr);
98 }
99
100 /**
101 * Returns extra drawing code that goes between pie and labels
102 */
103 protected function pieExtras()
104 {
105 $inner_text = $this->getOption('inner_text');
106 if(empty($inner_text))
107 return '';
108
109 // use content label for inner text - measurements don't really matter
110 $this->addContentLabel('innertext', 0,
111 $this->x_centre - 100, $this->y_centre - 100, 200, 200,
112 $inner_text);
113 return '';
114 }
115
116 /**
117 * Overridden to keep inner text in the middle
118 */
119 public function dataLabelPosition($dataset, $index, &$item, $x, $y, $w, $h,
120 $label_w, $label_h)
121 {
122 if($dataset === 'innertext')
123 return ['centre middle', [$x, $y] ];
124
125 list($pos, $target) = parent::dataLabelPosition($dataset, $index, $item,
126 $x, $y, $w, $h, $label_w, $label_h);
127 if(isset($this->slice_info[$index]) && $this->getOption('label_position') <= 1) {
128 $a = $this->slice_info[$index]->midAngle();
129 $ac = $this->s_angle + $a;
130 $rx = $this->slice_info[$index]->radius_x;
131 $ry = $this->slice_info[$index]->radius_y;
132 $ring_centre = ($this->getOption('inner_radius') + 1) * 0.5;
133 $xt = $rx * $ring_centre * cos($ac);
134 $yt = ($this->getOption('reverse') ? -1 : 1) * $ry * $ring_centre * sin($ac);
135 $target = [$x + $xt, $y + $yt];
136 }
137 return [$pos, $target];
138 }
139
140 /**
141 * Returns the style options for the inner text label
142 */
143 public function dataLabelStyle($dataset, $index, &$item)
144 {
145 $style = parent::dataLabelStyle($dataset, $index, $item);
146
147 if($dataset !== 'innertext')
148 return $style;
149
150 // label settings can override global settings
151 $opts = [
152 'font' => 'inner_text_font',
153 'font_size' => 'inner_text_font_size',
154 'font_weight' => 'inner_text_font_weight',
155 'font_adjust' => 'inner_text_font_adjust',
156 'colour' => 'inner_text_colour',
157 'back_colour' => 'inner_text_back_colour',
158 ];
159 foreach($opts as $key => $opt)
160 if(isset($this->settings[$opt]) && !empty($this->settings[$opt]))
161 $style[$key] = $this->settings[$opt];
162
163 // no boxes
164 $style['type'] = 'plain';
165 return $style;
166 }
167 }
168
169