dact-admin如何使用echarts绘制图
目前想使用dact-admin2.0制作数据图表,想使用echarts绘制图表
1.首先在app/admin/bootstraps.php文件中引入echarts CDN连接
Admin::js('https://lib.baomitu.com/echarts/5.0.0/echarts.common.min.js');
2.后开始在控制器中编写代码
public function ccuEcharts(Content $content, Request $request)
{
// 处理日期参数
if ($request->has('start_date') && $request->has('end_date')) {
$start_date = $request->input('start_date');
$end_date = $request->input('end_date');
$currentDate = date('Y-m-d');
if(empty($start_date) || empty($end_date)) {
$startDate = date('Y-m-d 00:00:00', strtotime($currentDate));
$endDate = date('Y-m-d 23:59:59', strtotime($currentDate));
} else {
$startDate = date('Y-m-d 00:00:00', strtotime($start_date));
$endDate = date('Y-m-d 23:59:59', strtotime($end_date));
}
} else {
$startDate = date('Y-m-d 00:00:00', strtotime('-7 days'));
$endDate = date('Y-m-d 23:59:59');
}
// 格式化日期用于表单显示
$formStartDate = date('Y-m-d', strtotime($startDate));
$formEndDate = date('Y-m-d', strtotime($endDate));
// 查询 CCU 数据
$logs = \App\Models\HeartbeatLog::whereBetween('date', [$startDate, $endDate])
->select('date', 'currentNum')
->orderBy('date', 'asc')
->get();
$timestamps = [];
$values = [];
foreach ($logs as $log) {
$formattedDate = date('Y-m-d H:i', strtotime($log->date));
$timestamps[] = $formattedDate;
$values[] = (int)$log->currentNum; // 确保是整数
}
$maxValue = !empty($values) ? max($values) : 0;
$minValue = !empty($values) ? min($values) : 0;
$avgValue = !empty($values) ? round(array_sum($values) / count($values), 2) : 0;
// 创建搜索表单
$formHtml = <<<HTML
<div class="card mb-3">
<div class="card-header">{$this->trans('ccu.ccu.date_range_selection')}</div>
<div class="card-body">
<form action="/admin/ccuEcharts" method="GET" class="form-inline">
<div class="form-group mr-3">
<label for="start_date" class="mr-2">{$this->trans('ccu.ccu.start_date')}:</label>
<input type="date" class="form-control" id="start_date" name="start_date" value="{$formStartDate}" required>
</div>
<div class="form-group mr-3">
<label for="end_date" class="mr-2">{$this->trans('ccu.ccu.end_date')}:</label>
<input type="date" class="form-control" id="end_date" name="end_date" value="{$formEndDate}" required>
</div>
<button type="submit" class="btn btn-primary">{$this->trans('ccu.ccu.query')}</button>
</form>
</div>
</div>
HTML;
// 创建统计信息卡片
$statsHtml = <<<HTML
<div class="card mb-3">
<div class="card-header">{$this->trans('ccu.ccu.statistics')}</div>
<div class="card-body">
<div class="row">
<div class="col-md-4">
<div class="info-box">
<span class="info-box-icon bg-info"><i class="fa fa-chart-line"></i></span>
<div class="info-box-content">
<span class="info-box-text">{$this->trans('ccu.ccu.max_concurrent')}</span>
<span class="info-box-number">{$maxValue}</span>
</div>
</div>
</div>
<div class="col-md-4">
<div class="info-box">
<span class="info-box-icon bg-success"><i class="fa fa-chart-area"></i></span>
<div class="info-box-content">
<span class="info-box-text">{$this->trans('ccu.ccu.min_concurrent')}</span>
<span class="info-box-number">{$minValue}</span>
</div>
</div>
</div>
<div class="col-md-4">
<div class="info-box">
<span class="info-box-icon bg-warning"><i class="fa fa-chart-bar"></i></span>
<div class="info-box-content">
<span class="info-box-text">{$this->trans('ccu.ccu.avg_concurrent')}</span>
<span class="info-box-number">{$avgValue}</span>
</div>
</div>
</div>
</div>
</div>
</div>
HTML;
// 预先计算JSON数据
$timestampsJson = $this->jsonEncode($timestamps);
$valuesJson = $this->jsonEncode($values);
// 直接使用JavaScript创建ECharts图表
$chartId = 'ccu.php-chart-' . uniqid();
$chartScript = <<<JS
$(function() {
// 确保DOM元素已加载
var chartDom = document.getElementById('{$chartId}');
if (!chartDom) {
console.error("找不到图表DOM元素: {$chartId}");
return;
}
if (typeof echarts === 'undefined') {
console.error("ECharts库未加载");
return;
}
var myChart = echarts.init(chartDom);
var timestamps = (typeof $timestampsJson !== 'undefined' && Array.isArray($timestampsJson)) ? $timestampsJson : [];
var values = (typeof $valuesJson !== 'undefined' && Array.isArray($valuesJson)) ? $valuesJson : [];
try {
console.log('图表数据:', JSON.stringify({ timestamps: timestamps, values: values }));
} catch (e) {
console.error('无法序列化图表数据:', e);
console.log('timestamps长度:', timestamps.length);
console.log('values长度:', values.length);
}
var option = {
title: {
text: '{$this->trans('ccu.ccu.data_statistics')}'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['CCU']
},
// 添加工具箱,包含图表类型切换功能
toolbox: {
feature: {
saveAsImage: {title: '{$this->trans('ccu.ccu.save_as_image')}'},
dataView: {title: '{$this->trans('ccu.ccu.data_view')}', lang: ['{$this->trans('ccu.ccu.data_view')}', '{$this->trans('ccu.ccu.close')}', '{$this->trans('ccu.ccu.refresh')}']},
magicType: {
type: ['line', 'bar'],
title: {
line: '{$this->trans('ccu.ccu.switch_to_line')}',
bar: '{$this->trans('ccu.ccu.switch_to_bar')}',
// stack: '切换为堆叠'
}
},
restore: {title: '{$this->trans('ccu.ccu.restore')}'}
}
},
// 添加数据缩放组件(滚动轴)
dataZoom: [
{
type: 'slider', // 滑动条型数据缩放组件
show: true,
xAxisIndex: [0],
start: 0,
end: 100,
filterMode: 'filter'
},
{
type: 'inside', // 内置型数据缩放组件(鼠标滚轮缩放)
xAxisIndex: [0],
start: 0,
end: 100,
filterMode: 'filter'
}
],
grid: {
left: '3%',
right: '4%',
bottom: '13%', // 增加底部空间以容纳滚动轴
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: timestamps,
axisLabel: {
rotate: 45,
interval: 'auto'
}
},
yAxis: {
type: 'value',
name: 'CCU'
},
series: [
{
name: 'CCU',
type: 'line',
smooth: true,
data: values,
markPoint: {
data: [
{type: 'max', name: '{$this->trans('ccu.ccu.max_value')}'},
{type: 'min', name: '{$this->trans('ccu.ccu.min_value')}'}
]
},
markLine: {
data: [
{type: 'average', name: '{$this->trans('ccu.ccu.avg_value')}'}
]
}
}
]
};
// 使用配置项显示图表
try {
myChart.setOption(option);
} catch (e) {
console.error("设置图表选项时出错:", e);
}
// 响应窗口大小变化
window.addEventListener('resize', function() {
if (myChart && typeof myChart.resize === 'function') {
myChart.resize();
}
});
});
JS;
// 添加脚本到页面
\Dcat\Admin\Admin::script($chartScript);
// 添加额外的调试信息
\Dcat\Admin\Admin::script(<<<JS
console.log("ECharts对象是否存在: " + (typeof echarts !== 'undefined'));
console.log("jQuery对象是否存在: " + (typeof $ !== 'undefined'));
console.log("图表容器ID: " + "{$chartId}");
JS);
// 创建图表容器
$chartHtml = <<<HTML
<div class="card mb-3">
<div class="card-header">
<div class="d-flex justify-content-between align-items-center">
<span>{$this->trans('ccu.ccu.data_chart')}</span>
</div>
</div>
<div class="card-body">
<div id="{$chartId}" style="width: 100%; height: 500px;"></div>
</div>
</div>
HTML;
return $content
->header($this->trans('ccu.ccu.data_statistics'))
->description($this->trans('ccu.ccu.daily_concurrent_users'))
->body($formHtml)
->body($statsHtml)
->body($chartHtml);
}
$this->trans(‘ccu.ccu.data_statistics’) 此方法是我自定义的辅助翻译方法,你可以在这里正常编写自己的文字,例如把$this->trans(‘ccu.ccu.data_statistics’) 替换为”标题”,或者你自定义的文本内容
效果图如下,
推荐文章: