Chart.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. <?php
  2. namespace Dcat\Admin\Widgets\ApexCharts;
  3. use Dcat\Admin\Support\Helper;
  4. use Dcat\Admin\Traits\FromApi;
  5. use Dcat\Admin\Widgets\Widget;
  6. use Illuminate\Support\Str;
  7. class Chart extends Widget
  8. {
  9. use FromApi;
  10. public static $js = '@apex-charts';
  11. protected $containerSelector;
  12. protected $options = [];
  13. protected $built = false;
  14. protected $scripts = [
  15. 'extend' => 'return options',
  16. ];
  17. public function __construct($containerSelector = null, $options = [])
  18. {
  19. if ($containerSelector && ! is_string($containerSelector)) {
  20. $options = $containerSelector;
  21. $containerSelector = null;
  22. }
  23. $this->selector($containerSelector);
  24. $this->options($options);
  25. }
  26. /**
  27. * 设置或获取图表容器选择器
  28. *
  29. * @param string|null $selector
  30. *
  31. * @return $this|string|null
  32. */
  33. public function selector(?string $selector = null)
  34. {
  35. if ($selector === null) {
  36. return $this->containerSelector;
  37. }
  38. $this->containerSelector = $selector;
  39. if ($selector && ! $this->built) {
  40. $this->autoRender();
  41. }
  42. return $this;
  43. }
  44. /**
  45. * @param string|array $title
  46. *
  47. * @return $this
  48. */
  49. public function title($title)
  50. {
  51. if (is_string($title)) {
  52. $options = ['text' => $title];
  53. } else {
  54. $options = Helper::array($title);
  55. }
  56. $this->options['title'] = $options;
  57. return $this;
  58. }
  59. /**
  60. * @param array $series
  61. *
  62. * @return $this
  63. */
  64. public function series($series)
  65. {
  66. $this->options['series'] = Helper::array($series);
  67. return $this;
  68. }
  69. /**
  70. * @param array $value
  71. *
  72. * @return $this
  73. */
  74. public function labels($value)
  75. {
  76. $this->options['labels'] = Helper::array($value);
  77. return $this;
  78. }
  79. /**
  80. * @param string|array $colors
  81. *
  82. * @return $this
  83. */
  84. public function colors($colors)
  85. {
  86. $this->options['colors'] = Helper::array($colors);
  87. return $this;
  88. }
  89. /**
  90. * @param array $value
  91. *
  92. * @return $this
  93. */
  94. public function stroke($value)
  95. {
  96. $this->options['stroke'] = Helper::array($value);
  97. return $this;
  98. }
  99. /**
  100. * @param array $value
  101. *
  102. * @return $this
  103. */
  104. public function xaxis($value)
  105. {
  106. $this->options['xaxis'] = Helper::array($value);
  107. return $this;
  108. }
  109. /**
  110. * @param array $value
  111. *
  112. * @return $this
  113. */
  114. public function tooltip($value)
  115. {
  116. $this->options['tooltip'] = Helper::array($value);
  117. return $this;
  118. }
  119. /**
  120. * @param array $value
  121. *
  122. * @return $this
  123. */
  124. public function yaxis($value)
  125. {
  126. $this->options['yaxis'] = Helper::array($value);
  127. return $this;
  128. }
  129. /**
  130. * @param array $value
  131. *
  132. * @return $this
  133. */
  134. public function fill($value)
  135. {
  136. $this->options['fill'] = Helper::array($value);
  137. return $this;
  138. }
  139. /**
  140. * @param array $value
  141. *
  142. * @return $this
  143. */
  144. public function chart($value)
  145. {
  146. $this->options['chart'] = Helper::array($value);
  147. return $this;
  148. }
  149. /**
  150. * @param array|bool $value
  151. *
  152. * @return $this
  153. */
  154. public function dataLabels($value)
  155. {
  156. if (is_bool($value)) {
  157. $value = ['enabled' => $value];
  158. }
  159. $this->options['dataLabels'] = Helper::array($value);
  160. return $this;
  161. }
  162. /**
  163. * @param string|\Closure $script
  164. *
  165. * @return $this
  166. */
  167. public function extendOptions($script)
  168. {
  169. $this->scripts['extend'] = value($script);
  170. return $this;
  171. }
  172. /**
  173. * @param string $options
  174. *
  175. * @return string
  176. */
  177. protected function buildDefaultScript($options)
  178. {
  179. return <<<JS
  180. (function () {
  181. var options = {$options}, extend = function (options) {
  182. {$this->scripts['extend']}
  183. };
  184. var chart = new ApexCharts(
  185. $("{$this->containerSelector}")[0],
  186. $.extend(options, extend(options))
  187. );
  188. chart.render();
  189. })();
  190. JS;
  191. }
  192. /**
  193. * @return string
  194. */
  195. public function script()
  196. {
  197. $options = json_encode($this->options);
  198. if (! $this->allowBuildRequest()) {
  199. return $this->buildDefaultScript($options);
  200. }
  201. $this->fetched(
  202. <<<JS
  203. if (! response.status) {
  204. return Dcat.error(response.message || 'Server internal error.');
  205. }
  206. var container = $('{$this->containerSelector}');
  207. container.html('');
  208. setTimeout(function () {
  209. var chart = new ApexCharts(container[0], response.options);
  210. chart.render();
  211. }, 50);
  212. JS
  213. );
  214. return $this->buildRequestScript();
  215. }
  216. /**
  217. * @return string
  218. */
  219. public function render()
  220. {
  221. if ($this->built) {
  222. return;
  223. }
  224. $this->built = true;
  225. $hasSelector = $this->containerSelector ? true : false;
  226. if (! $hasSelector) {
  227. $id = $this->generateId();
  228. $this->selector('#'.$id);
  229. }
  230. $this->script = $this->script();
  231. $this->collectAssets();
  232. if ($hasSelector) {
  233. return;
  234. }
  235. // 没有指定容器选择器,则需自动生成
  236. $this->setHtmlAttribute([
  237. 'id' => $id,
  238. ]);
  239. return <<<HTML
  240. <div {$this->formatHtmlAttributes()}></div>
  241. HTML;
  242. }
  243. /**
  244. * 返回请求结果.
  245. *
  246. * @return array
  247. */
  248. public function result()
  249. {
  250. return [
  251. 'status' => 1,
  252. 'options' => $this->options,
  253. ];
  254. }
  255. protected function generateId()
  256. {
  257. return 'apex-chart-'.Str::random(8);
  258. }
  259. }