public List <GroupedRows> Bin(ColumnViewModel selected, List <Row> rows) { Linear linear = new Linear() { DomainStart = rows.Select(r => (Double)r.Cells[selected.Index].Content).Min(), DomainEnd = rows.Select(r => (Double)r.Cells[selected.Index].Content).Max(), }; linear.Nice(); IEnumerable <Bin> bins = HistogramCalculator.Bin( linear.DomainStart, linear.DomainEnd, linear.Step, rows, selected ); List <GroupedRows> groupedRows = new List <GroupedRows>(); foreach (Bin bin in bins) { GroupedRows grs = new GroupedRows(); grs.Keys[selected] = bin; grs.Rows = bin.Rows.ToList(); groupedRows.Add(grs); } return(groupedRows); }
public static List <GroupedRows> GroupRecursive(List <Row> rows, List <ColumnViewModel> groupedColumnViewModels, Int32 pivotIndex) { ColumnViewModel pivot = groupedColumnViewModels[pivotIndex]; Dictionary <Object, List <Row> > dict = GetRowsByColumnViewModel(rows, pivot); if (pivotIndex < groupedColumnViewModels.Count - 1) // 그루핑을 더 해야함. { List <GroupedRows> groupedRowsList = new List <GroupedRows>(); foreach (KeyValuePair <Object, List <Row> > kv in dict) { List <GroupedRows> ret = GroupRecursive(kv.Value, groupedColumnViewModels, pivotIndex + 1); foreach (GroupedRows groupedRows in ret) { groupedRows.Keys[pivot] = kv.Key; groupedRowsList.Add(groupedRows); } } return(groupedRowsList); } else // 마지막임 { List <GroupedRows> groupedRowsList = new List <GroupedRows>(); foreach (KeyValuePair <Object, List <Row> > kv in dict) { GroupedRows groupedRows = new GroupedRows(); groupedRows.Keys[pivot] = kv.Key; groupedRows.Rows = kv.Value; groupedRowsList.Add(groupedRows); } return(groupedRowsList); } }
/// <summary> /// 현재 viewStatus와 sheetViewModel을 이용하여 grouepdRows와 groupedRowViewModels를 생성함 /// 문제는 columnViewModel의 /// </summary> /// <param name="sheetViewModel"></param> public void Generate(SheetViewModel sheetViewModel) { List <ColumnViewModel> orderedColumnViewModels = sheetViewModel.ColumnViewModels; Int32 index = 0; if (IsEmpty) { // 어차피 allRow가 보일 것이므로 RowViewModel 을 만들어 줄 필요는 없음 } else if (IsN) // 이 경우는 뉴메리컬 하나만 선택되어 비닝 된 결과가 보이는 경우이다. { ColumnViewModel selected = FirstColumn; GroupedRows = Bin(selected, sheetViewModel.FilteredRows); GroupedRowViewModels = new List <RowViewModel>(); // 여기서 groupedRows가 소팅되어야함 // 그런데 여기서는 선택되지 않은 컬럼의 경우에는 어차피 어그리게이션되므로 소팅 순서가 의미가 없음 따라서 선택된 컬럼에 대해서만 소팅하면 된다 GroupedRows.Sort(new GroupedRowComparer(sheetViewModel, this)); foreach (GroupedRows groupedRows in GroupedRows) { if (groupedRows.Rows.Count == 0) { continue; } RowViewModel rowViewModel = new RowViewModel(sheetViewModel.MainPageViewModel) { Index = index++, Rows = groupedRows.Rows }; foreach (ColumnViewModel columnViewModel in orderedColumnViewModels) { Cell cell = new Cell(); cell.ColumnViewModel = columnViewModel; if (columnViewModel == selected) { Bin bin = groupedRows.Keys[selected] as Bin; String content = bin.ToString() + $" ({groupedRows.Rows.Count})"; cell.RawContent = content; cell.Content = content; } else if (columnViewModel.Type == ColumnType.Categorical) { Int32 uniqueCount = groupedRows.Rows.Select(r => r.Cells[columnViewModel.Index].Content).Distinct().Count(); cell.Content = $"({uniqueCount})"; cell.RawContent = $"({uniqueCount})"; } else //numerical { Object aggregated = columnViewModel.AggregativeFunction.Aggregate(groupedRows.Rows.Select(r => (Double)r.Cells[columnViewModel.Index].Content)); String formatted = Formatter.FormatAuto4((Double)aggregated); cell.RawContent = formatted; cell.Content = Double.Parse(formatted); } rowViewModel.Cells.Add(cell); } GroupedRowViewModels.Add(rowViewModel); } } else if (IsNN) { GroupedRowViewModels = new List <RowViewModel>(); RowViewModel rowViewModel = new RowViewModel(sheetViewModel.MainPageViewModel) { Index = 0, Rows = sheetViewModel.FilteredRows }; foreach (ColumnViewModel columnViewModel in orderedColumnViewModels) { Cell cell = new Cell(); cell.ColumnViewModel = columnViewModel; if (columnViewModel.Type == ColumnType.Categorical) { Int32 uniqueCount = sheetViewModel.FilteredRows.Select(r => r.Cells[columnViewModel.Index].Content).Distinct().Count(); cell.Content = $"({uniqueCount})"; cell.RawContent = $"({uniqueCount})"; } else if (columnViewModel.Type == ColumnType.Numerical) { Object aggregated = columnViewModel.AggregativeFunction.Aggregate(sheetViewModel.FilteredRows.Select(r => (Double)r.Cells[columnViewModel.Index].Content)); String formatted = Formatter.FormatAuto4((Double)aggregated); cell.RawContent = formatted; cell.Content = Double.Parse(formatted); } rowViewModel.Cells.Add(cell); } GroupedRowViewModels.Add(rowViewModel); } else if (CategoricalCount > 0)// 이 경우는 categorical이든 datetime이든 뭔가로 그룹핑이 된 경우 { GroupedRows = GroupRecursive( sheetViewModel.FilteredRows, CategoricalColumnViewModels.ToList(), 0); GroupedRows.Sort(new GroupedRowComparer(sheetViewModel, this)); GroupedRowViewModels = new List <RowViewModel>(); foreach (GroupedRows groupedRows in GroupedRows) { RowViewModel rowViewModel = new RowViewModel(sheetViewModel.MainPageViewModel) { Index = index++, Rows = groupedRows.Rows }; foreach (ColumnViewModel columnViewModel in orderedColumnViewModels) { Cell cell = new Cell(); cell.ColumnViewModel = columnViewModel; if (groupedRows.Keys.ContainsKey(columnViewModel)) { Object content = groupedRows.Keys[columnViewModel]; cell.Content = content; cell.RawContent = cell.Content.ToString(); } else if (columnViewModel.Type == ColumnType.Categorical) { Int32 uniqueCount = groupedRows.Rows.Select(r => r.Cells[columnViewModel.Index].Content).Distinct().Count(); cell.Content = $"({uniqueCount})"; cell.RawContent = $"({uniqueCount})"; } else if (columnViewModel.Type == ColumnType.Numerical) { Object aggregated = columnViewModel.AggregativeFunction.Aggregate(groupedRows.Rows.Select(r => (Double)r.Cells[columnViewModel.Index].Content)); String formatted = Formatter.FormatAuto4((Double)aggregated); cell.RawContent = formatted; cell.Content = Double.Parse(formatted); } rowViewModel.Cells.Add(cell); } GroupedRowViewModels.Add(rowViewModel); } } else { ; } }