PageRenderTime 56ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/resources/php/qnet/controller/statisticsGraphicsController.php

http://qnet-ua2011.googlecode.com/
PHP | 296 lines | 263 code | 33 blank | 0 comment | 63 complexity | 627ef97402e69e939de3fe80a5e934cd MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. namespace Qnet\Controller;
  3. require_once dirname(__FILE__) . '\..\util.php';
  4. require_dao('queryDAO');
  5. require_dao('userDAO');
  6. require_dao('answersDAO');
  7. require_dao('statisticsDAO');
  8. require_model('User');
  9. use Qnet\Dao\QueryDAO;
  10. use Qnet\Dao\UserDAO;
  11. use Qnet\Dao\AnswersDAO;
  12. use Qnet\Dao\StatisticsDAO;
  13. use Qnet\Model\User;
  14. class StatisticsGraphicsController {
  15. private $udao;
  16. private $adao;
  17. private $qdao;
  18. private $sdao;
  19. private $cardinality;
  20. private $varAxisMap;
  21. private $qid;
  22. private $drawable = true;
  23. private $series;
  24. function __construct() {
  25. $this->udao = new UserDAO();
  26. $this->qdao = new QueryDAO();
  27. $this->sdao = new StatisticsDAO();
  28. $this->adao = new AnswersDAO();
  29. }
  30. function computeStatistic($sid) {
  31. $this->sdao->setCurrentStatistic($sid);
  32. $this->computeVarsCardinality();
  33. $this->mapVarsToAxises();
  34. if(!$this->drawable) { return; }
  35. $this->qid = $this->sdao->getQid();
  36. $answers = $this->adao->selectAnswersByQueryId($this->qid);
  37. $classified = array();
  38. foreach($answers as $ix => $aid) {
  39. $classified[$ix] = array();
  40. for($var = 0; $var < $this->varsCount(); $var++) {
  41. $classified[$ix][$var] = $this->classify($aid, $var);
  42. }
  43. }
  44. $totals = $this->computeTotals($classified);
  45. $this->toPercentages($totals, count($answers));
  46. $this->generateSeries($totals);
  47. }
  48. private function generateSeries($totals) {
  49. $zCount = $this->hasZ() ? $this->cardinality[$this->varAxisMap['z']] : 1;
  50. $xCount = $this->hasX() ?
  51. $this->cardinality[$this->varAxisMap['x']] :
  52. $this->cardinality[$this->varAxisMap['u']] * $this->cardinality[$this->varAxisMap['v']];
  53. $this->series = array();
  54. for($z = 0; $z < $zCount; $z++) {
  55. $this->series[$z] = array();
  56. for($x = 0; $x < $xCount; $x++) {
  57. $val = $this->getSeriesValue($z, $x, $totals);
  58. $lx = $this->getLabelForX($x);
  59. $this->series[$z][$lx] = $val;
  60. }
  61. }
  62. }
  63. private function getLabelForX($x){
  64. if($this->hasX()) {
  65. $var = $this->varAxisMap['x'];
  66. return $this->getVarLabel($var, $x);
  67. } else {
  68. $u = $this->varAxisMap['u'];
  69. $v = $this->varAxisMap['v'];
  70. $ul = $this->getVarLabel($u, floor($x / $this->cardinality[$v]));
  71. $vl = $this->getVarLabel($v, $x % $this->cardinality[$v]);
  72. return $ul . "/" . $vl;
  73. }
  74. }
  75. private function getVarLabel($var, $x) {
  76. if($this->sdao->getVarType($var) == "uVar") {
  77. $varValue = $this->sdao->getVarValue($var);
  78. return User::propertyValueAt($varValue, $x);
  79. } else {
  80. $qid = $this->sdao->getVarValue($var);
  81. return $this->adao->getOptionName($qid, $x + 1);
  82. }
  83. }
  84. private function getSeriesValue($z, $x, $totals) {
  85. switch ($this->varsCount()) {
  86. case 1: // X, !Z // => $z = 0
  87. return $totals[$x];
  88. case 2:
  89. if($this->hasX()) { // X, Z
  90. $zero = $this->varAxisMap['x'] == 0 ? $x : $z;
  91. $one = $this->varAxisMap['z'] == 0 ? $x : $z;
  92. return $totals[$zero][$one];
  93. } else { // !X, !Z // => $z = 0
  94. $v = $this->varAxisMap['v'];
  95. $uIx = floor($x / $this->cardinality[$v]);
  96. $vIx = $x % $this->cardinality[$v];
  97. $zero = $this->varAxisMap['u'] == 0 ? $uIx : $vIx;
  98. $one = $this->varAxisMap['u'] == 1 ? $uIx : $vIx;
  99. return $totals[$zero][$one];
  100. }
  101. case 3: // !X, Z
  102. $v = $this->varAxisMap['v'];
  103. $uIx = floor($x / $this->cardinality[$v]);
  104. $vIx = $x % $this->cardinality[$v];
  105. $zero = $this->varAxisMap['u'] < $this->varAxisMap['v'] ? $uIx : $vIx;
  106. $one = $this->varAxisMap['u'] > $this->varAxisMap['v'] ? $uIx : $vIx;
  107. switch ($this->varAxisMap['z']) {
  108. case 0: return $totals[$z][$zero][$one];
  109. case 1: return $totals[$zero][$z][$one];
  110. case 2: return $totals[$zero][$one][$z];
  111. }
  112. }
  113. }
  114. public function getData($series) {
  115. if($series >= count($this->series)) {
  116. return '';
  117. } else {
  118. return $this->series[$series];
  119. }
  120. }
  121. public function isDrawable() {
  122. return $this->drawable;
  123. }
  124. private function computeVarsCardinality() {
  125. $this->cardinality = array();
  126. $vars = $this->sdao->getVarsQty();
  127. for($i = 0; $i < $vars; $i++) {
  128. $cardinality = 0;
  129. if($this->sdao->getVarType($i) == "uVar") {
  130. $cardinality = User::getPropertyCardinality($this->sdao->getVarValue($i));
  131. } else if($this->sdao->getVarType($i) == "qVar") {
  132. $cardinality = $this->computeQVarCardinality($this->sdao->getVarValue($i));
  133. }
  134. $this->cardinality[$i] = $cardinality;
  135. }
  136. }
  137. private function classify($aid, $var) {
  138. if($this->sdao->getVarType($var) == "uVar"){
  139. $uid = $this->adao->getUserByAnswersId($aid);
  140. $user = $this->udao->selectUserById($uid);
  141. $varValue = $this->sdao->getVarValue($var);
  142. return User::indexOfUserValue($varValue, $user);
  143. } else {
  144. $qid = $this->sdao->getVarValue($var);
  145. $qmap = $this->adao->getOptionsMap($qid);
  146. $ansOpt = $this->adao->getAswersOptionsMap($aid);
  147. foreach($qmap as $oid => $number) {
  148. foreach($ansOpt as $ansOid) {
  149. if($oid == $ansOid) {
  150. return $number - 1;
  151. }
  152. }
  153. }
  154. }
  155. }
  156. public function getLegend($series) {
  157. $zLegend = $this->legendFor($this->varAxisMap['z']);
  158. return $zLegend[$series];
  159. }
  160. public function legendFor($var) {
  161. if($this->sdao->getVarType($var) == "uVar") {
  162. return User::propertyValues($this->sdao->getVarValue($var));
  163. } else if($this->sdao->getVarType($var) == "qVar") {
  164. return $this->adao->getOptionNames($this->sdao->getVarValue($var));
  165. }
  166. }
  167. private function computeQVarCardinality($qid) {
  168. return count($this->qdao->getOptionsByQuestionId($qid));
  169. }
  170. private function mapVarsToAxises() {
  171. $this->drawable = true;
  172. $this->varAxisMap = array(); // U x V | Z // U x V en el eje X, los valores, en el eje Y.
  173. if($this->varsCount() > 1) {
  174. $minCard = $this->cardinality[0];
  175. $minAxis = 0;
  176. for($i = 1; $i < count($this->cardinality); $i++) {
  177. if($this->cardinality[$i] < $minCard) {
  178. $minCard = $this->cardinality[$i];
  179. $minAxis = $i;
  180. }
  181. }
  182. if($this->varsCount() > 2) {
  183. if($minCard > 5) {
  184. $this->drawable = false;
  185. return;
  186. }
  187. $this->varAxisMap['z'] = $minAxis;
  188. $this->varAxisMap['u'] = $minAxis != 0 ? 0 : 2;
  189. $this->varAxisMap['v'] = $minAxis != 1 ? 1 : 2;
  190. } else {
  191. if($minCard > 5) {
  192. $this->varAxisMap['u'] = $minAxis;
  193. $this->varAxisMap['v'] = $minAxis == 0 ? 1 : 0;
  194. } else {
  195. $this->varAxisMap['z'] = $minAxis;
  196. $this->varAxisMap['x'] = $minAxis == 0 ? 1 : 0;
  197. }
  198. }
  199. } else {
  200. $this->varAxisMap['x'] = 0;
  201. }
  202. }
  203. private function varsCount() {
  204. return count($this->cardinality);
  205. }
  206. private function hasX() { // or has U and V.
  207. return array_key_exists('x', $this->varAxisMap);
  208. }
  209. public function hasZ() { // or not.
  210. return array_key_exists('z', $this->varAxisMap);
  211. }
  212. private function computeTotals($classified) {
  213. $totals = array();
  214. for($i = 0; $i < $this->cardinality[0]; $i++) {
  215. if($this->varsCount() > 1) {
  216. $totals[$i] = array();
  217. for($j = 0; $j < $this->cardinality[1]; $j++) {
  218. if($this->varsCount() > 2) {
  219. $totals[$i][$j] = array();
  220. for($k = 0; $k < $this->cardinality[2]; $k++) {
  221. $totals[$i][$j][$k] = 0;
  222. }
  223. } else {
  224. $totals[$i][$j] = 0;
  225. }
  226. }
  227. } else {
  228. $totals[$i] = 0;
  229. }
  230. }
  231. foreach(array_values($classified) as $map) { //$var => $opt
  232. switch ($this->varsCount()) {
  233. case 1:
  234. $totals[$map[0]]++;
  235. break;
  236. case 2:
  237. $totals[$map[0]][$map[1]]++;
  238. break;
  239. case 3:
  240. $totals[$map[0]][$map[1]][$map[2]]++;
  241. break;
  242. }
  243. }
  244. return $totals;
  245. }
  246. private function toPercentages($totals, $count) {
  247. for($i = 0; $i < $this->cardinality[0]; $i++) {
  248. if($this->varsCount() > 1) {
  249. for($j = 0; $j < $this->cardinality[1]; $j++) {
  250. if($this->varsCount() > 2) {
  251. for($k = 0; $k < $this->cardinality[2]; $k++) {
  252. $totals[$i][$j][$k] = number_format($totals[$i][$j][$k] / $count, 2);
  253. }
  254. } else {
  255. $totals[$i][$j] = number_format($totals[$i][$j] / $count, 2);
  256. }
  257. }
  258. } else {
  259. $totals[$i] = number_format($totals[$i] / $count, 2);
  260. }
  261. }
  262. }
  263. }