PluginProbe
E2Pdf – Export Pdf Tool for WordPress / 1.32.22
E2Pdf – Export Pdf Tool for WordPress v1.32.22
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 / StackedGroupedBarTrait.php

StackedGroupedBarTrait.php in E2Pdf – Export Pdf Tool for WordPress 1.32.22, at vendors/svggraph/StackedGroupedBarTrait.php

255 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Copyright (C) 2019-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 StackedGroupedBarTrait {
25
26 use GroupedBarTrait;
27
28 // stores the actual group starts
29 protected $groups = [];
30
31 // stores the group each dataset is within
32 protected $dataset_groups = [];
33
34 protected function drawBars()
35 {
36 $this->barSetup();
37 $group_count = count($this->groups);
38 $bar_count = count($this->multi_graph);
39
40 $bars = '';
41 $legend_entries = [];
42 $datasets = $this->multi_graph->getEnabledDatasets();
43 foreach($this->multi_graph as $bnum => $itemlist) {
44 $item = $itemlist[0];
45 $k = $item->key;
46 $bar_pos = $this->gridPosition($item, $bnum);
47
48 if($bar_pos !== null) {
49
50 for($l = 0; $l < $group_count; ++$l) {
51 $start_bar = $this->groups[$l];
52 $end_bar = isset($this->groups[$l + 1]) ? $this->groups[$l + 1] : $bar_count;
53 $ypos = $yneg = 0;
54
55 // stack the bars in order they must be drawn
56 $stack = [];
57 for($j = $start_bar; $j < $end_bar; ++$j) {
58 if(!in_array($j, $datasets))
59 continue;
60 $item = $itemlist[$j];
61 if($item->value !== null) {
62 if($item->value < 0) {
63 array_unshift($stack, [$j, $yneg]);
64 $yneg += $item->value;
65 continue;
66 }
67 $stack[] = [$j, $ypos];
68 $ypos += $item->value;
69 }
70 }
71
72 $stack_last = count($stack) - 1;
73 $top_dataset = 0;
74 foreach($stack as $b => $stack_bar) {
75 list($j, $start) = $stack_bar;
76 $item = $itemlist[$j];
77 $top = ($b == $stack_last);
78 if($top)
79 $top_dataset = $j;
80 $this->setBarVisibility($j, $item, $top);
81 $bars .= $this->drawBar($item, $bnum, $start, null, $j, ['top' => $top]);
82 $legend_entries[$j][$bnum] = $item;
83 }
84 $this->barTotals($item, $bnum, $ypos, $yneg, $top_dataset);
85 }
86 }
87 }
88
89 foreach($legend_entries as $j => $dataset)
90 foreach($dataset as $bnum => $item)
91 $this->setBarLegendEntry($j, $bnum, $item);
92
93 return $bars;
94 }
95
96 /**
97 * Sets up bar details
98 */
99 protected function barSetup()
100 {
101 parent::barSetup();
102 $group_count = count($this->groups);
103 $chunk_count = count($this->multi_graph);
104 list($group_width, $bspace, $group_unit_width) =
105 $this->barPosition($this->getOption('bar_width'),
106 $this->getOption('bar_width_min'),
107 $this->x_axes[$this->main_x_axis]->unit(), $group_count,
108 $this->getOption('bar_space'), $this->getOption('group_space'));
109 $this->group_bar_spacing = $group_unit_width;
110 $this->setBarWidth($group_width, $bspace);
111 }
112
113 /**
114 * Fills in the x and width of bar
115 */
116 protected function barX($item, $index, &$bar, $axis, $dataset)
117 {
118 $bar_x = $this->gridPosition($item, $index);
119 if($bar_x === null)
120 return null;
121
122 $group = $this->dataset_groups[$dataset];
123 $bar['x'] = $bar_x + $this->calculated_bar_space +
124 ($group * $this->group_bar_spacing);
125 $bar['width'] = $this->calculated_bar_width;
126 return $bar_x;
127 }
128
129 /**
130 * Check that the required options are set and match the data
131 */
132 protected function checkValues()
133 {
134 parent::checkValues();
135 $stack_group = $this->getOption('stack_group');
136 if(empty($stack_group))
137 throw new \Exception('stack_group not set');
138
139 // make sure the group details are stored in an array
140 if(!is_array($stack_group))
141 $stack_group = [$stack_group];
142
143 // make the list of groups
144 $datasets = count($this->multi_graph);
145 $groups = [0]; // first starts at 0, obviously
146 $dataset_groups = array_fill(0, $datasets, 0);
147
148 $last_start = 0;
149 foreach($stack_group as $key => $group_start) {
150 if($group_start <= $last_start)
151 throw new \Exception('Invalid stack_group option');
152 if($group_start < $datasets)
153 $groups[] = $group_start;
154 $last_start = $group_start;
155 for($d = $group_start; $d < $datasets; ++$d) {
156 $dataset_groups[$d] = $key + 1;
157 }
158 }
159
160 // without this check there will be an invalid axis error
161 if(count($groups) == 1)
162 throw new \Exception('Too few datasets for grouping');
163
164 // check disabled datasets
165 $datasets = $this->multi_graph->getEnabledDatasets();
166 $cleaned_dg = [];
167 foreach($dataset_groups as $d => $g) {
168 if(in_array($d, $datasets))
169 $cleaned_dg[$d] = $g;
170 }
171
172 // check for unused groups
173 $u = array_unique($cleaned_dg);
174 if(count($u) < count($groups))
175 throw new \Exception('Disabled datasets prevent grouping');
176
177 $this->groups = $groups;
178 $this->dataset_groups = $cleaned_dg;
179 }
180
181 /**
182 * Returns the maximum (stacked) value
183 */
184 public function getMaxValue()
185 {
186 $max = null;
187 $values = &$this->multi_graph->getValues();
188 $datasets = $this->multi_graph->getEnabledDatasets();
189
190 // find the max for each group from the MultiGraph's structured data
191 for($i = 0; $i < count($this->groups); ++$i) {
192 $start = $this->groups[$i];
193 $end = isset($this->groups[$i + 1]) ? $this->groups[$i + 1] - 1 :
194 count($this->multi_graph) - 1;
195
196 $stack = [];
197 for($j = $start; $j <= $end; ++$j)
198 if(in_array($j, $datasets))
199 $stack[] = $j;
200
201 list($junk, $group_max) = $values->getMinMaxSumValuesFor($stack);
202
203 if($max === null || $group_max > $max)
204 $max = $group_max;
205 }
206 return $max;
207 }
208
209 /**
210 * Returns the minimum (stacked) value
211 */
212 public function getMinValue()
213 {
214 $min = null;
215 $values = &$this->multi_graph->getValues();
216 $datasets = $this->multi_graph->getEnabledDatasets();
217
218 // find the min for each group from the MultiGraph's structured data
219 for($i = 0; $i < count($this->groups); ++$i) {
220 $start = $this->groups[$i];
221 $end = isset($this->groups[$i + 1]) ? $this->groups[$i + 1] - 1 :
222 count($this->multi_graph) - 1;
223
224 $stack = [];
225 for($j = $start; $j <= $end; ++$j)
226 if(in_array($j, $datasets))
227 $stack[] = $j;
228
229 list($group_min) = $values->getMinMaxSumValuesFor($stack);
230
231 if($min === null || $group_min < $min)
232 $min = $group_min;
233 }
234 return $min;
235 }
236
237 /**
238 * Returns the order that the bar datasets appear in
239 */
240 public function getLegendOrder()
241 {
242 $groups = [];
243 foreach($this->dataset_groups as $d => $g)
244 $groups[$g][] = $d;
245
246 // order is down stack, then left to right in groups
247 $order = [];
248 foreach($groups as $g => $d)
249 foreach(array_reverse($d) as $e)
250 $order[] = $e;
251 return $order;
252 }
253 }
254
255