jqh 5 лет назад
Родитель
Сommit
6460535ed9

+ 7 - 4
resources/views/widgets/metrics/card.blade.php

@@ -9,7 +9,11 @@
             </div>
             @endif
 
-            <div class="metric-content">{!! Dcat\Admin\Support\Helper::render($options['content']) !!}</div>
+            @if($options['title'])
+                <h4 class="card-title mb-1">{!! $options['title'] !!}</h4>
+            @endif
+
+            <div class="metric-header">{!! $header !!}</div>
         </div>
 
         @if(! empty($options['dropdown']))
@@ -25,7 +29,6 @@
         </div>
         @endif
     </div>
-    <div class="card-content" style="position: relative;width: 100%">
-        {!! ! empty($chart) ? $chart : '' !!}
-    </div>
+
+    <div class="metric-content">{!! $content !!}</div>
 </div>

+ 0 - 33
resources/views/widgets/metrics/radial-bar-card.blade.php

@@ -1,33 +0,0 @@
-<div {!! $attributes !!}>
-    <div class="card-header d-flex justify-content-between pb-0">
-        <h4 class="card-title mb-1">{!! $options['title'] !!}</h4>
-
-        @if(! empty($options['dropdown']))
-        <div class="dropdown chart-dropdown">
-            <button class="btn btn-sm btn-light shadow-0 dropdown-toggle p-0 waves-effect" data-toggle="dropdown">
-                {{ current($options['dropdown']) }}
-            </button>
-            <div class="dropdown-menu dropdown-menu-right">
-                @foreach($options['dropdown'] as $key => $value)
-                    <li class="dropdown-item"><a href="javascript:void(0)" class="select-option" data-option="{{ $key }}">{{ $value }}</a></li>
-                @endforeach
-            </div>
-        </div>
-        @endif
-    </div>
-    <div class="card-content">
-        <div class="card-body pt-0">
-            <div class="row">
-                <div class="metric-content col-sm-2 col-12 d-flex flex-column flex-wrap text-center">
-                    {!! \Dcat\Admin\Support\Helper::render($options['content']) !!}
-                </div>
-                <div class="col-sm-10 col-12 d-flex justify-content-center">
-                    {!! ! empty($chart) ? $chart : '' !!}
-                </div>
-            </div>
-            <div class="chart-info metric-footer d-flex justify-content-between">
-                {!! \Dcat\Admin\Support\Helper::render($options['footer']) !!}
-            </div>
-        </div>
-    </div>
-</div>

+ 3 - 3
src/Support/Helper.php

@@ -96,9 +96,9 @@ class Helper
     /**
      * 把给定的值转化为字符串.
      *
-     * @param mixed  $value
-     * @param array  $params
-     * @param object $newThis
+     * @param string|Grid|\Closure|Renderable|Htmlable  $value
+     * @param array                                     $params
+     * @param object                                    $newThis
      *
      * @return string
      */

+ 5 - 3
src/Widgets/ApexCharts/Chart.php

@@ -248,7 +248,7 @@ if (! response.status) {
     return Dcat.error(response.message || 'Server internal error.');
 }
 
-var container = $('{$this->containerSelector}'), extend = {$this->buildExtendOptionsScript()};
+var container = $(response.selector || '{$this->containerSelector}'), extend = {$this->buildExtendOptionsScript()};
 
 container.html('');
 
@@ -288,6 +288,7 @@ JS;
         $hasSelector = $this->containerSelector ? true : false;
 
         if (! $hasSelector) {
+            // 没有指定ID,需要自动生成
             $id = $this->generateId();
 
             $this->selector('#'.$id);
@@ -319,8 +320,9 @@ HTML;
     public function result()
     {
         return [
-            'status' => 1,
-            'options' => $this->options,
+            'status'   => 1,
+            'selector' => $this->containerSelector,
+            'options'  => $this->options,
         ];
     }
 

+ 0 - 13
src/Widgets/Markdown.php

@@ -34,19 +34,6 @@ class Markdown extends Widget
         Admin::collectAssets('@editor-md');
     }
 
