EchantsHelper.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <?php
  2. namespace common\helpers;
  3. use Yii;
  4. /**
  5. * 图表辅助类
  6. *
  7. * Class EchantsHelper
  8. * @package common\helpers
  9. * @author jianyan74 <751393839@qq.com>
  10. */
  11. class EchantsHelper
  12. {
  13. /**
  14. * 通用格式化日期匹配
  15. *
  16. * @var array
  17. */
  18. protected static $formats = [
  19. 'minute' => [
  20. 'default' => 'Y-n-d H:i',
  21. 'sql' => '%Y-%c-%d %H:%i',
  22. 'view' => 'd H:i',
  23. ],
  24. 'hour' => [
  25. 'default' => 'Y-n-d H:00',
  26. 'sql' => '%Y-%c-%d %H:00',
  27. 'view' => 'H:00',
  28. ],
  29. 'week' => [
  30. 'default' => 'Y-n-d',
  31. 'sql' => '%Y-%c-%d',
  32. 'view' => 'Y-n-d',
  33. ],
  34. 'day' => [
  35. 'default' => 'Y-n-d',
  36. 'sql' => '%Y-%c-%d',
  37. 'view' => 'Y-n-d',
  38. ],
  39. 'month' => [
  40. 'default' => 'Y-n',
  41. 'sql' => '%Y-%c',
  42. 'view' => 'Y-m',
  43. ],
  44. 'year' => [
  45. 'default' => 'Y',
  46. 'sql' => '%Y',
  47. 'view' => 'Y',
  48. ],
  49. ];
  50. /**
  51. * 根据类型快速获取时间区间和格式
  52. *
  53. * @param $type
  54. * @param array $betweenTime
  55. * @return array
  56. */
  57. public static function getFormatTime($type, $start_time = '', $end_time = '')
  58. {
  59. switch ($type) {
  60. case 'yesterday' :
  61. list($time, $format) = [DateHelper::yesterday(), 'hour'];
  62. break;
  63. case 'thisWeek' :
  64. list($time, $format) = [DateHelper::thisWeek(), 'week'];
  65. break;
  66. case 'thisMonth' :
  67. list($time, $format) = [DateHelper::thisMonth(), 'day'];
  68. break;
  69. case 'thisYear' :
  70. list($time, $format) = [DateHelper::aYear(date('Y')), 'month'];
  71. break;
  72. case 'this30Day' :
  73. list($time, $format) = [['start' => time() - 60 * 60 * 24 * 30, 'end' => time()], 'day'];
  74. break;
  75. case 'this7Day' :
  76. list($time, $format) = [['start' => time() - 60 * 60 * 24 * 7, 'end' => time()], 'week'];
  77. break;
  78. case 'lastYear' :
  79. list($time, $format) = [DateHelper::aYear(date('Y') - 1), 'month'];
  80. break;
  81. case 'betweenHour' :
  82. list($time, $format) = [['start' => $start_time, 'end' => $end_time], 'hour'];
  83. break;
  84. case 'betweenDay' :
  85. list($time, $format) = [['start' => $start_time, 'end' => $end_time], 'day'];
  86. break;
  87. case 'betweenMonth' :
  88. list($time, $format) = [['start' => $start_time, 'end' => $end_time], 'month'];
  89. break;
  90. case 'betweenYear' :
  91. list($time, $format) = [['start' => $start_time, 'end' => $end_time], 'year'];
  92. break;
  93. case 'customData' :
  94. $end = strtotime(Yii::$app->request->get('echarts_end')) + 60 * 60 * 24 - 1;
  95. list($time, $format) = [['start' => strtotime(Yii::$app->request->get('echarts_start')), 'end' => $end], 'day'];
  96. break;
  97. case 'all' :
  98. list($time, $format) = [['start' => $start_time, 'end' => $end_time], ''];
  99. break;
  100. default :
  101. // 默认今天
  102. list($time, $format) = [DateHelper::today(), 'hour'];
  103. break;
  104. }
  105. return [$time, $format];
  106. }
  107. /**
  108. * 折线 柱状 获取区间统计
  109. *
  110. * $fields = [
  111. * 'count' => '订单笔数',
  112. * 'product_count' => '产品数量',
  113. * ];
  114. *
  115. * @param $function
  116. * @param array $fields 字段数组
  117. * @param array $time
  118. * @param string $format
  119. * @param string $distinguishKey 时间字段名称
  120. * @return array
  121. */
  122. public static function lineOrBarInTime(
  123. $function,
  124. array $fields,
  125. array $time,
  126. $format = 'day',
  127. $distinguishKey = 'time',
  128. $eChartType = 'line'
  129. ) {
  130. $data = call_user_func($function, $time['start'], $time['end'], self::$formats[$format]['sql']);
  131. // 对比key
  132. $data = ArrayHelper::arrayKey($data, $distinguishKey);
  133. // 递增时间
  134. $all = self::progressiveIncreaseTime($time['start'], $time['end'], $format);
  135. // 默认数据
  136. $seriesData = [];
  137. foreach ($fields as $field => &$value) {
  138. if (is_array($value)) {
  139. $value['data'] = [];
  140. $seriesData[] = $value;
  141. } else {
  142. $seriesData[] = [
  143. 'field' => $field,
  144. 'name' => $value,
  145. 'type' => $eChartType,
  146. // 显示数量
  147. // 'label' => [
  148. // 'show' => true
  149. // ],
  150. // 'smooth' => 'true',
  151. 'data' => [],
  152. ];
  153. }
  154. }
  155. foreach ($all as &$item) {
  156. if (isset($data[$item])) {
  157. foreach ($seriesData as $key => &$value) {
  158. $field = $seriesData[$key]['field'];
  159. $value['data'][] = $data[$item][$field] ?? 0;
  160. }
  161. } else {
  162. foreach ($seriesData as $key => &$value) {
  163. $value['data'][] = 0;
  164. }
  165. }
  166. // 格式化页面显示
  167. if ($format == 'week') {
  168. $item .= '(' . DateHelper::getWeekName(strtotime($item)) . ')';
  169. } else {
  170. $item = date(self::$formats[$format]['view'], strtotime($item));
  171. }
  172. }
  173. return [
  174. 'xAxisData' => $all,
  175. 'seriesData' => $seriesData,
  176. 'fieldsName' => array_values($fields),
  177. ];
  178. }
  179. /**
  180. * 饼图
  181. *
  182. * @param $function
  183. * @param array $time
  184. * @param array $defaultSeries
  185. * @return array
  186. */
  187. public static function pie($function, array $time, $defaultSeries = [])
  188. {
  189. list($data, $fields) = call_user_func($function, $time['start'], $time['end']);
  190. // 重组增加默认数据
  191. $seriesData = [];
  192. $seriesData[] = ArrayHelper::merge([
  193. 'name' => '',
  194. 'type' => 'pie',
  195. 'radius' => '55%',
  196. 'center' => ['50%', '50%'],
  197. 'data' => [],
  198. 'itemStyle' => [
  199. 'emphasis' => [
  200. 'shadowBlur' => 10,
  201. 'shadowOffsetX' => 0,
  202. 'shadowColor' => 'rgba(0, 0, 0, 0.5)',
  203. ]
  204. ]
  205. ], $defaultSeries);
  206. if (empty($data)) {
  207. $data = [
  208. [
  209. 'name' => '暂无数据',
  210. 'value' => 0
  211. ]
  212. ];
  213. }
  214. $seriesData[0]['data'] = $data;
  215. return [
  216. 'seriesData' => $seriesData,
  217. 'fieldsName' => $fields,
  218. ];
  219. }
  220. /**
  221. * 饼图
  222. *
  223. * @param $function
  224. * @param array $time
  225. * @param array $defaultSeries
  226. * @return array
  227. */
  228. public static function lineGraphic($function, array $time, $defaultSeries = [])
  229. {
  230. list($data, $fields) = call_user_func($function, $time['start'], $time['end']);
  231. // 重组增加默认数据
  232. $seriesData = [];
  233. $seriesData[] = ArrayHelper::merge([
  234. 'name' => '',
  235. 'type' => 'bar',
  236. 'smooth' => true,
  237. 'barCategoryGap' => 25,
  238. 'data' => [],
  239. 'lineStyle' => [
  240. 'normal' => [
  241. 'width' => 3,
  242. 'shadowBlur' => 10,
  243. 'shadowOffsetY' => 10,
  244. 'shadowColor' => 'rgba(0, 0, 0, 0.5)',
  245. ]
  246. ]
  247. ], $defaultSeries);
  248. if (empty($data)) {
  249. $data = [0];
  250. }
  251. $seriesData[0]['data'] = $data;
  252. return [
  253. 'seriesData' => $seriesData,
  254. 'fieldsName' => $fields,
  255. ];
  256. }
  257. /**
  258. * 字符云
  259. *
  260. * @param $function
  261. * @param array $time
  262. * @param array $defaultSeries
  263. * @return array
  264. */
  265. public static function wordCloud($function, array $time)
  266. {
  267. $data = call_user_func($function, $time['start'], $time['end']);
  268. empty($data) && $data = [
  269. [
  270. 'name' => '暂无数据',
  271. 'value' => 0,
  272. ]
  273. ];
  274. return [
  275. 'seriesData' => $data,
  276. 'fieldsName' => [],
  277. ];
  278. }
  279. /**
  280. * 重组数据 - 主要用户多此分组
  281. *
  282. * @param array $statData
  283. * @param $field
  284. * @param string $distinguishKey
  285. * @param string $sumKey
  286. * @return array
  287. */
  288. public static function regroupTimeData(array $statData, $field, $distinguishKey = 'time', $sumKey = 'count')
  289. {
  290. $resData = [];
  291. foreach ($statData as $statDatum) {
  292. $key = $statDatum[$distinguishKey];
  293. if (!isset($resData[$key])) {
  294. $resData[$key] = [
  295. $distinguishKey => $statDatum[$distinguishKey],
  296. $statDatum[$field] => $statDatum[$sumKey],
  297. ];
  298. } else {
  299. $fieldKey = $statDatum[$field];
  300. if (!isset($resData[$key][$fieldKey])) {
  301. $resData[$key][$fieldKey] = $statDatum[$sumKey];
  302. } else {
  303. $resData[$key][$fieldKey] += $statDatum[$sumKey];
  304. }
  305. }
  306. }
  307. return $resData;
  308. }
  309. /**
  310. * 获取递增时间区间
  311. *
  312. * @param $start_time
  313. * @param $end_time
  314. * @param $type
  315. * @return array
  316. */
  317. protected static function progressiveIncreaseTime($start_time, $end_time, $type)
  318. {
  319. $type == 'week' && $type = 'day';
  320. // 获取格式化
  321. $dateformat = self::$formats[$type]['default'];
  322. $startTime = strtotime(date($dateformat, $start_time));
  323. $endTime = strtotime(date($dateformat, $end_time));
  324. // 取得递增
  325. $all = [];
  326. $all[] = date($dateformat, $start_time);
  327. while (($startTime = strtotime("+1 $type", $startTime)) <= $endTime) {
  328. $all[] = date($dateformat, $startTime);
  329. }
  330. return $all;
  331. }
  332. }
粤ICP备19079148号