图表

Dcat Admin引入了apexcharts图表功能,通过Dcat\Admin\Widgets\ApexCharts\Chart这个类可以帮助开发者快速渲染图表。

简单用法

如果你需要构建一个图表,可以参考下面的方式

更多类型的图表,请参考apexcharts官方文档

  1. <?php
  2. namespace App\Admin\Widgets\Charts;
  3. use Dcat\Admin\Admin;
  4. use Dcat\Admin\Widgets\ApexCharts\Chart;
  5. class MyBar extends Chart
  6. {
  7. public function __construct($containerSelector = null, $options = [])
  8. {
  9. parent::__construct($containerSelector, $options);
  10. $this->setUpOptions();
  11. }
  12. /**
  13. * 初始化图表配置
  14. */
  15. protected function setUpOptions()
  16. {
  17. $color = Admin::color();
  18. $colors = [$color->primary(), $color->primaryDarker()];
  19. $this->options([
  20. 'colors' => $colors,
  21. 'chart' => [
  22. 'type' => 'bar',
  23. 'height' => 430
  24. ],
  25. 'plotOptions' => [
  26. 'bar' => [
  27. 'horizontal' => true,
  28. 'dataLabels' => [
  29. 'position' => 'top',
  30. ],
  31. ]
  32. ],
  33. 'dataLabels' => [
  34. 'enabled' => true,
  35. 'offsetX' => -6,
  36. 'style' => [
  37. 'fontSize' => '12px',
  38. 'colors' => ['#fff']
  39. ]
  40. ],
  41. 'stroke' => [
  42. 'show' => true,
  43. 'width' => 1,
  44. 'colors' => ['#fff']
  45. ],
  46. 'xaxis' => [
  47. 'categories' => [],
  48. ],
  49. ]);
  50. }
  51. /**
  52. * 处理图表数据
  53. */
  54. protected function buildData()
  55. {
  56. // 执行你的数据查询逻辑
  57. $data = [
  58. [
  59. 'data' => [44, 55, 41, 64, 22, 43, 21]
  60. ],
  61. [
  62. 'data' => [53, 32, 33, 52, 13, 44, 32]
  63. ]
  64. ];
  65. $categories = [2001, 2002, 2003, 2004, 2005, 2006, 2007];
  66. $this->withData($data);
  67. $this->withCategories($categories);
  68. }
  69. /**
  70. * 设置图表数据
  71. *
  72. * @param array $data
  73. *
  74. * @return $this
  75. */
  76. public function withData(array $data)
  77. {
  78. return $this->option('series', $data);
  79. }
  80. /**
  81. * 设置图表类别.
  82. *
  83. * @param array $data
  84. *
  85. * @return $this
  86. */
  87. public function withCategories(array $data)
  88. {
  89. return $this->option('xaxis.categories', $data);
  90. }
  91. /**
  92. * 渲染图表
  93. *
  94. * @return string
  95. */
  96. public function render()
  97. {
  98. $this->buildData();
  99. return parent::render();
  100. }
  101. }

使用

<?php

use App\Admin\Widgets\Charts\MyBar;
use Dcat\Admin\Widgets\Card;
use Dcat\Admin\Layout\Content;

class MyController
{
    public function index(Content $content)
    {
        return $content->body(
            Card::make('我的图表', MyBar::make())
        );
    }
}

效果
图表 - 图1

图表与后端API交互

如果你的图表需要与后端API交互,可以参考以下方式

为了方便阅读,这里的示例代码直接继承前面定义的MyBar类。

<?php

namespace App\Admin\Widgets\Charts;

use Illuminate\Http\Request;

class MyAjaxBar extends MyBar
{
    protected $id;
    protected $username;

    // 这里的参数一定要设置默认值
    public function __construct($id = null, $username = null) 
    {
        parent::__construct();

        $this->id = $id;
        $this->username = $username;
    }

