Создание отчетов с графиками — задача, с которой рано или поздно сталкивается каждый разработчик на Yii2. Это не просто вывод таблицы, а целая история о данных, их агрегации и визуализации. В этой статье я расскажу, как подойти к этому процессу системно, какие инструменты выбрать и как избежать типичных ошибок.
Выбор библиотеки для графиков
Yii2 сам по себе не рисует графики. Для визуализации нужно подключать сторонние JavaScript-библиотеки. Самые популярные варианты: Chart.js, Highcharts, Google Charts, ECharts. Каждая имеет свои сильные стороны.
Chart.js — легкий и простой, идеален для базовых диаграмм. Highcharts — мощный, но платный для коммерческого использования. Google Charts — бесплатный, но требует интернет-соединения. ECharts — отличный выбор для больших данных и сложных визуализаций.
Вот сравнительная таблица:
| Библиотека | Лицензия | Сложность | Лучше для |
|---|---|---|---|
| Chart.js | MIT | Низкая | Простые графики |
| Highcharts | Проприетарная | Средняя | Богатый функционал |
| Google Charts | Бесплатная | Средняя | Быстрый старт |
| ECharts | Apache 2.0 | Высокая | Сложные дашборды |
Мой совет: начните с Chart.js, если не уверены. Она проста и покрывает 80% потребностей.
Подготовка данных в Yii2
Прежде чем рисовать график, нужно собрать и агрегировать данные. В Yii2 удобно использовать ActiveRecord и QueryBuilder. Например, если нужно построить отчет по продажам за месяц, сгруппировав по дням, можно написать такой запрос:
$salesData = Order::find()
->select([
'DATE(created_at) AS date',
'SUM(total) AS total_amount',
'COUNT(*) AS order_count'
])
->where(['>=', 'created_at', date('Y-m-d', strtotime('-30 days'))])
->groupBy('DATE(created_at)')
->orderBy('date ASC')
->asArray()
->all();
Этот запрос вернет массив с датами, суммами и количеством заказов. Дальше эти данные нужно передать в представление и преобразовать в формат, понятный JavaScript-библиотеке.
Часто требуется более сложная агрегация: например, сравнение показателей за разные периоды или вычисление скользящего среднего. Yii2 позволяет использовать SQL-функции и даже писать подзапросы. Главное — не забывайте про индексы и кэширование, чтобы отчеты не тормозили.
Интеграция графиков в представление
Самый простой способ — передать данные из контроллера в представление и инициализировать график через JavaScript. Рассмотрим на примере Chart.js.
В контроллере:
public function actionReport()
{
$data = Order::find()
->select(['DATE(created_at) AS date', 'SUM(total) AS total'])
->groupBy('DATE(created_at)')
->orderBy('date ASC')
->asArray()
->all();
$dates = array_column($data, 'date');
$totals = array_column($data, 'total');
return $this->render('report', [
'dates' => $dates,
'totals' => $totals,
]);
}
В представлении подключаем Chart.js и рисуем график:
Обратите внимание: данные из PHP передаются в JavaScript через json_encode. Это безопасно и удобно.
json_encode с флагами JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT.
Настройка сложных отчетов: фильтры и экспорт
Сложные отчеты редко обходятся без фильтров. Пользователь хочет выбрать период, категорию товара или менеджера. В Yii2 удобно использовать ActiveForm для построения формы фильтрации и передавать параметры в запрос.
Пример формы фильтра в представлении:
'get']); ?>
= $form->field($model, 'dateFrom')->input('date') ?>
= $form->field($model, 'dateTo')->input('date') ?>
= Html::submitButton('Применить', ['class' => 'btn btn-primary']) ?>
В контроллере эти параметры добавляются в условия запроса. Не забудьте про валидацию и значения по умолчанию.
Экспорт отчетов — еще одна частая задача. Можно использовать расширения вроде kartik-v/yii2-export или phpoffice/phpspreadsheet для выгрузки в Excel. Графики в Excel экспортировать сложнее, но можно сохранять изображения через canvas.toDataURL() и вставлять их в файл.
Кэширование и оптимизация
Отчеты с большими данными могут быть медленными. Используйте кэширование Yii2 для сохранения результатов тяжелых запросов. Например, оберните запрос в Yii::$app->cache->getOrSet():
$data = Yii::$app->cache->getOrSet('report_data_' . $dateFrom . '_' . $dateTo, function () use ($dateFrom, $dateTo) {
return Order::find()
->select(['DATE(created_at) AS date', 'SUM(total) AS total'])
->where(['between', 'created_at', $dateFrom, $dateTo])
->groupBy('DATE(created_at)')
->asArray()
->all();
}, 3600); // кэш на час
Также стоит подумать о фоновой генерации отчетов через очереди (например, RabbitMQ или Redis) для очень больших выгрузок.
->createCommand()->rawSql — так вы увидите итоговый SQL и сможете оптимизировать его вручную.
Что в итоге
Построение сложных отчетов и графиков в Yii2 — это комбинация правильной подготовки данных, выбора подходящей библиотеки визуализации и грамотной интеграции. Начните с простых графиков на Chart.js, постепенно усложняя логику. Не забывайте про кэширование и безопасность. И помните: хороший отчет — тот, который быстро строится и легко читается.
Студия WNDER



