using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Windows.Input; using SmartAquaViewer.Controls; using SmartAquaViewer.DataAnalysis; using SmartAquaViewer.Model; namespace SmartAquaViewer.ViewModel { public class GreenHouseGasViewModel : INotifyPropertyChanged { public GraphControlViewModel GraphControlVM { get; } = new GraphControlViewModel(); public ObservableCollection GraphTypes { get; } public List WaterQualityList { get; set; } private int _selectedGraphIndex = -1; public int SelectedGraphIndex { get => _selectedGraphIndex; set { if (_selectedGraphIndex != value) { _selectedGraphIndex = value; OnPropertyChanged(); // 인덱스가 바뀌면 enum도 맞춰준다 if (value >= 0 && value < GraphTypes.Count) SelectedGraphType = GraphTypes[value]; } } } private GraphType _selectedGraphType; public GraphType SelectedGraphType { get => _selectedGraphType; set { if (_selectedGraphType != value) { _selectedGraphType = value; OnPropertyChanged(); OnPropertyChanged(nameof(ShowXSelector)); RebuildFieldCandidates(); var idx = GraphTypes.IndexOf(value); if (idx != -1 && idx != _selectedGraphIndex) { _selectedGraphIndex = idx; OnPropertyChanged(nameof(SelectedGraphIndex)); } } } } public bool ShowXSelector => SelectedGraphType == GraphType.SCATTER; // [필드 후보 목록] 탭/시스템에 따라 달라짐 public ObservableCollection AvailableFields { get; } = new(); // [X축 후보/선택] public ObservableCollection XFieldCandidates { get; } = new(); private FieldItem? _selectedXField; public FieldItem? SelectedXField { get => _selectedXField; set { if (_selectedXField != value) { _selectedXField = value; OnPropertyChanged(); } } } // [Y축 후보/선택] — Line/Step: 다중, Scatter/Box: 단일 public ObservableCollection YFieldCandidates { get; } = new(); // 다중 선택(Y)용 public ObservableCollection SelectedYFields { get; } = new(); // 단일 선택(Y)용 private FieldItem? _selectedYField; public FieldItem? SelectedYField { get => _selectedYField; set { if (_selectedYField != value) { _selectedYField = value; OnPropertyChanged(); } } } private bool _showMarkers; // Line public bool ShowMarkers { get => _showMarkers; set { _showMarkers = value; OnPropertyChanged(); } } private bool _showLegends; public bool ShowLegends { get => _showLegends; set { _showLegends = value; OnPropertyChanged(); } } private bool _useAverage; public bool UseAverage { get => _useAverage; set { _useAverage = value; OnPropertyChanged(); } } private bool _isDonut; public bool IsDonut { get => _isDonut; set { _isDonut = value; OnPropertyChanged(); } } public ICommand DrawGraphCommand { get; } public GreenHouseGasViewModel() { WaterQualityList = Datas.Instance.GetWaterQualityVO().ToList(); GraphTypes = new ObservableCollection { GraphType.LINE, GraphType.STACKAREA, GraphType.PIE }; DrawGraphCommand = new RelayCommand(DrawGraph); RebuildAvailableFields(); RebuildFieldCandidates(); } private void DrawGraph(object obj) { switch (SelectedGraphType) { case GraphType.LINE: GraphControlVM.SetMultiLineGraph(WaterQualityList, SelectedYFields, DataType.GreenhouseGas, ShowMarkers, ShowLegends); break; case GraphType.STACKAREA: GraphControlVM.SetStackAreaPlot(WaterQualityList, SelectedYFields, DataType.GreenhouseGas, ShowMarkers, ShowLegends); break; case GraphType.PIE: GraphControlVM.SetPieChart(WaterQualityList, SelectedYFields, DataType.GreenhouseGas, UseAverage, IsDonut); break; default: break; } } private void RebuildAvailableFields() { AvailableFields.Clear(); // 공통 시간 AvailableFields.Add(new FieldItem { Name = "RecordedTime", Display = "시간", DataType = typeof(DateTime) }); AvailableFields.Add(new FieldItem { Name = "TotalGreenhouseGas", Display = "총 배출량", DataType = typeof(double), Kind = StepFieldKind.Energy }); AvailableFields.Add(new FieldItem { Name = "Filtering.SandFilterGreenhouseGas", Display = "모래여과기", DataType = typeof(double), Kind = StepFieldKind.Energy }); AvailableFields.Add(new FieldItem { Name = "Filtering.CirculationPumpGreenhouseGas", Display = "순환펌프", DataType = typeof(double), Kind = StepFieldKind.Energy }); AvailableFields.Add(new FieldItem { Name = "Filtering.HeatPumpGreenhouseGas", Display = "히트펌프", DataType = typeof(double), Kind = StepFieldKind.Energy }); AvailableFields.Add(new FieldItem { Name = "Filtering.AirBlowerGreenhouseGas", Display = "에어브로와", DataType = typeof(double), Kind = StepFieldKind.Energy }); AvailableFields.Add(new FieldItem { Name = "Sterilizing.OzoneGeneratorGreenhouseGas", Display = "오존발생기", DataType = typeof(double), Kind = StepFieldKind.Energy }); AvailableFields.Add(new FieldItem { Name = "Sterilizing.UVSterilizerGreenhouseGas", Display = "자외선 살균기", DataType = typeof(double), Kind = StepFieldKind.Energy }); AvailableFields.Add(new FieldItem { Name = "Sterilizing.OzoneDissolverGreenhouseGas", Display = "오존용해장치", DataType = typeof(double), Kind = StepFieldKind.Energy }); AvailableFields.Add(new FieldItem { Name = "Sterilizing.ExcessOzoneDestroyerGreenhouseGas", Display = "배오존장치", DataType = typeof(double), Kind = StepFieldKind.Energy }); } private void RebuildFieldCandidates() { // 후보 초기화 XFieldCandidates.Clear(); YFieldCandidates.Clear(); // X축: 시간 우선 foreach (var f in AvailableFields) { XFieldCandidates.Add(f); if (SelectedGraphType == GraphType.LINE || SelectedGraphType == GraphType.STACKAREA) break; } SelectedXField = AvailableFields.FirstOrDefault(f => f.DataType == typeof(DateTime)) ?? AvailableFields.FirstOrDefault(); IEnumerable src = AvailableFields; if (SelectedGraphType is GraphType.LINE or GraphType.STACKAREA or GraphType.PIE) { // 수치형만 (LINE/STACKAREA/PIE 연속값 위주) src = src.Where(f => f.DataType == typeof(double)); } // Y축 후보: 수치형 foreach (var f in src) { if (SelectedGraphType is GraphType.STACKAREA or GraphType.PIE && f.Name.Equals("TotalEnergy")) continue; YFieldCandidates.Add(f); } // 기본 선택 세팅 (타입별) SelectedYFields.Clear(); SelectedYField = null; switch (SelectedGraphType) { case GraphType.LINE: //var def = YFieldCandidates.FirstOrDefault(); //if (def != null) SelectedYFields.Add(def); break; case GraphType.STACKAREA: SelectedYField = YFieldCandidates.FirstOrDefault(); break; case GraphType.PIE: //SelectedYField = YFieldCandidates.FirstOrDefault(); break; } OnPropertyChanged(nameof(SelectedYFields)); } public event PropertyChangedEventHandler? PropertyChanged; private void OnPropertyChanged([CallerMemberName] string? name = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); } }