Browse Source

metrics card

jqh 5 years ago
parent
commit
f920397efc

+ 17 - 19
resources/views/dashboard/title.blade.php

@@ -1,20 +1,11 @@
 <style>
 <style>
-    .title {
-        font-size: 50px;
-        color: #636b6f;
-        font-weight: 100;
-        display: block;
-        text-align: center;
-        margin: 20px 0 10px 0px;
-    }
-
     .links {
     .links {
         text-align: center;
         text-align: center;
-        margin-bottom: 20px;
+        /*margin-bottom: 20px;*/
     }
     }
 
 
     .links > a {
     .links > a {
-        color: #636b6f;
+        color: {{ \Dcat\Admin\Admin::color()->white50()  }};
         padding: 0 25px;
         padding: 0 25px;
         font-size: 12px;
         font-size: 12px;
         font-weight: 600;
         font-weight: 600;
@@ -24,11 +15,18 @@
     }
     }
 </style>
 </style>
 
 
-<div class="title">
-    Dcat Admin
-</div>
-<div class="links">
-    <a href="https://github.com/jqhph/dcat-admin" target="_blank">Github</a>
-    <a href="https://jqhph.github.io/dcat-admin/docs.html" id="doc-link" target="_blank">Documentation</a>
-    <a href="https://jqhph.github.io/dcat-admin/demo.html" id="demo-link" target="_blank">Demo</a>
-</div>
+<div class="text-center">
+    <div class="avatar avatar-xl bg-primary shadow mt-0 mb-2">
+        <div class="avatar-content">
+            <i class="feather icon-award white font-large-1"></i>
+        </div>
+    </div>
+    <div class="text-center mb-1">
+        <h1 class="mb-2 text-white">Dcat Admin</h1>
+        <div class="links">
+            <a href="https://github.com/jqhph/dcat-admin" target="_blank">Github</a>
+            <a href="https://jqhph.github.io/dcat-admin/docs.html" id="doc-link" target="_blank">Documentation</a>
+            <a href="https://jqhph.github.io/dcat-admin/demo.html" id="demo-link" target="_blank">Demo</a>
+        </div>
+    </div>
+</div>

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

@@ -9,23 +9,23 @@
             </div>
             </div>
             @endif
             @endif
 
 
-            {!! Dcat\Admin\Support\Helper::render($options['contents']) !!}
+            <div class="metric-content">{!! Dcat\Admin\Support\Helper::render($options['content']) !!}</div>
         </div>
         </div>
 
 
-        @if(! empty($options['ranges']))
+        @if(! empty($options['dropdown']))
         <div class="dropdown chart-dropdown">
         <div class="dropdown chart-dropdown">
-            <button class="btn btn-sm shadow-0 dropdown-toggle p-0 waves-effect" type="button" id="dropdownItem5" data-toggle="dropdown">
-                {{ current($options['ranges']) }}
+            <button class="btn btn-sm btn-light shadow-0 dropdown-toggle p-0 waves-effect" data-toggle="dropdown">
+                {{ current($options['dropdown']) }}
             </button>
             </button>
             <div class="dropdown-menu dropdown-menu-right">
             <div class="dropdown-menu dropdown-menu-right">
-                @foreach($options['ranges'] as $key => $range)
-                <li class="dropdown-item"><a href="#" data-key="{{ $key }}">{{ $range }}</a></li>
+                @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
                 @endforeach
             </div>
             </div>
         </div>
         </div>
         @endif
         @endif
     </div>
     </div>
     <div class="card-content" style="position: relative;width: 100%">
     <div class="card-content" style="position: relative;width: 100%">
-        {!! $chart !!}
+        {!! ! empty($chart) ? $chart : '' !!}
     </div>
     </div>
 </div>
 </div>

+ 3 - 2
src/Controllers/Dashboard.php

@@ -3,17 +3,18 @@
 namespace Dcat\Admin\Controllers;
 namespace Dcat\Admin\Controllers;
 
 
 use Dcat\Admin\Admin;
 use Dcat\Admin\Admin;
