본문 바로가기
카테고리 없음

BlazorDatasheet

by keisoft 2025. 4. 5.

BlazorDatasheet에서 데이터 정렬 시 셀 색상을 유지하는 문제를 해결하기 위한 접근 방식을 제안해 드리겠습니다.

먼저 말씀하신 아이디어는 정확합니다. 각 행(row)의 데이터와 색상 정보를 함께 관리하는 것이 핵심입니다. 이를 효율적으로 구현하는 방법을 알아보겠습니다.

해결 방안

  1. 복합 데이터 모델 사용
    • 각 행에 대한 원본 데이터와 스타일 정보를 함께 포함하는 래퍼 클래스를 만듭니다.
  2. 인덱스 기반 매핑
    • 데이터의 원래 인덱스를 키로 사용하여 셀 색상 정보를 Dictionary에 저장합니다.
  3. 데이터와 스타일의 동시 정렬
    • 정렬 시 데이터와 색상 정보를 함께 정렬하도록 합니다.

성능 최적화 방안

  1. 메모리 최적화
    • 스타일 정보가 있는 셀만 스타일 Dictionary에 저장하여 메모리 사용량을 줄입니다.
    • 대량의 데이터를 다룬다면 필요한 열에만 스타일 정보를 저장하세요.
  2. 연산 최적화
    • 정렬 시 전체 객체를 복사하지 않고 참조만 재정렬하여 처리합니다.
    • 변경된 셀만 업데이트하는 방식을 고려하세요.
  3. 지연 로딩(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; }
}