PluginProbe
E2Pdf – Export Pdf Tool for WordPress / 1.32.49
E2Pdf – Export Pdf Tool for WordPress v1.32.49
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 / Pie3DGraph.php

Pie3DGraph.php in E2Pdf – Export Pdf Tool for WordPress 1.32.49, at vendors/svggraph/Pie3DGraph.php

210 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Copyright (C) 2010-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 class Pie3DGraph extends PieGraph {
25
26 protected $edge_class = 'Goat1000\\SVGGraph\\PieSliceEdge';
27 protected $depth;
28
29 public function __construct($w, $h, array $settings, array $fixed_settings = [])
30 {
31 $fs = [
32 // for 100% pie the flat sides are all hidden
33 'draw_flat_sides' => false,
34 ];
35 $fs = array_merge($fs, $fixed_settings);
36 parent::__construct($w, $h, $settings, $fs);
37
38 $this->depth = $this->getOption('depth');
39 }
40
41 protected function draw()
42 {
43 // modify pad_bottom to make PieGraph do the hard work
44 $pb = $this->pad_bottom;
45 $space = $this->height - $this->pad_top - $this->pad_bottom;
46 if($space < $this->depth)
47 $this->depth = $space / 2;
48 $this->pad_bottom += $this->depth;
49 $this->calc();
50 $this->pad_bottom = $pb;
51
52 // see if flat sides are visible
53 if(is_numeric($this->end_angle)) {
54 $start = fmod(deg2rad($this->start_angle), M_PI * 2.0);
55 $end = fmod(deg2rad($this->end_angle), M_PI * 2.0);
56 if($this->getOption('reverse')) {
57 if(($end > M_PI * 0.5 && $end < M_PI * 1.5) ||
58 $start < M_PI * 0.5 || $start > M_PI * 1.5)
59 $this->setOption('draw_flat_sides', true);
60 } else {
61 if(($start > M_PI * 0.5 && $start < M_PI * 1.5) ||
62 $end < M_PI * 0.5 || $end > M_PI * 1.5)
63 $this->setOption('draw_flat_sides', true);
64 }
65 }
66 return PieGraph::draw();
67 }
68
69 /**
70 * Returns the SVG markup to draw all slices
71 */
72 protected function drawSlices($slice_list)
73 {
74 $edge_list = [];
75 foreach($slice_list as $key => $slice) {
76
77 $edges = $this->getEdges($slice);
78 if(!empty($edges))
79 $edge_list = array_merge($edge_list, $edges);
80 }
81
82 // should not be empty - that would mean no sides visible
83 if(empty($edge_list))
84 return parent::drawSlices($slice_list);
85
86 usort($edge_list, function($a, $b) {
87 if($a->y == $b->y)
88 return 0;
89 return ($a->y < $b->y ? -1 : 1);
90 });
91
92 $edges = [];
93 $overlay = is_array($this->getOption('depth_shade_gradient'));
94 foreach($edge_list as $edge) {
95
96 $edges[] = $this->getEdge($edge, $this->x_centre, $this->y_centre,
97 $this->depth, $overlay);
98 }
99
100 return implode($edges) . parent::drawSlices($slice_list);
101 }
102
103 /**
104 * Returns the edges for the slice that face outwards
105 */
106 protected function getEdges($slice)
107 {
108 $edges = $this->edge_class::getEdges($this, $slice, $this->s_angle,
109 $this->getOption('draw_flat_sides'));
110 return $edges;
111 }
112
113 /**
114 * Returns an edge markup
115 */
116 protected function getEdge($edge, $x_centre, $y_centre, $depth, $overlay)
117 {
118 $item = $edge->slice['item'];
119 $attr = [
120 'fill' => $this->getColour($item, $edge->slice['colour_index'],
121 $this->dataset, false, false),
122 'id' => $this->newID(),
123 ];
124 if($this->getOption('show_tooltips'))
125 $this->setTooltip($attr, $item, $this->dataset, $item->key, $item->value, true);
126 if($this->getOption('show_context_menu'))
127 $this->setContextMenu($attr, $this->dataset, $item, true);
128 $this->addLabelClient($this->dataset, $edge->slice['original_position'], $attr);
129
130 $content = '';
131
132 // the gradient overlay uses a clip-path
133 if($overlay) {
134 $clip_id = $this->newID();
135 $this->defs->add($edge->getClipPath($this, $x_centre, $y_centre, $depth,
136 $clip_id));
137
138 // fill without stroking
139 $attr['stroke'] = 'none';
140 $content = $edge->draw($this, $x_centre, $y_centre, $depth, $attr);
141
142 // overlay
143 $content .= $this->getEdgeOverlay($x_centre, $y_centre, $depth, $clip_id, $edge);
144
145 // stroke without filling
146 unset($attr['stroke']);
147 $attr['fill'] = 'none';
148 }
149 $content .= $edge->draw($this, $x_centre, $y_centre, $depth, $attr);
150 return $this->getLink($item, $item->key, $content);
151 }
152
153 /**
154 * Overlays the gradient on the pie sides
155 */
156 protected function pieExtras()
157 {
158 // removed the overlay code because it drew over the stroked edges -
159 // overlays are always drawn separately now
160 return '';
161 }
162
163 /**
164 * Returns the gradient overlay
165 */
166 protected function getEdgeOverlay($x_centre, $y_centre, $depth, $clip_path, $edge)
167 {
168 // use radius of whole pie unless slice values are set
169 $radius_x = $this->radius_x;
170 $radius_y = $this->radius_y;
171 if($edge->slice['radius_x'] && $edge->slice['radius_y']) {
172 $radius_x = $edge->slice['radius_x'];
173 $radius_y = $edge->slice['radius_y'];
174 }
175
176 // clip a rect to the edge shape
177 $rect = [
178 'x' => $x_centre - $radius_x,
179 'y' => $y_centre - $radius_y,
180 'width' => $radius_x * 2.0,
181 'height' => $radius_y * 2.0 + $this->depth + 2.0,
182 'clip-path' => 'url(#' . $clip_path . ')',
183 ];
184
185 $gradient_id = $this->defs->addGradient($this->getOption('depth_shade_gradient'));
186 if($edge->curve()) {
187 $rect['fill'] = 'url(#' . $gradient_id . ')';
188 } else {
189 $a = $edge->angle();
190 if($a > M_PI)
191 $a -= M_PI;
192
193 $pos = 50 * cos($a);
194 if($pos < 0)
195 $pos = 100 + $pos;
196
197 $fill = $this->defs->getGradientColour($gradient_id, $pos);
198 $opacity = $fill->opacity();
199
200 if($opacity < 0.01 || $fill->isNone())
201 return '';
202 if($opacity < 0.99)
203 $rect['opacity'] = $opacity;
204 $rect['fill'] = $fill;
205 }
206 return $this->element('rect', $rect);
207 }
208 }
209
210