Создание отчетов с графиками — задача, с которой рано или поздно сталкивается каждый разработчик на Yii2. Это не просто вывод таблицы, а целая история о данных, их агрегации и визуализации. В этой статье я расскажу, как подойти к этому процессу системно, какие инструменты выбрать и как избежать типичных ошибок.

Digital-студия WNDER

Выбор библиотеки для графиков

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. Это безопасно и удобно.

Правило: Всегда экранируйте данные при передаче в JavaScript, чтобы избежать XSS-уязвимостей. Используйте json_encode с флагами JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT.

Настройка сложных отчетов: фильтры и экспорт

Сложные отчеты редко обходятся без фильтров. Пользователь хочет выбрать период, категорию товара или менеджера. В Yii2 удобно использовать ActiveForm для построения формы фильтрации и передавать параметры в запрос.

Пример формы фильтра в представлении:


 'get']); ?>
    field($model, 'dateFrom')->input('date') ?>
    field($model, 'dateTo')->input('date') ?>
     '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