WPF FlexChart WPF Chart 컨트롤의 비동기 드릴다운 옵션
페이지 정보
작성자 GrapeCity 작성일 2022-10-12 09:11 조회 563회 댓글 0건본문
첨부파일
관련링크
바로 이런 경우 차트에 드릴다운이 필요합니다. 드릴다운은 플롯과 관련된 추가 데이터가 포함된 새 하위 차트를 열기 위해 원본 또는 부모 차트에서 개별 데이터 플롯을 클릭하는 경우입니다. 이러한 추가/하위 데이터는 요구 사항에 따라 요구 시 API/데이터베이스에서 가져올 수 있습니다. 충분히 큰 데이터 집합을 사용하면 끝없는 수준의 드릴다운을 만들 수 있습니다.
이 블로그에서는 ComponentOne WPF FlexChart를 사용하여 비동기 드릴다운을 구현하는 방법을 설명합니다.
이번 사용 사례에서는 거래소에 등록된 화폐와 가격 차트로 드릴다운하는 암호화폐 거래소를 사용합니다.
데이터 소스 만들기
가장 먼저 거래, 화폐 및 가격 데이터를 나타낼 몇 가지 구조를 만듭니다. 따라서 동일하게 다음 클래스를 사용합니다.
public class CryptoExchange { public int Id { get; set; } public string ExchangeName { get; set; } public int ListedCurrencies { get; set; } } public class CryptoCurrency { public int Id { get; set; } public int ExchangeId { get; set; } public string CurrencyName { get; set; } public string Symbol { get; set; } public double CurrentPrice { get; set; } } public class PriceData { public int Id { get; set; } public int CurrencyId { get; set; } public double High { get; set; } public double Low { get; set; } public double Open { get; set; } public double Close { get; set; } public DateTime Date { get; set; } }
거래, 화폐 및 가격 데이터를 저장/가져오기 위해 다음 DataService 클래스를 사용합니다. 요컨대, 이 클래스는 드릴다운 중 각 데이터를 가져오는 REST API를 모방합니다.
public class DataService { public Task<IEnumerable<CryptoExchange>> FetchTop5CryptoExchanges() { } public async Task<IEnumerable<CryptoCurrency>> FetchTop4CryptoCurrencies(int exchangeId) { } public async Task<IEnumerable<PriceData>> FetchMonthlyPriceData(int currencyId) { } public async Task<IEnumerable<PriceData>> FetchWeeklyPriceData(int currencyId, int month) { } public async Task<IEnumerable<PriceData>> FetchDailyPriceData(int currencyId, int month, int week) { } }
비동기식 드릴다운 관리자 만들기
이제 데이터 소스를 사용할 준비가 되었습니다. FlexChart를 사용하여 드릴다운을 수행하도록 허용하는 드릴다운 관리자를 구현합니다.
public interface IDrillDownManager { /// Fires on drill down. event EventHandler<DrillEventArgs> DrilledDown; /// Fires on drill up. event EventHandler<DrillEventArgs> DrilledUp; // Gets the Drill depth (Number of steps). int Depth { get; } // Gets the current drilled level. int CurrentLevel { get; } // Gets the path that has been navigated/drilled. IEnumerable<StepResult> DrilledPath { get; } // Registers a drill down step which will be executed in the order they are added. void AddDrillDownStep(IDrillDownStep step); // Drill down one level. Task DrillDown(Point point); // Drill up one level. Task DrillUp(); // Drills to specific path. Task DrillToPath(StepResult path); // Resets the drill level and clears the drilling history. void Reset(); }
위 코드에서 볼 수 있는 것처럼 AddDrillDownStep이라는 메서드가 있습니다.
public void AddDrillDownStep(IDrillDownStep step) { _drillDownSteps.Add(step); }
이 메서드를 사용하면 드릴다운 관리자로 여러 드릴다운 스텝을 등록할 수 있습니다(IDrillDownStep 구현). 이러한 스텝은 등록된 순서대로 실행됩니다. 드릴다운 스텝에 대해서는 이 블로그의 뒷부분에서 다룰 것입니다.
이제 가장 중요한 부분을 살펴보면, IDrillDownManager의 DrillDown 메서드를 사용하여 FlexChart에서 비동기식으로 드릴다운합니다.
public virtual async Task DrillDown(Point point) { // perform hittest on chart var hitTest = _flexChart.HitTest(point); if (CanDrillDown(hitTest)) { _currentLevel++; var drillDownStep = _drillDownSteps[_currentLevel]; var result = await drillDownStep.Execute(hitTest); // execute step // add to history _drillDownHistory.Push(new DrillInfo() { HitTestInfo = hitTest, StepPerformed = drillDownStep, }); _drilledPath.Add(result); OnDrilledDown(new DrillEventArgs() { Level = _currentLevel }); } } protected bool CanDrillDown(HitTestInfo hitTest) { if (_drillDownSteps.Count == 0) return false; return _currentLevel < Depth && _drillDownSteps[_currentLevel + 1].CanExecute(hitTest); }
위 코드에서는 IDrillDownStep의 CanExecute 메서드를 사용하여 드릴다운이 허용되는지 여부를 기본적으로 확인하는 CanDrillDown 메서드를 확인할 수 있습니다. 드릴다운이 허용되면 드릴다운 스텝이 실행되어 드릴업 작업에 대한 기록(드릴된 스텝)을 포함한 스택에 추가됩니다.
참고: IDrillDownStep의 CanExecute 메서드는 몇 가지 조건을 기준으로 FlexChart 드릴다운을 허용/금지하는 로직을 포함합니다. 예를 들어, 데이터 요소에서 5픽셀 이내의 거래에서 마우스를 클릭한 경우에만 드릴다운합니다.
마찬가지로, 기록 스택에 저장된 스텝을 실행하여 드릴업 작업을 구현할 수 있습니다. 그러나 이 블로그에서는 간단하게 설명하기 위해 DrillUp 메서드에 대한 코드 조각은 포함하지 않았습니다. 전체 구현 코드는 을 참조하세요.
드릴다운 스텝 만들기
이제 드릴다운 스텝이 IDrillDownStep 인터페이스에서 구현된다는 내용을 이해했습니다. 이 인터페이스의 구현에는 다른 드릴 수준에서 받은 입력을 바탕으로 FlexChart를 구성하는 로직이 포함됩니다.
public interface IDrillDownStep { /// Gets whether this step can execute or not. bool CanExecute(HitTestInfo hitTest); /// Executes the step. Task<StepResult> Execute(HitTestInfo hitTest); }
이 블로그에서 언급한 것처럼 가상화폐 거래소를 사용하여 거래소의 등록 화폐 및 가격 차트를 드릴다운할 것입니다.
사용 사례에 따라 다음 단계를 수행해야 합니다.
가상화폐 거래소에 등록된 상위 5개 화폐의 세로 막대형 차트를 표시합니다.
1단계에서 선택한 화폐의 월별 캔들 차트를 표시합니다.
2단계에서 선택한 월 캔들의 주별 캔들 차트를 표시합니다.
3단계에서 선택한 주 캔들의 일별 캔들 차트를 표시합니다.
첫 번째 드릴다운 스텝을 만드는 것부터 시작해 보겠습니다. 즉, 거래소에 등록된 상위 4개 화폐를 표시해 보겠습니다.
public class ExchangeTop4CurrenciesStep : IDrillDownStep { private DataService _dataService; public ExchangeTop4CurrenciesStep(DataService dataService) { _dataService = dataService; } public bool CanExecute(HitTestInfo hitTest) { // hittest object recieved from drill down manager return hitTest != null && hitTest.Distance < 5 && hitTest.ChartElement == ChartElement.PlotArea && hitTest.Series != null && hitTest.Item is CryptoExchange; } public async Task<StepResult> Execute(HitTestInfo hitTest) { var exchange = hitTest.Item as CryptoExchange; var currencies = await _dataService.FetchTop4CryptoCurrencies(exchange.Id); var chart = hitTest.Series.Chart as FlexChart; // resets chart Helpers.ResetChart(chart); chart.ItemsSource = currencies.ToList(); chart.Header = string.Format(StringResources.Exchange, exchange.ExchangeName); chart.DataLabel.Position = LabelPosition.Top; chart.DataLabel.Content = "{value}"; chart.ToolTipContent = "Currency : {CurrencyName}\nSymbol : {Symbol}\nCurrent Price : {CurrentPrice}"; // series configuration chart.Series.Clear(); chart.Series.Add(new Series() { Binding = "CurrentPrice", BindingX = "CurrencyName" }); // axis configuration chart.AxisX.Title = "Crypto Currencies"; chart.AxisY.Title = "Current Price"; chart.AxisY.Format = "C"; chart.AxisX.TitleStyle = chart.HeaderStyle = chart.AxisY.TitleStyle = Helpers.AxisStyle; return new StepResult() { Value = exchange.ExchangeName }; } }
Execute 메서드 내에서 거래소의 상위 5개 암호화폐를 가져오는 데 사용되는 DataService 클래스를 이 스텝에 주입했습니다. 나중에 FlexChart의 ItemsSource, Series, Axis 등의 속성을 구성했습니다.
위 코드에서 이 StepResult가 무엇을 반환하는지 궁금할 수 있습니다. StepResult는 실행된 각 스텝에 대한 고유한 식별자 역할을 합니다.
이 경우에는 IDrillDownManager의 DrilledPath 속성 및 DrillToPath 메서드가 사용되었습니다. DrilledPath 속성은 실행될 때 등록된 스텝에서 반환되는 모든 StepResult를 저장합니다. 따라서 인스턴스를 IDrillDownManager의 DrillToPath 메서드에 전달하여 드릴다운된 특정 스텝으로 이동할 수 있습니다.
참고: 각 스텝은 StepResult의 새 인스턴스를 반환해야 합니다.
마찬가지로, 위에서 언급한 접근 방식에 따라 다른 스텝 3개를 만들 수 있습니다. (코드는 첨부된 샘플을 참조하세요.)
FlexChart와 드릴다운 관리자 통합
드릴다운 관리자 및 스텝을 사용할 준비가 되었으며 이제 FlexChart와 통합할 차례입니다. FlexChart가 포함된 프로젝트를 이미 만들었다고 가정해 보겠습니다. 이제 FlexChart의 초기 보기를 구성합니다. 예를 들어, 이 경우에는 다음과 같이 가상화폐 거래소의 상위 5개 화폐를 표시하는 세로 막대형 차트를 표시합니다.
var exchanges = await _dataService.FetchTop5CryptoExchanges(); chart.ItemsSource = exchanges.ToList(); chart.Header = "Top 5 Crypto Currency Exchanges"; chart.DataLabel.Position = LabelPosition.Top; chart.DataLabel.Content = "{value}"; chart.ToolTipContent = "Listed Currencies : {value}"; // series configuration chart.Series.Clear(); chart.Series.Add(new Series() { Binding = "ListedCurrencies", BindingX = "ExchangeName" }); // axis configuration chart.AxisX.Title = "Crypto Exchanges"; chart.AxisY.Title = "Listed Currencies"; chart.AxisX.TitleStyle = chart.HeaderStyle = chart.AxisY.TitleStyle = Helpers.AxisStyle; chart.AxisY.AxisLine = true;
그 결과는 다음과 같습니다.
완료하면 다음과 같이 드릴다운 관리자를 사용하여 드릴다운 스텝을 등록합니다.
_drillDownManager = new AsyncDrillDownManager(flexChart); // register drill down steps _drillDownManager.AddDrillDownStep(new ExchangeTop4CurrenciesStep(_dataService)); _drillDownManager.AddDrillDownStep(new MonthlyPriceChartStep(_dataService)); _drillDownManager.AddDrillDownStep(new WeeklyPriceChartStep(_dataService)); _drillDownManager.AddDrillDownStep(new DailyPriceChartStep(_dataService));
이제 드릴다운에 필요한 항목을 모두 설정했습니다. 남아 있는 유일한 단계는 FlexChart의 마우스 클릭 이벤트로 드릴다운 관리자를 사용하는 것입니다.
FlexChart의 MouseLeftButtonDown 내에서 IDrillDownManager의 DrillDown 메서드를 사용할 수 있도록 마우스 왼쪽 단추를 클릭하여 드릴다운합니다.
private async void OnFlexChartMouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { await _drillDownManager.DrillDown(e.GetPosition(flexChart)); }
마찬가지로, 드릴업을 위해 다음과 같이 FlexChart의 MouseRightButtonDown 이벤트를 사용할 수 있도록 마우스 오른쪽 버튼을 클릭합니다.
private async void OnFlexChartMouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) { await _drillDownManager.DrillUp(); }
이제 완성입니다! FlexChart를 사용하여 비동기 드릴다운을 구현했습니다.
지금 바로 ComponentOne을 다운로드하여 직접 테스트해보세요!
댓글목록
등록된 댓글이 없습니다.