-    /**
-     * @param mixed $k
-     * @param mixed $v
-     *
-     * @return $this
-     */
-    public function option($k, $v)
-    {
-        $this->options[$k] = $v;
-
-        return $this;
-    }
-
     /**
      * @param string|Renderable $markdown
      *

+ 152 - 74
src/Widgets/Metrics/Card.php

@@ -23,7 +23,9 @@ class Card extends Widget
      */
     protected $options = [
         'icon' => null,
-        'content' => '',
+        'title' => null,
+        'header' => null,
+        'content' => null,
         'dropdown' => [],
     ];
 
@@ -40,54 +42,7 @@ class Card extends Widget
     /**
      * @var array 
      */
-    protected $chartOptions = [
-        'chart' => [
-            'type' => 'area',
-            'toolbar' => [
-                'show' => false,
-            ],
-            'sparkline' => [
-                'enabled' => true,
-            ],
-            'grid' => [
-                'show' => false,
-                'padding' => [
-                    'left' => 0,
-                    'right' => 0,
-                ]
-            ],
-        ],
-        'tooltip' => [
-            'x' => [
-                'show' => false,
-            ],
-        ],
-        'xaxis' => [
-            'labels' => [
-                'show' => false,
-            ],
-            'axisBorder' => [
-                'show' => false,
-            ],
-        ],
-        'yaxis' => [
-            'y' => 0,
-            'offsetX' => 0,
-            'offsetY' => 0,
-            'padding' => ['left' => 0, 'right' => 0],
-        ],
-        'dataLabels' => [
-            'enabled' => false,
-        ],
-        'stroke' => [
-            'width' => 2.5,
-            'curve' => 'straight'
-        ],
-        'fill' => [
-            'opacity' => 0.1,
-            'type' => 'solid',
-        ],
-    ];
+    protected $chartOptions = [];
 
     /**
      * @var Chart
@@ -99,10 +54,14 @@ class Card extends Widget
      */
     protected $chartCallback;
 
-    public function __construct($icon = null, $contents = null)
+    public function __construct($title = null, $icon = null)
     {
+        $this->title($title);
         $this->icon($icon);
-        $this->content($contents);
+
+        if ($options = $this->defaultChartOptions()) {
+            $this->chartOptions = $options;
+        }
 
         $this->init();
     }
@@ -110,58 +69,109 @@ class Card extends Widget
     /**
      * 初始化
      */
-    public function init()
+    protected function init()
     {
         $this->id('metric-card-'.Str::random(8));
         $this->class('card');
     }
 
     /**
-     * 设置图表
+     * 图表默认配置
+     *
+     * @return array
+     */
+    protected function defaultChartOptions()
+    {
+        return [];
+    }
+
+    /**
+     * 启用图表.
+     *
+     * @return Chart
+     */
+    public function useChart()
+    {
+        return $this->chart ?: ($this->chart = Chart::make());
+    }
+
+    /**
+     * 设置图表.
      */
-    public function setUpChart()
+    protected function setUpChart()
     {
-        $chart = $this->chart ?: ($this->chart = Chart::make());
+        if (! $chart = $this->chart) {
+            return;
+        }
 
         // 设置图表高度
         $this->chartOptions['chart']['height'] = $this->chartHeight;
 
+        // 颜色
+        if (empty($this->chartOptions['colors'])) {
+            $this->chartOptions['colors'] = (array) Admin::color()->get($this->style);
+        }
+
         // 图表配置选项
         $chart->options($this->chartOptions);
-        // 颜色
-        $chart->colors(Admin::color()->get($this->style));
 
         if ($callback = $this->chartCallback) {
             $callback($chart);
         }
+    }
+
+    /**
+     * 设置图标.
+     *
+     * @param string $icon
+     *
+     * @return $this
+     */
+    public function icon(?string $icon)
+    {
+        $this->options['icon'] = $icon;
+
+        return $this;
+    }
+
+    /**
+     * 设置卡片标题.
+     *
+     * @param string $title
+     *
+     * @return $this
+     */
+    public function title(?string $title)
+    {
+        $this->options['title'] = $title;
 
-        $this->variables['chart'] = $chart;
+        return $this;
     }
 
     /**
-     * 设置卡片内容.
+     * 设置卡片内容.
      *
      * @param string $contents
      *
      * @return $this
      */
