Laravel Nova 定义 Metrics

2023-02-16 17:09 更新

Nova 的 metrics 可以帮助您快速了解应用的关键业务指标。例如,您可以定义一个 metrics,用来显示每天添加到应用中的用户总数或每周销售额。

Nova 提供三种类型的内置 metrics:值 metrics、趋势 metrics 和分区 metrics。下面我们将学习每种类型的 metrics 并在演示它们的用法。

Value Metrics

Value metrics 可以展示单个值,如果需要,也可以显示与上个周期间隔的比值。 例如,一个 value metric 想显示前三十天新用户和 上个三十天新用户的比值:


Value metrics 可以使用 nova:value Artisan 命令生成。默认 所有新生成的 metrics 都会在 app/Nova/Metrics 目录中:

php artisan nova:value NewUsers

一旦生成值 metric 类后,您就可以对其进行自定义了。每个值 metric 都有一个 calculate 方法,该方法返回了一个 Laravel\Nova\Metrics\ValueResult 对象。Nova 附带了各种帮助程序,可以快速生成结果。

下面的例子,我们使用 count 助手自动对选定范围的 Eloquent 模型执行 count 查询,并自动对 “上一个” 索引范围计数。

<?php

namespace App\Nova\Metrics;

use App\User;
use Illuminate\Http\Request;
use Laravel\Nova\Metrics\Value;

class NewUsers extends Value
{
    /**
     * 计算 metric 的值。
     *
     * @param  \Illuminate\Http\Request  $request
     * @return mixed
     */
    public function calculate(Request $request)
    {
        return $this->count($request, User::class);
    }

    /**
     * 获取 metric 的时间范围。
     *
     * @return array
     */
    public function ranges()
    {
        return [
            30 => '30 Days',
            60 => '60 Days',
            365 => '365 Days',
            'MTD' => 'Month To Date',
            'QTD' => 'Quarter To Date',
            'YTD' => 'Year To Date',
        ];
    }

    /**
     * 获取 metric 的 URI 键。
     *
     * @return string
     */
    public function uriKey()
    {
        return 'new-users';
    }
}

值查询类型

值 metrics 不只是附带一个 count 助手。在构建 metric 时,您还可以在构建 metric 时使用各种其他聚合函数。

Average

average 方法可用于计算给定列与前一个时间间隔 / 范围相比的平均值:

return $this->average($request, Post::class, 'word_count');

Sum

sum 方法可用于计算给定列与前一时间间隔 / 范围的总和:

return $this->sum($request, Order::class, 'price');

Max

max 方法可用于计算给定列相对于前一时间间隔 / 范围的最大值:

return $this->max($request, Order::class, 'total');

Min

min 方法可用于计算给定列相对于前一时间间隔 / 范围的最小值:

return $this->min($request, Order::class, 'total');

值范围

每个值度量类都包含一个 ranges 方法。此方法确定值度量的范围选择菜单中的可用的范围。数组的键确定应包含在查询中的天数,而值确定将放置在范围选择菜单中的「可读的」文本。当然,您根本不需要定义任何范围:

/**
 * 获取指标可用范围。
 *
 * @return array
 */
public function ranges()
{
    return [
        5 => '5 Days',
        10 => '10 Days',
        15 => '15 Days',
        'MTD' => 'Month To Date',
        'QTD' => 'Quarter To Date',
        'YTD' => 'Year To Date',
    ];
}

MTD / QTD / YTD 范围键

您可以定制这些范围以满足您的需求;但是,如果您使用内置的「月度至今」、「季度至今」、或 「年度至今」范围,则不应更改它们的键。

手动构建结果值

如果你不能使用自带的查询助手构建您的 metric 值,你可以使用 result 和 previous 方法手动为 metric 提供最终值:

return $this->result(100)->previous(50);

趋势 Metrics

趋势 metrics 通过折线图显示随着时间变化的值。例如,趋势 metric 可能会显示过去 30 天内每天创建的新用户数:


趋势指标可以使用 nova:trend Artisan 命令生成。默认情况下,所有新指标都将放在 app/Nova/Metrics 目录中:

php artisan nova:trend UsersPerDay