    /**
     * 处理请求
     * 如果你的图表类中包含此方法,则可以通过此方法处理前端通过ajax提交的获取图表数据的请求
     *
     * @param Request $request
     * @return mixed|void
     */
    public function handle(Request $request)
    {
        // 获取 parameters 方法设置的自定义参数
        $id = $request->get('id');
        $username = $request->get('username');

        switch ((int) $request->get('option')) {
            case 30:
                // 你的数据查询逻辑
                $data = [
                    [
                        'data' => [44, 55, 41, 64, 22, 43, 21]
                    ],
                    [
                        'data' => [53, 32, 33, 52, 13, 44, 32]
                    ]
                ];
                $categories = [2001, 2002, 2003, 2004, 2005, 2006, 2007];

                break;
            case 28:
                // 你的数据查询逻辑
                $data = [
                    [
                        'data' => [44, 55, 41, 64, 22, 43, 21]
                    ],
                    [
                        'data' => [53, 32, 33, 52, 13, 44, 32]
                    ]
                ];
                $categories = [2001, 2002, 2003, 2004, 2005, 2006, 2007];

                break;
            case 7:
            default:
                // 你的数据查询逻辑
                $data = [
                    [
                        'data' => [44, 55, 41, 64, 22, 43, 21]
                    ],
                    [
                        'data' => [53, 32, 33, 52, 13, 44, 32]
                    ]
                ];
                $categories = [2001, 2002, 2003, 2004, 2005, 2006, 2007];
                break;
        }

        $this->withData($data);
        $this->withCategories($categories);
    }

    /**
      * 这里返回需要异步传递到 handler 方法的参数 
      * 
     * @return array
     */
    public function parameters(): array
    {
        return [
            'id'        => $this->id,
            'username' => $this->username,
        ];
    }

    /**
     * 这里覆写父类的方法,不再查询数据
     */
    protected function buildData()
    {
    }
}

用户点击构建下拉菜单加载不同的图表数据

<?php

use App\Admin\Widgets\Charts\MyAjaxBar;
use Dcat\Admin\Widgets\Dropdown;
use Dcat\Admin\Widgets\Box;
use Dcat\Admin\Layout\Row;
use Dcat\Admin\Layout\Content;

class MyController
{
    public function index(Content $content)
    {
        return $content->body(function (Row $row) {
            // 构建下拉菜单,当点击菜单时发起请求获取数据重新渲染图表
            $menu = [
                '7'  => '最近7天',
                '28' => '最近28天',
                '30' => '最近30天',
            ];
            $dropdown = Dropdown::make($menu)
                ->button(current($menu))
                ->click()
                ->map(function ($v, $k) {
                    // 此处设置的 data-xxx 属性会作为post数据发送到后端api
                    return "<a class='switch-bar' data-option='{$k}'>{$v}</a>";
                });

                        // 传递自定义参数
            $id = ...;
            $username = ...;

            $bar = MyAjaxBar::make($id, $username)
                ->fetching('$("#my-box").loading()') // 设置loading效果
                ->fetched('$("#my-box").loading(false)') // 移除loading效果
                ->click('.switch-bar'); // 设置图表点击菜单则重新发起请求,且被点击的目标元素上的 data-xxx 属性会被作为post数据发送到后端API

            $box = Box::make('我的图表2', $bar)
                ->id('my-box') // 设置盒子的ID
                ->tool($dropdown); // 设置下拉菜单按钮

            $row->column(12, $box);
        });
    }
}

效果
图表 - 图2

设置图表配置为可执行JS代码

如果你需要在图表配置加入可执行的JS代码,可参考以下方式

<?php

use use Dcat\Admin\Support\JavaScript;
use Dcat\Admin\Admin;
use Dcat\Admin\Widgets\ApexCharts\Chart;

class MyBar extends Chart
{
    public function __construct($containerSelector = null, $options = [])
    {
        parent::__construct($containerSelector, $options);

        $this->setUpOptions();
    }

    /**
     * 初始化图表配置
     */
    protected function setUpOptions()
    {
        $number = 20;

        $this->option(
            'plotOptions.radialBar.dataLabels.total.formatter',
            // 这个值最后段代码会作为JS代码执行
            JavaScript::make("function () { return {$number}; }")
        );

        ...
    }

    ...   
}