BlazorDatasheet에서 데이터 정렬 시 셀 색상을 유지하는 문제를 해결하기 위한 접근 방식을 제안해 드리겠습니다.
먼저 말씀하신 아이디어는 정확합니다. 각 행(row)의 데이터와 색상 정보를 함께 관리하는 것이 핵심입니다. 이를 효율적으로 구현하는 방법을 알아보겠습니다.
해결 방안
- 복합 데이터 모델 사용
- 각 행에 대한 원본 데이터와 스타일 정보를 함께 포함하는 래퍼 클래스를 만듭니다.
- 인덱스 기반 매핑
- 데이터의 원래 인덱스를 키로 사용하여 셀 색상 정보를 Dictionary에 저장합니다.
- 데이터와 스타일의 동시 정렬
- 정렬 시 데이터와 색상 정보를 함께 정렬하도록 합니다.
성능 최적화 방안
- 메모리 최적화
- 스타일 정보가 있는 셀만 스타일 Dictionary에 저장하여 메모리 사용량을 줄입니다.
- 대량의 데이터를 다룬다면 필요한 열에만 스타일 정보를 저장하세요.
- 연산 최적화
- 정렬 시 전체 객체를 복사하지 않고 참조만 재정렬하여 처리합니다.
- 변경된 셀만 업데이트하는 방식을 고려하세요.
- 지연 로딩(Lazy Loading) 사용
- 화면에 보이는 데이터만 처리하도록 가상화(Virtualization)를 구현합니다.
위 코드에서 DataRowWithStyle<T> 클래스는 원본 데이터와 스타일 정보를 함께 관리하며, DataSheetManager<T> 클래스는 정렬 시 데이터와 스타일을 모두 유지합니다. 이 방식을 사용하면 정렬 후에도 각 행에 대한 색상 정보가 유지됩니다.
추가적인 최적화가 필요하시면 말씀해 주세요.
// 1. 데이터와 색상 정보를 함께 저장할 래퍼 클래스 정의
public class DataRowWithStyle<T>
{
public T Data { get; set; }
public int OriginalIndex { get; set; }
public Dictionary<string, string> CellStyles { get; set; } = new Dictionary<string, string>();
public string RowStyle { get; set; }
}
// 2. 데이터와 셀 색상을 함께 관리하는 서비스 클래스
public class DataSheetManager<T>
{
private List<DataRowWithStyle<T>> _items = new List<DataRowWithStyle<T>>();
private List<T> _originalData;
// 초기 데이터 설정 및 스타일 정보 연결
public void Initialize(List<T> data)
{
_originalData = data;
_items.Clear();
for (int i = 0; i < data.Count; i++)
{
_items.Add(new DataRowWithStyle<T>
{
Data = data[i],
OriginalIndex = i,
RowStyle = "", // 기본 행 스타일 설정
CellStyles = new Dictionary<string, string>()
});
}
}
// 행 스타일 설정
public void SetRowStyle(int index, string style)
{
if (index >= 0 && index < _items.Count)
{
_items[index].RowStyle = style;
}
}
// 셀 스타일 설정
public void SetCellStyle(int rowIndex, string columnName, string style)
{
if (rowIndex >= 0 && rowIndex < _items.Count)
{
_items[rowIndex].CellStyles[columnName] = style;
}
}
// 데이터 정렬 - 속성 이름과 정렬 방향에 따라
public List<T> SortData<TKey>(Func<T, TKey> keySelector, bool ascending = true)
{
if (ascending)
{
_items = _items.OrderBy(item => keySelector(item.Data)).ToList();
}
else
{
_items = _items.OrderByDescending(item => keySelector(item.Data)).ToList();
}
// 정렬된 데이터만 반환
return _items.Select(item => item.Data).ToList();
}
// 특정 행의 스타일 가져오기
public string GetRowStyle(int index)
{
return index >= 0 && index < _items.Count ? _items[index].RowStyle : "";
}
// 특정 셀의 스타일 가져오기
public string GetCellStyle(int rowIndex, string columnName)
{
if (rowIndex >= 0 && rowIndex < _items.Count && _items[rowIndex].CellStyles.ContainsKey(columnName))
{
return _items[rowIndex].CellStyles[columnName];
}
return "";
}
// 현재 정렬된 데이터 반환
public List<T> GetCurrentData()
{
return _items.Select(item => item.Data).ToList();
}
}
// 3. Blazor 컴포넌트에서 사용 예시
@page "/datasheet-example"
@using BlazorDatasheet
@inject DataSheetManager<MyDataModel> DataManager
<h3>데이터 시트 예제</h3>
<div>
<button @onclick="() => SortData(x => x.Name)">이름으로 정렬</button>
<button @onclick="() => SortData(x => x.Value, false)">값 내림차순 정렬</button>
</div>
<BlazorDatasheet Data="@CurrentData" TItem="MyDataModel">
<DatasheetColumn Field="@nameof(MyDataModel.Name)" Title="이름">
<CellTemplate>
<div style="@GetCellStyleString(context.RowIndex, nameof(MyDataModel.Name))">
@context.Item.Name
</div>
</CellTemplate>
</DatasheetColumn>
<DatasheetColumn Field="@nameof(MyDataModel.Value)" Title="값">
<CellTemplate>
<div style="@GetCellStyleString(context.RowIndex, nameof(MyDataModel.Value))">
@context.Item.Value
</div>
</CellTemplate>
</DatasheetColumn>
</BlazorDatasheet>
@code {
private List<MyDataModel> CurrentData { get; set; } = new List<MyDataModel>();
protected override void OnInitialized()
{
// 초기 데이터 설정
var initialData = new List<MyDataModel>
{
new MyDataModel { Name = "항목 1", Value = 10 },
new MyDataModel { Name = "항목 2", Value = 20 },
new MyDataModel { Name = "항목 3", Value = 15 },
};
DataManager.Initialize(initialData);
CurrentData = initialData;
// 로직에 따라 색상 설정
ApplyColorLogic();
}
private void ApplyColorLogic()
{
// 예: 값이 15보다 큰 셀은 빨간색으로 표시
for (int i = 0; i < CurrentData.Count; i++)
{
if (CurrentData[i].Value > 15)
{
DataManager.SetCellStyle(i, nameof(MyDataModel.Value), "background-color: #ffdddd;");
}
// 특정 조건에 따른 행 스타일 설정
if (i % 2 == 0)
{
DataManager.SetRowStyle(i, "background-color: #f9f9f9;");
}
}
}
private void SortData<TKey>(Func<MyDataModel, TKey> keySelector, bool ascending = true)
{
CurrentData = DataManager.SortData(keySelector, ascending);
StateHasChanged();
}
private string GetCellStyleString(int rowIndex, string columnName)
{
return DataManager.GetCellStyle(rowIndex, columnName);
}
}
// 데이터 모델 예시
public class MyDataModel
{
public string Name { get; set; }
public int Value { get; set; }
}