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

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

225 lines 5.9 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-2020 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 ArrayGraph extends Graph {
25
26 use MultiGraphTrait {
27 values as mgValues;
28 }
29
30 protected $inner_options;
31 protected $inner_types;
32 protected $raw_data;
33 protected $raw_settings;
34
35 public function __construct($w, $h, array $settings, array $fixed_settings = [])
36 {
37 $this->raw_settings = $settings;
38 parent::__construct($w, $h, $settings, $fixed_settings);
39 }
40
41 /**
42 * Stores raw values to make it easier to set up subgraphs
43 */
44 public function values($values)
45 {
46 $this->raw_data = $values;
47 return $this->mgValues($values);
48 }
49
50 /**
51 * Now create the subgraphs
52 */
53 public function checkValues()
54 {
55 parent::checkValues();
56 $opt = [
57 'keep_colour_order' => true,
58 'back_stroke_width' => 0,
59 'back_colour' => 'none',
60 'back_shadow' => 0,
61 'title' => null,
62 ];
63 $opt = array_merge($this->raw_settings, $opt);
64
65 $graphs = $this->getLayout();
66 foreach($graphs as $graph) {
67 $s = new Subgraph($graph['type'], $graph['x'], $graph['y'],
68 $graph['w'], $graph['h'], array_merge($opt, $graph['options']));
69 $s->values($this->raw_data);
70 $s->setColours($this->colours);
71 $this->subgraphs[] = $s;
72 }
73 }
74
75 public function draw()
76 {
77 // all drawing is done by subgraphs
78 return $this->underShapes() . $this->overShapes();
79 }
80
81 /**
82 * Returns the list of graphs to be drawn and where to draw them
83 */
84 private function getLayout()
85 {
86 // find which datasets are going in each graph
87 $enabled_datasets = $this->multi_graph->getEnabledDatasets();
88 $graph_datasets = $this->getOption('array_graph_dataset');
89 if($graph_datasets === null) {
90
91 // default is one dataset per graph
92 $graph_datasets = [];
93 foreach($enabled_datasets as $d) {
94 $graph_datasets[] = [$d];
95 }
96 } else {
97
98 // need to check each of the selected datasets is enabled
99 $new_outer = [];
100 foreach($graph_datasets as $gd) {
101 $new_inner = [];
102 if(is_array($gd)) {
103 foreach($gd as $d) {
104 if(!in_array($d, $enabled_datasets))
105 continue;
106 $new_inner[] = $d;
107 }
108 } else {
109 if(!in_array($gd, $enabled_datasets))
110 continue;
111 $new_inner[] = $gd;
112 }
113
114 if(count($new_inner) > 0)
115 $new_outer[] = $new_inner;
116 }
117 $graph_datasets = $new_outer;
118 }
119
120 $graph_count = count($graph_datasets);
121 $cols = $this->getOption('array_graph_columns');
122 if($cols === null || $cols === 'auto') {
123 $cols = $this->calcCols($graph_count);
124 } else {
125 $cols = (int)$cols;
126 if($cols < 1)
127 throw new \Exception('Invalid array_graph_columns value: ' . $cols);
128 if($this->width / $cols < 20)
129 throw new \Exception('Option array_graph_columns too large: ' . $cols);
130 }
131 $rows = ceil($graph_count / $cols);
132 $w = $this->width / $cols;
133 $h = $this->height / $rows;
134
135 $inner_options = $this->getOption('array_graph_options');
136 if($inner_options !== null) {
137 if(!is_array($inner_options))
138 throw new \Exception('Option array_graph_options is not an array');
139
140 // check if it is an array of arrays
141 if(!isset($inner_options[0]) || !is_array($inner_options[0])) {
142
143 // put single array into outer array
144 $inner_options = [ $inner_options ];
145 }
146 } else {
147
148 // no special options
149 $inner_options = [ [ ] ];
150 }
151 $o_count = count($inner_options);
152
153 $index = 0;
154 $layout = [];
155 $last_row_count = $graph_count % $cols;
156 $last_row_offset = 0;
157 $align = $this->getOption('array_graph_align');
158 if($last_row_count && $align != 'left') {
159 $mult = $align == 'right' ? 1.0 : 0.5;
160 $last_row_offset = ($this->width - $last_row_count * $w) * $mult;
161 }
162
163 foreach($graph_datasets as $d) {
164 $col = $index % $cols;
165 $row = floor($index / $cols);
166 $x_offset = ($row == $rows - 1 ? $x_offset = $last_row_offset : 0);
167
168 $options = $inner_options[$index % $o_count];
169 $options['dataset'] = $d;
170
171 $g = [
172 'x' => $x_offset + $w * $col,
173 'y' => $h * $row,
174 'w' => $w,
175 'h' => $h,
176 'type' => $this->getOption(['array_graph_type', $index], ['@', 'PieGraph']),
177 'options' => $options,
178 ];
179
180 $layout[] = $g;
181 ++$index;
182 }
183
184 return $layout;
185 }
186
187 /**
188 * Calculates the best number of columns
189 */
190 private function calcCols($count)
191 {
192 if($count === 1)
193 return 1;
194
195 $w = $this->width;
196 $h = $this->height;
197 if($count === 2)
198 return $w > $h ? 2 : 1;
199
200 $matches = [];
201 for($c = 1; $c <= $count; ++$c) {
202 $r = ceil($count / $c);
203 $bw = $w / $c;
204 $bh = $h / $r;
205 $area = $bw * $bh;
206 $aspect = $bw < $bh ? $bw / $h : $bh / $bw;
207 $score = $area * ($aspect + 1);
208
209 $matches[] = [
210 'c' => $c,
211 'r' => $r,
212 'area' => $area,
213 'aspect' => $aspect,
214 'score' => $score,
215 ];
216 }
217
218 usort($matches, function($a, $b) { return $a['score'] - $b['score']; });
219 $winner = array_pop($matches);
220 return $winner['c'];
221 }
222
223 }
224
225