-    public function content($contents)
+    public function header($contents)
     {
-        $this->options['content'] = $contents;
+        $this->options['header'] = $contents;
 
         return $this;
     }
 
     /**
-     * 设置图标.
+     * 设置卡片内容.
      *
-     * @param string $icon
+     * @param string $contents
      *
      * @return $this
      */
-    public function icon(?string $icon)
+    public function content($contents)
     {
-        $this->options['icon'] = $icon;
+        $this->options['content'] = $contents;
 
         return $this;
     }
@@ -221,7 +231,39 @@ class Card extends Widget
     {
         $this->chartHeight = $number;
 
-        $this->setUpChart();
+        $this->useChart();
+
+        return $this;
+    }
+
+    /**
+     * 设置图表label.
+     *
+     * @param string|array $label
+     *
+     * @return $this
+     */
+    public function chartLabels($label)
+    {
+        $this->chartOptions['labels'] = (array) $label;
+
+        $this->useChart();
+
+        return $this;
+    }
+
+    /**
+     * 设置图表颜色
+     *
+     * @param string|array $colors
+     *
+     * @return $this
+     */
+    public function chartColors($colors)
+    {
+        $this->chartOptions['colors'] = (array) $colors;
+
+        $this->useChart();
 
         return $this;
     }
@@ -244,7 +286,7 @@ class Card extends Widget
             );
         }
 
-        $this->setUpChart();
+        $this->useChart();
 
         return $this;
     }
@@ -270,8 +312,9 @@ JS
 
         $this->fetched(
             <<<'JS'
-$card.loading(false);            
-$card.find('.metric-content').html(response.content)
+$card.loading(false);   
+$card.find('.metric-header').html(response.header);
+$card.find('.metric-content').html(response.content);
 JS
         );
 
@@ -297,14 +340,44 @@ $('{$clickable}').click(function () {
 JS;
     }
 
+    /**
+     * @return string
+     */
+    public function renderHeader()
+    {
+        return Helper::render($this->options['header']);
+    }
+
+    /**
+     * @return string
+     */
+    public function renderContent()
+    {
+        return Helper::render($this->options['content']);
+    }
+
+    /**
+     * 渲染图表.
+     *
+     * @return string
+     */
+    public function renderChart()
+    {
+        return $this->chart ? $this->chart->render() : '';
+    }
+
     /**
      * @return string
      */
     public function render()
     {
+        $this->setUpChart();
+
         $this->script = $this->script();
 
         $this->variables['style'] = $this->style;
+        $this->variables['header'] = $this->renderHeader();
+        $this->variables['content'] = $this->renderContent();
 
         return parent::render();
     }
@@ -316,10 +389,15 @@ JS;
      */
     public function result()
     {
-        return [
-            'status'  => 1,
-            'content' => Helper::render($this->options['content']),
-            'options' => optional($this->chart)->getOptions(),
-        ];
+        $this->setUpChart();
+
+        return array_merge(
+            [
+                'status'  => 1,
+                'header'  => $this->renderHeader(),
+                'content' => $this->renderContent(),
+            ],
+            (array) optional($this->chart)->result()
+        );
     }
 }

+ 35 - 79
src/Widgets/Metrics/RadialBarCard.php

