Вопрос или проблема
У меня есть веб-приложение Streamlit, которое использует таблицу AG Grid для отображения данных. В рамках приложения пользователь должен обновить прогноз. Прогноз затем сравнивается с бюджетом. Если есть отклонение, то пользователь должен ввести комментарий. Чтобы указать это, я хотел бы выделить ячейку Комментария для данной строки красным цветом в зависимости от различных критериев:
- Комментарий пустой, но есть отклонение
- Комментарий не изменился, но отклонение изменилось (прогноз обновлен)
Также я хотел бы указать, что комментарий не был сохранен, но пользователь обновил комментарий
В моем JS-коде форматирование работает, НО только после того, как я попытаюсь отредактировать комментарий. Расчет отклонения отображается сразу после обновления прогноза, но форматирование ячейки комментария не обновляется.
Ниже вы можете увидеть, что отклонение присутствует. Но только после редактирования комментария, ввода ничего и выбора другой ячейки, форматирование обновляется.
Я думал о том, чтобы использовать ValueFormatter, но не могу заставить его работать.
// Логика для обязательного комментария к прогнозу
if (params.colDef.field === 'forecast_comment' && params.data.hierarchy_level ===4) {{
if (!(params.data.forecast_comment === params.data.unchanged_comment)) {{
styles.backgroundColor="{comment_required_unsaved_background}";
}}
else if (params.data['annual_budget'] !== params.data['annual_forecast']
&& !params.data.forecast_comment) {{
styles.backgroundColor="{comment_required_empty_background}";
}}
else if (params.data['annual_budget'] !== params.data['annual_forecast']
&& params.data.annual_budget - params.data.annual_forecast !== params.data.forecast_variance) {{
styles.backgroundColor="{comment_required_unsaved_background}";
}}
}}
Вот как я настраиваю свой столбец:
gb.configure_column("forecast_comment",
header_name="Комментарий прогноза",
cellStyle=jscode_comments,
cellClass="custom-cell-text",
wrapText=True, editable=make_forecast_editable,
cellEditorPopup=True,
cellEditor="agLargeTextCellEditor",
cellEditorParams={'maxLength': 200}, minWidth=300,
maxWidth=800)
Я вставил свой JS-код в качестве valueFormatter и забыл кое-что простое и глупое — вернуть стили…
jscode_format_forecast_comment = JsCode(f"""
function forecastCommentValueFormatter(params) {{
let styles = {{ 'white-space': 'pre-wrap' }}; // Сохранять пробелы и переносы строк
if (params.colDef.field === 'forecast_comment' && params.data.hierarchy_level ===4) {{
if (!(params.data.forecast_comment === params.data.unchanged_comment)) {{
styles.backgroundColor="{comment_required_unsaved_background}";
}}
else if (params.data['annual_budget'] !== params.data['annual_forecast']
&& !params.data.forecast_comment) {{
styles.backgroundColor="{comment_required_empty_background}";
}}
else if (params.data['annual_budget'] !== params.data['annual_forecast']
&& params.data.annual_budget - params.data.annual_forecast !== params.data.forecast_variance) {{
styles.backgroundColor="{comment_required_unsaved_background}";
}}
}}
return styles;
}}
""")
Ответ или решение
Для решения вашей задачи по форматированию ячеек в AG Grid с учетом комментариев и их состояния, важно учитывать несколько критериев, которые должны быть реализованы в коде. Вы хотите выделить ячейки комментариев красным цветом в зависимости от определенных условий, и нужно сделать так, чтобы изменения отображались сразу при обновлении данных, а не только после редактирования ячейки.
Проблемы в текущем подходе
-
Обновление стилей: Обратите внимание, что стандартный механизм AG Grid не всегда автоматически обновляет стили ячеек при изменении данных. Это связано с тем, что визуальные обновления в AG Grid могут быть не привязаны к логике ваших данных.
-
Использование
valueFormatter
: Ваш текущий подход сvalueFormatter
не включает возврат стилей, что приводит к отсутствию визуальных изменений.
Решение проблемы
Шаг 1: Изменение логики форматирования
Необходимо переопределить подход к форматированию ячейки и вместо использования valueFormatter
использовать cellStyle
или cellClass
с динамической логикой.
Шаг 2: Код для динамического форматирования ячейки
Вот пример, как может быть настроен ваш cellStyle
, чтобы учитывать все условия:
function jscode_comments(params) {
let styles = {
'white-space': 'pre-wrap' // Сохраняем пробелы и переносы
};
if (params.data.hierarchy_level === 4) {
// Если есть несоответствие и комментарий пустой
if (params.data.annual_budget !== params.data.annual_forecast && !params.data.forecast_comment) {
styles.backgroundColor = "red"; // Цвет для пустого комментария при несоответствии
}
// Если комментарий не изменился, но изменилось несоответствие
else if (params.data.forecast_comment === params.data.unchanged_comment && params.data.forecast_variance !== (params.data.annual_budget - params.data.annual_forecast)) {
styles.backgroundColor = "orange"; // Цвет для несохраненного комментария
}
// Если комментарий изменен
else if (params.data.forecast_comment !== params.data.unchanged_comment) {
styles.backgroundColor = "yellow"; // Цвет для измененного комментария
}
}
return styles;
}
Шаг 3: Конфигурация столбца
Затем вам нужно будет применить этот метод к конфигурации столбца в AG Grid:
gridOptions.columnDefs = [
{
headerName: "Forecast Comment",
field: "forecast_comment",
cellStyle: jscode_comments,
cellClass: "custom-cell-text",
wrapText: true,
editable: true,
cellEditor: "agLargeTextCellEditor",
cellEditorParams: { 'maxLength': 200 },
minWidth: 300,
maxWidth: 800
}
];
Шаг 4: Обновление состояния ячеек при изменении прогнозов
Необходимо убедиться, что состояние ячеек обновляется при каждом изменении прогноза. Это можно сделать, вызвав gridOptions.api.refreshCells()
после изменения данных:
// Пример обновления прогноза
function updateForecast(newForecast) {
// Логика обновления данных
// ...
// Обновляем ячейки для обновления стилей
gridOptions.api.refreshCells();
}
Итог
Таким образом, при выполнении всех этих шагов вы сможете динамически изменять стили ячеек в AG Grid в зависимости от состояния комментариев и прогноза. Это обеспечит, что все визуальные изменения отображаются сразу, без необходимости редактирования ячейки.