生成趋势度量类后,您就可以对其进行自定义了。每个趋势度量类都包含一个 calculate 方法。这个方法应该返回一个 Laravel\Nova\Metrics\TrendResult 对象。不用担心,Nova 附带了各种帮助程序,可以快速生成结果。

在这个例子中,我们使用了 countByDays 帮助器,它会自动对指定的 Eloquent 模型执行一个 count 查询,用于选定的范围和选定的间隔单位 (在这种情况下,天):

<?php

namespace App\Nova\Metrics;

use App\User;
use Illuminate\Http\Request;
use Laravel\Nova\Metrics\Trend;

class UsersPerDay extends Trend
{
    /**
     * Calculate the value of the metric.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return mixed
     */
    public function calculate(Request $request)
    {
        return $this->countByDays($request, User::class);
    }

    /**
     * Get the ranges available for the metric.
     *
     * @return array
     */
    public function ranges()
    {
        return [
            30 => '30 Days',
            60 => '60 Days',
            90 => '90 Days',
        ];
    }

    /**
     * Get the URI key for the metric.
     *
     * @return string
     */
    public function uriKey()
    {
        return 'users-per-day';
    }
}

趋势查询类型

趋势 metrics 不只是附带一个 countByDays 助手。在构建 metric 时,您还可以使用各种其他聚合函数和时间间隔。

Count

count 方法可用于计算给定列随着时间变化的计数:

return $this->countByMonths($request, User::class);
return $this->countByWeeks($request, User::class);
return $this->countByDays($request, User::class);
return $this->countByHours($request, User::class);
return $this->countByMinutes($request, User::class);

Average

average 方法可用于计算给定列随着时间变化的平均值:

return $this->averageByMonths($request, Post::class, 'word_count');
return $this->averageByWeeks($request, Post::class, 'word_count');
return $this->averageByDays($request, Post::class, 'word_count');
return $this->averageByHours($request, Post::class, 'word_count');
return $this->averageByMinutes($request, Post::class, 'word_count');

Sum

sum 方法可用于计算给定列随着时间变化的总和:

return $this->sumByMonths($request, Order::class, 'price');
return $this->sumByWeeks($request, Order::class, 'price');
return $this->sumByDays($request, Order::class, 'price');
return $this->sumByHours($request, Order::class, 'price');
return $this->sumByMinutes($request, Order::class, 'price');

Max

max 方法可用于计算给定列随着时间变化的最大值:

return $this->maxByMonths($request, Order::class, 'total');
return $this->maxByWeeks($request, Order::class, 'total');
return $this->maxByDays($request, Order::class, 'total');
return $this->maxByHours($request, Order::class, 'total');
return $this->maxByMinutes($request, Order::class, 'total');

Min

min 方法可用于计算给定列随着时间变化的最小值:

return $this->minByMonths($request, Order::class, 'total');
return $this->minByWeeks($request, Order::class, 'total');
return $this->minByDays($request, Order::class, 'total');
return $this->minByHours($request, Order::class, 'total');
return $this->minByMinutes($request, Order::class, 'total');

趋势范围

每个趋势度量标准类都包含一个 范围 方法。此方法确定将在趋势市度量标准范围选择菜单中提供的范围。数组的密钥确定应在查询中包含的时间间隔单位 (月,周,天等) 的数量,而值确定将放置在范围选择菜单中的「可读的」文本。当然,您无需定义任何范围:

/**
 * Get the ranges available for the metric.
 *
 * @return array
 */
public function ranges()
{
    return [
        5 => '5 Days',
        10 => '10 Days',
        15 => '15 Days',
    ];
}

格式化趋势值

有时,您可能希望添加一个前缀或后缀到趋势值。为了实现这一点,您可以使用 prefix 和 suffix 方法:

return $this->countByDays($request, User::class)
            ->prefix(');

如果你的趋势 metric 是显示一个货币值,您可以使用 dollars 和 euros 快捷方法快速在趋势值前添加美元或欧元符号:

return $this->countByDays($request, User::class)
            ->dollars();

显示当前值

有时,您可能希望突出最新时间间隔的值。例如,在这个截图中,在最后一天创建了 6 个用户:


您可以使用 showLatestValue 方法完成这个:

return $this->countByDays($request, User::class)
            ->showLatestValue();

手动构建趋势结果

如果您无法使用包含的查询助手来构建趋势指标,您可以手动构建 Laravel\Nova\Metrics\TrendResult 对象并从指标的 calculate 方法中返回它:

return (new TrendResult)->trend([
    'July 1' => 100,
    'July 2' => 150,
    'July 3' => 200,
]);

分区指标

分区指标显示值的饼图。例如,分区指标可能会显示应用程序提供的每个计费计划的用户总数:


可以使用 nova:partition artisan 命令生成分区度量。默认情况下,所有新指标都将放在 app/nova/metrics 目录中:

php artisan nova:partition UsersPerPlan

一旦生成了分区度量类,您就可以自定义了它。每个分区度量类包含一个 calculate 方法。此方法应返回一个 laravel\nova\metrics\partitionResult 对象。别担心,Nova 提供了各种各样的助手,可以快速生成结果

在此示例中,我们正在使用 count 助手程序,它将自动执行针对指定的 eloquent 模型的 count 查询,并检索属于指定的每个不同值的模型数量「group by」列:

<?php

namespace App\Nova\Metrics;

use App\User;
use Illuminate\Http\Request;
use Laravel\Nova\Metrics\Partition;

class UsersPerPlan extends Partition
{
    /**
     * 计算度量标准的值。
     *
     * @param  \Illuminate\Http\Request  $request
     * @return mixed
     */
    public function calculate(Request $request)
    {
        return $this->count($request, User::class, 'stripe_plan');
    }

    /**
     * 获取度量标准的URI键。
     *
     * @return string
     */
    public function uriKey()
    {
        return 'users-by-plan';
    }
}

分区查询类型

分区度量不只附带 count 帮助器。在构建指标时,您还可以使用各种其他聚合函数。

平均值

average 方法可用于计算不同组中给定列的平均值。例如,以下对 average 方法的调用将显示一个饼形图,其中包含公司每个部门的平均订单价格:

return $this->average($request, Order::class, 'price', 'department');

求和

sum 方法可用于计算不同组中给定列的总和。例如,以下对 sum 方法的调用将显示一个饼图,其中包含公司每个部门的所有订单价格的总和:

return $this->sum($request, Order::class, 'price', 'department');

最大值

max 方法可用于计算不同组中给定列的最大值。例如,以下对 max 方法的调用将显示一个饼图,其中包含公司每个部门的最高订单价格:

return $this->max($request, Order::class, 'price', 'department');

Min

min 方法可用于计算不同组内给定列的最小值。例如下面的 min 方法将显示一个饼图,其中包含公司每个部门的最低订单价格:

return $this->min($request, Order::class, 'price', 'department');

自定义分区标签

通常,将分区 metrics 指标分组的列值将是最简单的键,而不是 “友好” 的东西。或者,如果您要显示布尔值列分组的分区 metric,Nova 会将您的组标签显示为 “0” 和 "1"。因此,Nova 允许您提供一个 Closure 将标签格式化为更具有可读性的内容:

/**
 * 计算 metric 的值。
 *
 * @param  \Illuminate\Http\Request  $request
 * @return mixed
 */
public function calculate(Request $request)
{
    return $this->count($request, User::class, 'stripe_plan')
            ->label(function ($value) {
                switch ($value) {
                    case null:
                        return 'None';
                    default:
                        return ucfirst($value);
                }
            });
}

手动生成分区结果

如果您无法使用内置的查询助手构建你的分区 metric,您可以使用 result 方法手动为 metric 提供最终值:

return $this->result([
    'Group 1' => 100,
    'Group 2' => 200,
    'Group 3' => 300,
]);

缓存

有时 metric 值的计算可能会很慢且成本很高。因此,所有 Nova metrics 都包含一个 cacheFor 方法,该方法允许您指定 metric 结果的缓存时长:

/**
 * 指定 metric 应缓存多少分钟。
 *
 * @return  \DateTimeInterface|\DateInterval|float|int
 */
public function cacheFor()
{
    return now()->addMinutes(5);
}


以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号