@@ -11,18 +11,15 @@ class RadialBarCard extends Card
 {
     use FromApi;
 
-    /**
-     * @var string
-     */
-    protected $view = 'admin::widgets.metrics.radial-bar-card';
-
     /**
      * @var array
      */
     protected $options = [
-        'title' => '',
-        'content' => '',
-        'footer' => '',
+        'icon'     => null,
+        'title'    => null,
+        'header'   => null,
+        'content'  => null,
+        'footer'   => null,
         'dropdown' => [],
     ];
 
@@ -32,28 +29,16 @@ class RadialBarCard extends Card
     protected $chartHeight = 200;
 
     /**
-     * @var array
-     */
-    protected $chartOptions = [];
-
-    public function __construct(?string $title = null, $contents = null)
-    {
-        $this->title($title);
-        $this->content($contents);
-
-        $this->defaultChartOptions();
-
-        $this->init();
-    }
-
-    /**
-     * 图表默认配置
+     * 图表默认配置.
+     *
+     * @return array
      */
     protected function defaultChartOptions()
     {
         $gradientColor = Admin::color()->success();
+        $labelColor = '#99a2ac';
 
-        $this->chartOptions = [
+        return [
             'chart' => [
                 'type' => 'radialBar',
             ],
@@ -73,7 +58,7 @@ class RadialBarCard extends Card
                     'dataLabels' => [
                         'value' => [
                             'offsetY' => 30,
-                            'color' => '#99a2ac',
+                            'color' => $labelColor,
                             'fontSize' => '2rem'
                         ]
                     ]
@@ -98,20 +83,6 @@ class RadialBarCard extends Card
         ];
     }
 
-    /**
-     * 设置卡片标题.
-     *
-     * @param string $value
-     *
-     * @return $this
-     */
-    public function title(?string $value)
-    {
-        $this->options['title'] = $value;
-
-        return $this;
-    }
-
     /**
      * 设置卡片底部内容.
      *
@@ -127,51 +98,36 @@ class RadialBarCard extends Card
     }
 
     /**
-     * 设置图表label.
-     *
-     * @param string|array $label
-     *
-     * @return $this
+     * @return string
      */
-    public function chartLabels($label)
+    public function renderFooter()
     {
-        $this->chartOptions['labels'] = (array) $label;
-
-        $this->setUpChart();
-
-        return $this;
+        return Helper::render($this->options['footer']);
     }
 
     /**
-     * @return mixed
-     */
-    public function script()
-    {
-        if (! $this->allowBuildRequest()) {
-            return;
-        }
-
-        $this->fetched(
-            <<<'JS'
-$card.find('.metric-footer').html(response.footer);
-JS
-        );
-
-        return parent::script();
-    }
-
-        /**
-     * 返回卡片数据结果.
-     *
-     * @return array
+     * @return string
      */
-    public function result()
+    public function renderContent()
     {
-        return array_merge(
-            parent::result(),
-            [
-                'footer' => Helper::render($this->options['footer']),
-            ]
-        );
+        $content = parent::renderContent();
+
+        return <<<HTML
+<div class="card-content">
+    <div class="card-body pt-0">
+        <div class="row">
+            <div class="metric-content col-sm-2 col-12 d-flex flex-column flex-wrap text-center">
+                {$content}
+            </div>
+            <div class="col-sm-10 col-12 d-flex justify-content-center">
+                {$this->renderChart()}
+            </div>
+        </div>
+        <div class="chart-info metric-footer d-flex justify-content-between">
+            {$this->renderFooter()}
+        </div>
+    </div>
+</div>
+HTML;
     }
 }

+ 93 - 0
src/Widgets/Metrics/SparklineCard.php

@@ -0,0 +1,93 @@
+<?php
+
+namespace Dcat\Admin\Widgets\Metrics;
+
+/**
+ * 趋势图卡片
+ *
+ * @package Dcat\Admin\Widgets\Metrics
+ */
+class SparklineCard extends Card
+{
+    /**
+     * 趋势图图表默认配置
+     *
+     * @var array
+     */
+    protected $chartOptions = [
+        'chart' => [
+            'type' => 'area',
+            'toolbar' => [
+                'show' => false,
+            ],
+            'sparkline' => [
+                'enabled' => true,
+            ],
+            'grid' => [
+                'show' => false,
+                'padding' => [
+                    'left' => 0,
+                    'right' => 0,
+                ]
+            ],
+        ],
+        'tooltip' => [
+            'x' => [
+                'show' => false,
+            ],
+        ],
+        'xaxis' => [
+            'labels' => [
+                'show' => false,
+            ],
+            'axisBorder' => [
+                'show' => false,
+            ],
+        ],
+        'yaxis' => [
+            'y' => 0,
+            'offsetX' => 0,
+            'offsetY' => 0,
+            'padding' => ['left' => 0, 'right' => 0],
+        ],
+        'dataLabels' => [
+            'enabled' => false,
+        ],
+        'stroke' => [
+            'width' => 2.5,
+            'curve' => 'straight'
+        ],
+        'fill' => [
+            'opacity' => 0.1,
+            'type' => 'solid',
+        ],
+    ];
+
+    /**
+     * 初始化
+     */
+    protected function init()
+    {
+        parent::init();
+
+        // 初始化图表
+        $this->setUpChart();
+    }
+
+    /**
+     * 渲染内容,加上图表.
+     *
+     * @return string
+     */
+    public function renderContent()
+    {
+        $content = parent::renderContent();
+
+        return <<<HTML
+{$content}
+<div class="card-content" style="position: relative;width: 100%">
+    {$this->renderChart()}
+</div>
+HTML;
+    }
+}

+ 31 - 8
src/Widgets/Widget.php

@@ -8,6 +8,7 @@ use Dcat\Admin\Support\Helper;
 use Dcat\Admin\Traits\HasHtmlAttributes;
 use Illuminate\Contracts\Support\Arrayable;
 use Illuminate\Contracts\Support\Renderable;
+use Illuminate\Support\Arr;
 
 /**
  * @method $this class(string $class, bool $append = false)
@@ -49,8 +50,6 @@ abstract class Widget implements Renderable
     protected $options = [];
 
     /**
-     * Create a widget instance.
-     *
      * @param mixed ...$params
      *
      * @return static
@@ -61,6 +60,8 @@ abstract class Widget implements Renderable
     }
 
     /**
+     * 批量设置选项.
+     *
      * @param array $options
      *
      * @return $this
@@ -76,13 +77,37 @@ abstract class Widget implements Renderable
         return $this;
     }
 
+    /**
+     * 设置或获取配置选项.
+     *
+     * @param string $key
+     * @param mixed  $value
+     *
+     * @return $this
+     */
+    public function option($key, $value = null)
+    {
+        if ($value === null) {
+            return Arr::get($this->options, $key);
+        } else {
+            Arr::set($this->options, $key, $value);
+        }
+
+        return $this;
+    }
+
+    /**
+     * 获取所有选项.
+     *
+     * @return array
+     */
     public function getOptions()
     {
         return $this->options;
     }
 
     /**
-     * Variables in view.
+     * 获取视图变量.
      *
      * @return array
      */
@@ -95,7 +120,7 @@ abstract class Widget implements Renderable
     }
 
     /**
-     * Collect assets.
+     * 收集静态资源.
      */
     protected function collectAssets()
     {
@@ -106,8 +131,6 @@ abstract class Widget implements Renderable
     }
 
     /**
-     * To string.
-     *
      * @param $value
      *
      * @return string
@@ -136,7 +159,7 @@ abstract class Widget implements Renderable
     }
 
     /**
-     * Automatically render to the body element.
+     * 自动调用render方法.
      *
      * @return void
      */
@@ -150,7 +173,7 @@ abstract class Widget implements Renderable
     }
 
     /**
-     * Set view of widget.
+     * 设置模板.
      *
      * @param string $view
      */