+use Dcat\Admin\Widgets\Card;
 use Dcat\Admin\Widgets\Tab;
 use Dcat\Admin\Widgets\Tab;
 use Illuminate\Support\Arr;
 use Illuminate\Support\Arr;
 
 
 class Dashboard
 class Dashboard
 {
 {
     /**
     /**
-     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
+     * @return mixed
      */
      */
     public static function title()
     public static function title()
     {
     {
-        return view('admin::dashboard.title');
+        return Card::make(view('admin::dashboard.title'))->class('bg-primary-gradient', true);
     }
     }
 
 
     public static function tab()
     public static function tab()

+ 22 - 50
src/Traits/HasHtmlAttributes.php

@@ -7,17 +7,17 @@ use Illuminate\Support\Arr;
 
 
 trait HasHtmlAttributes
 trait HasHtmlAttributes
 {
 {
-    /**
-     * @var array
-     */
     protected $htmlAttributes = [];
     protected $htmlAttributes = [];
 
 
-    /**
-     * @param string|array $key
-     * @param mixed        $value
-     *
-     * @return $this
-     */
+    public function defaultHtmlAttribute($attribute, $value)
+    {
+        if (! array_key_exists($attribute, $this->htmlAttributes)) {
+            $this->setHtmlAttribute($attribute, $value);
+        }
+
+        return $this;
+    }
+
     public function setHtmlAttribute($key, $value = null)
     public function setHtmlAttribute($key, $value = null)
     {
     {
         if (is_array($key)) {
         if (is_array($key)) {
@@ -30,11 +30,19 @@ trait HasHtmlAttributes
         return $this;
         return $this;
     }
     }
 
 
-    /**
-     * @param string|array $keys
-     *
-     * @return $this
-     */
+    public function appendHtmlAttribute($key, $value)
+    {
+        $result = $this->getHtmlAttribute($key);
+
+        if (is_array($result)) {
+            $result[] = $value;
+        } else {
+            $result = "{$result} {$value}";
+        }
+
+        return $this->setHtmlAttribute($key, $result);
+    }
+
     public function forgetHtmlAttribute($keys)
     public function forgetHtmlAttribute($keys)
     {
     {
         Arr::forget($this->htmlAttributes, $keys);
         Arr::forget($this->htmlAttributes, $keys);
@@ -42,57 +50,21 @@ trait HasHtmlAttributes
         return $this;
         return $this;
     }
     }
 
 
-    /**
-     * @return array
-     */
     public function getHtmlAttributes()
     public function getHtmlAttributes()
     {
     {
         return $this->htmlAttributes;
         return $this->htmlAttributes;
     }
     }
 
 
-    /**
-     * Set default attribute.
-     *
-     * @param string $attribute
-     * @param mixed  $value
-     *
-     * @return $this
-     */
-    public function defaultHtmlAttribute($attribute, $value)
-    {
-        if (! array_key_exists($attribute, $this->htmlAttributes)) {
-            $this->setHtmlAttribute($attribute, $value);
-        }
-
-        return $this;
-    }
-
-    /**
-     * @param mixed $key
-     * @param mixed $default
-     *
-     * @return |null
-     */
     public function getHtmlAttribute($key, $default = null)
     public function getHtmlAttribute($key, $default = null)
     {
     {
         return $this->htmlAttributes[$key] ?? $default;
         return $this->htmlAttributes[$key] ?? $default;
     }
     }
 
 
-    /**
-     * @param mixed $key
-     *
-     * @return |null
-     */
     public function hasHtmlAttribute($key)
     public function hasHtmlAttribute($key)
     {
     {
         return array_key_exists($key, $this->htmlAttributes);
         return array_key_exists($key, $this->htmlAttributes);
     }
     }
 
 
-    /**
-     * Build an HTML attribute string from an array.
-     *
-     * @return string
-     */
     public function formatHtmlAttributes()
     public function formatHtmlAttributes()
     {
     {
         return Helper::buildHtmlAttributes($this->htmlAttributes);
         return Helper::buildHtmlAttributes($this->htmlAttributes);

+ 38 - 17
src/Widgets/ApexCharts/Chart.php

@@ -3,13 +3,13 @@
 namespace Dcat\Admin\Widgets\ApexCharts;
 namespace Dcat\Admin\Widgets\ApexCharts;
 
 
 use Dcat\Admin\Support\Helper;
 use Dcat\Admin\Support\Helper;
-use Dcat\Admin\Traits\HasRemoteData;
+use Dcat\Admin\Traits\FromApi;
 use Dcat\Admin\Widgets\Widget;
 use Dcat\Admin\Widgets\Widget;
 use Illuminate\Support\Str;
 use Illuminate\Support\Str;
 
 
 class Chart extends Widget
 class Chart extends Widget
 {
 {
-    use HasRemoteData;
+    use FromApi;
 
 
     public static $js = '@apex-charts';
     public static $js = '@apex-charts';
 
 
@@ -212,14 +212,13 @@ class Chart extends Widget
     }
     }
 
 
     /**
     /**
+     * @param string $options
+     *
      * @return string
      * @return string
      */
      */
-    public function script()
+    protected function buildDefaultScript($options)
     {
     {
-        $options = json_encode($this->options);
-
-        if (! $this->allowBuildRequestScript()) {
-            return <<<JS
+        return <<<JS
 (function () {
 (function () {
     var options = {$options}, extend = function (options) {
     var options = {$options}, extend = function (options) {
         {$this->scripts['extend']}
         {$this->scripts['extend']}
@@ -232,9 +231,18 @@ class Chart extends Widget
     chart.render();
     chart.render();
 })();
 })();
 JS;
 JS;
-        }
+    }
 
 
-        $id = 'chart_'.Str::random();
+    /**
+     * @return string
+     */
+    public function script()
+    {
+        $options = json_encode($this->options);
+
+        if (! $this->allowBuildRequest()) {
+            return $this->buildDefaultScript($options);
+        }
 
 
         $this->fetched(
         $this->fetched(
             <<<JS
             <<<JS
@@ -242,15 +250,15 @@ if (! response.status) {
     return Dcat.error(response.message || 'Server internal error.');
     return Dcat.error(response.message || 'Server internal error.');
 }
 }
 
 
-var id = '{$id}', chart = window[id];
-
-if (chart) {
-chart = new ApexCharts($("{$this->containerSelector}")[0], {$options});
+var container = $('{$this->containerSelector}');
 
 
-chart.render();
-}
+container.html('');
 
 
-chart.updateOptions(response.options);
+setTimeout(function () {
+    var chart = new ApexCharts(container[0], response.options);
+    
+    chart.render();
+}, 50);
 JS
 JS
         );
         );
 
 
@@ -293,8 +301,21 @@ JS
 HTML;
 HTML;
     }
     }
 
 
+    /**
+     * 返回请求结果.
+     *
+     * @return array
+     */
+    public function result()
+    {
+        return [
+            'status' => 1,
+            'options' => $this->options,
+        ];
+    }
+
     protected function generateId()
     protected function generateId()
     {
     {
-        return 'apex-chart-'.$this->type.Str::random(8);
+        return 'apex-chart-'.Str::random(8);
     }
     }
 }
 }

+ 135 - 22
src/Widgets/Metrics/Card.php

@@ -5,18 +5,25 @@ namespace Dcat\Admin\Widgets\Metrics;
 use Dcat\Admin\Admin;
 use Dcat\Admin\Admin;
 use Dcat\Admin\Support\Helper;
 use Dcat\Admin\Support\Helper;
 use Dcat\Admin\Widgets\ApexCharts\Chart;
 use Dcat\Admin\Widgets\ApexCharts\Chart;
-use Dcat\Admin\Traits\HasRemoteData;
+use Dcat\Admin\Traits\FromApi;
 use Dcat\Admin\Widgets\Widget;
 use Dcat\Admin\Widgets\Widget;
+use Illuminate\Support\Str;
 
 
 class Card extends Widget
 class Card extends Widget
 {
 {
-    use HasRemoteData;
+    use FromApi;
 
 
+    /**
+     * @var string
+     */
     protected $view = 'admin::widgets.metrics.card';
     protected $view = 'admin::widgets.metrics.card';
 
 
+    /**
+     * @var array
+     */
     protected $options = [
     protected $options = [
         'icon' => 'feather icon-users',
         'icon' => 'feather icon-users',
-        'contents' => '',
+        'content' => '',
         'style' => 'primary',
         'style' => 'primary',
         'ranges' => [],
         'ranges' => [],
         'chartHeight' => 70,
         'chartHeight' => 70,
@@ -69,25 +76,44 @@ class Card extends Widget
      */
      */
     protected $chart;
     protected $chart;
 
 
+    /**
+     * @var \Closure
+     */
     protected $chartCallback;
     protected $chartCallback;
 
 
     public function __construct($icon = 'feather icon-users', $contents = null)
     public function __construct($icon = 'feather icon-users', $contents = null)
     {
     {
         $this->icon($icon);
         $this->icon($icon);
-        $this->contents($contents);
+        $this->content($contents);
+
+        $this->init();
+    }
+
+    /**
+     * 初始化
+     */
+    public function init()
+    {
+        $this->id('metric-card-'.Str::random(8));
         $this->class('card');
         $this->class('card');
     }
     }
 
 
     /**
     /**
-     * 初始化图表
+     * 设置图表
      */
      */
-    public function initChart()
+    public function setUpChart()
     {
     {
-        $this->options['chart']['chart']['height'] = $this->options['chartHeight'];
+        $chart = $this->chart ?: ($this->chart = Chart::make());
 
 
-        $chart = Chart::make()
-            ->colors(Admin::color()->get($this->options['style']))
-            ->options($this->options['chart']);
+        // 设置图表高度
+        if (empty($this->options['chart']['chart']['height'])) {
+            $this->options['chart']['chart']['height'] = $this->options['chartHeight'];
+        }
+
+        // 颜色
+        $chart->colors(Admin::color()->get($this->options['style']));
+        // 匹配选项
+        $chart->options($this->options['chart']);
 
 
         if ($callback = $this->chartCallback) {
         if ($callback = $this->chartCallback) {
             $callback($chart);
             $callback($chart);
@@ -103,9 +129,9 @@ class Card extends Widget
      *
      *
      * @return $this
      * @return $this
      */
      */
-    public function contents($contents)
+    public function content($contents)
     {
     {
-        $this->options['contents'] = $contents;
+        $this->options['content'] = $contents;
 
 
         return $this;
         return $this;
     }
     }
@@ -139,15 +165,47 @@ class Card extends Widget
     }
     }
 
 
     /**
     /**
-     * 设置卡片的可用范围.
+     * 设置卡片的下拉菜单选项.
      *
      *
      * @param array $items
      * @param array $items
      *
      *
      * @return $this
      * @return $this
      */
      */
-    public function ranges(array $items)
+    public function dropdown(array $items)
     {
     {
-        $this->options['ranges'] = $items;
+        $this->options['dropdown'] = $items;
+
+        return $this;
+    }
+
+    /**
+     * 设置最小高度
+     *
+     * @param string|int $value
+     *
+     * @return $this
+     */
+    public function minHeight($value)
+    {
+        if (is_numeric($value)) {
+            $value .= 'px';
+        }
+
+        return $this->appendHtmlAttribute('style', "min-height:{$value};");
+    }
+
+    /**
+     * 设置图表高度
+     *
+     * @param int $number
+     *
+     * @return $this
+     */
+    public function chartHeight(int $number)
+    {
+        $this->setUpChart();
+
+        $this->options['chartHeight'] = $number;
 
 
         return $this;
         return $this;
     }
     }
@@ -155,16 +213,14 @@ class Card extends Widget
     /**
     /**
      * 设置图表.
      * 设置图表.
      *
      *
-     * @param array|int|\Closure $options
+     * @param array|\Closure $options
      *
      *
      * @return $this
      * @return $this
      */
      */
-    public function chart($options)
+    public function chart($options = [])
     {
     {
         if ($options instanceof \Closure) {
         if ($options instanceof \Closure) {
             $this->chartCallback = $options;
             $this->chartCallback = $options;
-        } elseif (is_numeric($options)) {
-            $this->options['chartHeight'] = $options;
         } else {
         } else {
             $this->options['chart'] = array_merge(
             $this->options['chart'] = array_merge(
                 $this->options['chart'],
                 $this->options['chart'],
@@ -172,25 +228,82 @@ class Card extends Widget
             );
             );
         }
         }
 
 
+        $this->setUpChart();
+
         return $this;
         return $this;
     }
     }
 
 
     /**
     /**
-     * @return string
+     * js代码.
+     *
+     * @return mixed
      */
      */
     public function script()
     public function script()
     {
     {
+        if (! $this->allowBuildRequest()) {
+            return;
+        }
+
+        $id = $this->id();
+
+        // 开启loading效果
+        $this->fetching(
+            <<<JS
+var \$card = $('#{$id}');
+\$card.loading();
+JS
+        );
+
+        $this->fetched(
+            <<<'JS'
+$card.loading(false);            
+$card.find('.metric-content').html(response.content)
+JS
+        );
+
+        $clickable = "#{$id} .dropdown .select-option";
+
+        $cardRequestScript = '';
+
+        if ($this->chart) {
+            $this->chart->merge($this)->click($clickable);
+        } else {
+            $this->click($clickable);
+
+            $cardRequestScript = $this->buildRequestScript();
+        }
+
+        // 按钮显示选中文本
         return <<<JS
         return <<<JS
+$('{$clickable}').click(function () {
+    $(this).parents('.dropdown').find('.btn').html($(this).text());
+});
 
 
+{$cardRequestScript}
 JS;
 JS;
     }
     }
 
 
+    /**
+     * @return string
+     */
     public function render()
     public function render()
     {
     {
-        $this->initChart();
-
         $this->script = $this->script();
         $this->script = $this->script();
 
 
         return parent::render(); // TODO: Change the autogenerated stub
         return parent::render(); // TODO: Change the autogenerated stub
     }
     }
+
+    /**
+     * 返回卡片数据结果.
+     *
+     * @return array
+     */
+    public function result()
+    {
+        return [
+            'status'  => 1,
+            'content' => Helper::render($this->options['content']),
+            'options' => $this->chart ? $this->chart->getOptions() : [],
+        ];
+    }
 }
 }

+ 8 - 2
src/Widgets/Widget.php

@@ -12,7 +12,7 @@ use Illuminate\Contracts\Support\Renderable;
 /**
 /**
  * @method $this class(string $class, bool $append = false)
  * @method $this class(string $class, bool $append = false)
  * @method $this style(string $style, bool $append = true)
  * @method $this style(string $style, bool $append = true)
- * @method $this id(string $id)
+ * @method $this id(string $id = null)
  */
  */
 abstract class Widget implements Renderable
 abstract class Widget implements Renderable
 {
 {
@@ -190,7 +190,13 @@ abstract class Widget implements Renderable
             return $this->setHtmlAttribute($method, $value);
             return $this->setHtmlAttribute($method, $value);
         }
         }
 
 
-        $this->htmlAttributes[$method] = count($parameters) > 0 ? $parameters[0] : true;
+        // 获取属性
+        if (count($parameters) === 0) {
+            return $this->getHtmlAttribute($method);
+        }
+
+        // 设置属性
+        $this->setHtmlAttribute($method, $parameters[0]);
 
 
         return $this;
         return $this;
     }
     }