using System; using System.Collections; using FastReport.Data; namespace FastReport.CrossView { /// /// Contains a set of properties and methods to hold and manipulate the CrossView descriptors. /// /// /// This class contains three collections of descriptors such as , /// and . Descriptors are filled from FastCube Slice. /// public class CrossViewData { #region Fields private CrossViewHeader columns; private CrossViewHeader rows; private CrossViewCells cells; internal int[] columnDescriptorsIndexes; internal int[] rowDescriptorsIndexes; internal int[] columnTerminalIndexes; internal int[] rowTerminalIndexes; #endregion #region FastCube properties (temporary) private CubeSourceBase cubeSource; /// /// /// public int XAxisFieldsCount { get { return cubeSource != null ? cubeSource.XAxisFieldsCount : 0; } } /// /// /// public int YAxisFieldsCount { get { return cubeSource != null ? cubeSource.YAxisFieldsCount : 0; } } /// /// /// public int MeasuresCount { get { return cubeSource != null ? cubeSource.MeasuresCount : 0; } } /// /// /// public int MeasuresLevel { get { return cubeSource != null ? cubeSource.MeasuresLevel : 0; } } /// /// /// public bool MeasuresInXAxis { get { return cubeSource != null ? cubeSource.MeasuresInXAxis : false; } } /// /// /// public bool MeasuresInYAxis { get { return cubeSource != null ? cubeSource.MeasuresInYAxis : false; } } /// /// /// public int DataColumnCount { get { return cubeSource != null ? cubeSource.DataColumnCount : 0; } } /// /// /// public int DataRowCount { get { return cubeSource != null ? cubeSource.DataRowCount : 0; } } /// /// /// public bool SourceAssigned { get { return cubeSource != null; } } #if !DOTNET_4 private string intArrayToString(int[] intArray) { string res = ""; foreach (int item in intArray) { if (res != "") res += ","; res += item.ToString(); } return res; } private int[] stringToIntArray(string str) { string[] strArray = str.Split(','); int[] res = new int[strArray.Length]; for (int i = 0; i < strArray.Length; i++) { res[i] = int.Parse(strArray[i]); } return res; } #endif /// /// /// public string ColumnDescriptorsIndexes { #if DOTNET_4 get { return string.Join(",", columnDescriptorsIndexes); } set { columnDescriptorsIndexes = Array.ConvertAll(value.Split(','), int.Parse); } #else get { return intArrayToString(columnDescriptorsIndexes); } set { columnDescriptorsIndexes = stringToIntArray(value); } #endif } /// /// /// public string RowDescriptorsIndexes { #if DOTNET_4 get { return string.Join(",", rowDescriptorsIndexes); } set { rowDescriptorsIndexes = Array.ConvertAll(value.Split(','), int.Parse); } #else get { return intArrayToString(rowDescriptorsIndexes); } set { rowDescriptorsIndexes = stringToIntArray(value); } #endif } /// /// /// public string ColumnTerminalIndexes { #if DOTNET_4 get { return string.Join(",", columnTerminalIndexes); } set { columnTerminalIndexes = Array.ConvertAll(value.Split(','), int.Parse); } #else get { return intArrayToString(columnTerminalIndexes); } set { columnTerminalIndexes = stringToIntArray(value); } #endif } /// /// /// public string RowTerminalIndexes { #if DOTNET_4 get { return string.Join(",", rowTerminalIndexes); } set { rowTerminalIndexes = Array.ConvertAll(value.Split(','), int.Parse); } #else get { return intArrayToString(rowTerminalIndexes); } set { rowTerminalIndexes = stringToIntArray(value); } #endif } internal CubeSourceBase CubeSource { get { return cubeSource; } set { if (cubeSource != value) { cubeSource = value; } } } internal void CreateDescriptors() { columnDescriptorsIndexes = new int[0]; rowDescriptorsIndexes = new int[0]; columnTerminalIndexes = new int[0]; rowTerminalIndexes = new int[0]; CrossViewHeaderDescriptor crossViewHeaderDescriptor; Columns.Clear(); Rows.Clear(); Cells.Clear(); if (!SourceAssigned) return; int cell = 0; for (int i = 0; i < XAxisFieldsCount; i++) { cell = 0; if (MeasuresInXAxis && (MeasuresLevel <= i)) { if (MeasuresLevel == i) { for (int k = 0; k <= i; k++) { for (int j = 0; j < MeasuresCount; j++) { if (k == i) { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", CubeSource.GetMeasureName(j), false, false, true); crossViewHeaderDescriptor.cellsize = 1; crossViewHeaderDescriptor.levelsize = XAxisFieldsCount - i; } else { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetXAxisFieldName(k), CubeSource.GetMeasureName(j), false, false, true); crossViewHeaderDescriptor.cellsize = (XAxisFieldsCount - i); crossViewHeaderDescriptor.levelsize = 1; } crossViewHeaderDescriptor.level = i; crossViewHeaderDescriptor.cell = cell; cell += crossViewHeaderDescriptor.cellsize; Columns.Add(crossViewHeaderDescriptor); if ((j == 0) && (k == 0)) { Array.Resize(ref rowDescriptorsIndexes, rowDescriptorsIndexes.Length + 1); rowDescriptorsIndexes[rowDescriptorsIndexes.Length - 1] = Columns.Count - 1; } if ((k == i) || (i == (XAxisFieldsCount - 1))) { Array.Resize(ref columnTerminalIndexes, columnTerminalIndexes.Length + 1); columnTerminalIndexes[columnTerminalIndexes.Length - 1] = Columns.Count - 1; } } } } else { for (int j = 0; j < MeasuresCount; j++) { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetXAxisFieldName(i), "", false, false, false); crossViewHeaderDescriptor.level = i; crossViewHeaderDescriptor.levelsize = 1; crossViewHeaderDescriptor.cell = cell; crossViewHeaderDescriptor.cellsize = XAxisFieldsCount - i; cell += crossViewHeaderDescriptor.cellsize; Columns.Add(crossViewHeaderDescriptor); if (j == 0) { Array.Resize(ref rowDescriptorsIndexes, rowDescriptorsIndexes.Length + 1); rowDescriptorsIndexes[rowDescriptorsIndexes.Length - 1] = Columns.Count - 1; } if (i == 1) { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", "", false, true, false); } else if (i == (MeasuresLevel + 1)) { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetXAxisFieldName(i - 2), "", true, false, false); } else { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetXAxisFieldName(i - 1), "", true, false, false); } crossViewHeaderDescriptor.level = i; crossViewHeaderDescriptor.levelsize = XAxisFieldsCount - i; crossViewHeaderDescriptor.cell = cell; crossViewHeaderDescriptor.cellsize = 1; cell += crossViewHeaderDescriptor.cellsize; Columns.Add(crossViewHeaderDescriptor); if ((crossViewHeaderDescriptor.level + crossViewHeaderDescriptor.levelsize == XAxisFieldsCount)) { Array.Resize(ref columnTerminalIndexes, columnTerminalIndexes.Length + 1); columnTerminalIndexes[columnTerminalIndexes.Length - 1] = Columns.Count - 1; } } } } else { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetXAxisFieldName(i), "", false, false, false); crossViewHeaderDescriptor.level = i; crossViewHeaderDescriptor.levelsize = 1; crossViewHeaderDescriptor.cell = cell; if (MeasuresInXAxis) { crossViewHeaderDescriptor.cellsize = (XAxisFieldsCount - i - 1) * MeasuresCount; if (crossViewHeaderDescriptor.cellsize == 0) crossViewHeaderDescriptor.cellsize = MeasuresCount; } else { crossViewHeaderDescriptor.cellsize = XAxisFieldsCount - i; } cell += crossViewHeaderDescriptor.cellsize; Columns.Add(crossViewHeaderDescriptor); if ((crossViewHeaderDescriptor.level + crossViewHeaderDescriptor.levelsize == XAxisFieldsCount)) { Array.Resize(ref columnTerminalIndexes, columnTerminalIndexes.Length + 1); columnTerminalIndexes[columnTerminalIndexes.Length - 1] = Columns.Count - 1; } Array.Resize(ref rowDescriptorsIndexes, rowDescriptorsIndexes.Length + 1); rowDescriptorsIndexes[rowDescriptorsIndexes.Length - 1] = Columns.Count - 1; if (i == 0) { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", "", false, true, false); } else { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetXAxisFieldName(i - 1), "", true, false, false); } crossViewHeaderDescriptor.level = i; crossViewHeaderDescriptor.cell = cell; if (MeasuresInXAxis) { crossViewHeaderDescriptor.levelsize = MeasuresLevel - i; crossViewHeaderDescriptor.cellsize = MeasuresCount; } else { crossViewHeaderDescriptor.levelsize = XAxisFieldsCount - i; crossViewHeaderDescriptor.cellsize = 1; } cell += crossViewHeaderDescriptor.cellsize; Columns.Add(crossViewHeaderDescriptor); if ((crossViewHeaderDescriptor.level + crossViewHeaderDescriptor.levelsize == XAxisFieldsCount)) { Array.Resize(ref columnTerminalIndexes, columnTerminalIndexes.Length + 1); columnTerminalIndexes[columnTerminalIndexes.Length - 1] = Columns.Count - 1; } } } if (Columns.Count == 0) { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", "", false, true, false); crossViewHeaderDescriptor.level = 0; crossViewHeaderDescriptor.levelsize = 1; crossViewHeaderDescriptor.cell = 0; crossViewHeaderDescriptor.cellsize = 1; Columns.Add(crossViewHeaderDescriptor); Array.Resize(ref rowDescriptorsIndexes, rowDescriptorsIndexes.Length + 1); rowDescriptorsIndexes[rowDescriptorsIndexes.Length - 1] = Columns.Count - 1; Array.Resize(ref columnTerminalIndexes, columnTerminalIndexes.Length + 1); columnTerminalIndexes[columnTerminalIndexes.Length - 1] = Columns.Count - 1; } for (int i = 0; i < YAxisFieldsCount; i++) { cell = 0; if (MeasuresInYAxis && (MeasuresLevel <= i)) { if (MeasuresLevel == i) { for (int k = 0; k <= i; k++) { for (int j = 0; j < MeasuresCount; j++) { if (k == i) { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", CubeSource.GetMeasureName(j), false, false, true); crossViewHeaderDescriptor.cellsize = 1; crossViewHeaderDescriptor.levelsize = YAxisFieldsCount - i; } else { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetYAxisFieldName(k), CubeSource.GetMeasureName(j), false, false, true); crossViewHeaderDescriptor.cellsize = (YAxisFieldsCount - i); crossViewHeaderDescriptor.levelsize = 1; } crossViewHeaderDescriptor.level = i; crossViewHeaderDescriptor.cell = cell; cell += crossViewHeaderDescriptor.cellsize; Rows.Add(crossViewHeaderDescriptor); if ((j == 0) && (k == 0)) { Array.Resize(ref columnDescriptorsIndexes, columnDescriptorsIndexes.Length + 1); columnDescriptorsIndexes[columnDescriptorsIndexes.Length - 1] = Rows.Count - 1; } if ((k == i) || (i == (YAxisFieldsCount - 1))) { Array.Resize(ref rowTerminalIndexes, rowTerminalIndexes.Length + 1); rowTerminalIndexes[rowTerminalIndexes.Length - 1] = Rows.Count - 1; } } } } else { for (int j = 0; j < MeasuresCount; j++) { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetYAxisFieldName(i), "", false, false, false); crossViewHeaderDescriptor.level = i; crossViewHeaderDescriptor.levelsize = 1; crossViewHeaderDescriptor.cell = cell; crossViewHeaderDescriptor.cellsize = YAxisFieldsCount - i; cell += crossViewHeaderDescriptor.cellsize; Rows.Add(crossViewHeaderDescriptor); if (j == 0) { Array.Resize(ref columnDescriptorsIndexes, columnDescriptorsIndexes.Length + 1); columnDescriptorsIndexes[columnDescriptorsIndexes.Length - 1] = Rows.Count - 1; } if (i == 1) { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", "", false, true, false); } else if (i == (MeasuresLevel + 1)) { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetYAxisFieldName(i - 2), "", true, false, false); } else { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetYAxisFieldName(i - 1), "", true, false, false); } crossViewHeaderDescriptor.level = i; crossViewHeaderDescriptor.levelsize = YAxisFieldsCount - i; crossViewHeaderDescriptor.cell = cell; crossViewHeaderDescriptor.cellsize = 1; cell += crossViewHeaderDescriptor.cellsize; Rows.Add(crossViewHeaderDescriptor); if ((crossViewHeaderDescriptor.level + crossViewHeaderDescriptor.levelsize == YAxisFieldsCount)) { Array.Resize(ref rowTerminalIndexes, rowTerminalIndexes.Length + 1); rowTerminalIndexes[rowTerminalIndexes.Length - 1] = Rows.Count - 1; } } } } else { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetYAxisFieldName(i), "", false, false, false); crossViewHeaderDescriptor.level = i; crossViewHeaderDescriptor.levelsize = 1; crossViewHeaderDescriptor.cell = cell; if (MeasuresInYAxis) { crossViewHeaderDescriptor.cellsize = (YAxisFieldsCount - i - 1) * MeasuresCount; if (crossViewHeaderDescriptor.cellsize == 0) crossViewHeaderDescriptor.cellsize = MeasuresCount; } else { crossViewHeaderDescriptor.cellsize = YAxisFieldsCount - i; } cell += crossViewHeaderDescriptor.cellsize; Rows.Add(crossViewHeaderDescriptor); if ((crossViewHeaderDescriptor.level + crossViewHeaderDescriptor.levelsize == YAxisFieldsCount)) { Array.Resize(ref rowTerminalIndexes, rowTerminalIndexes.Length + 1); rowTerminalIndexes[rowTerminalIndexes.Length - 1] = Rows.Count - 1; } Array.Resize(ref columnDescriptorsIndexes, columnDescriptorsIndexes.Length + 1); columnDescriptorsIndexes[columnDescriptorsIndexes.Length - 1] = Rows.Count - 1; if (i == 0) { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", "", false, true, false); } else { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetYAxisFieldName(i - 1), "", true, false, false); } crossViewHeaderDescriptor.level = i; crossViewHeaderDescriptor.cell = cell; if (MeasuresInYAxis) { crossViewHeaderDescriptor.levelsize = MeasuresLevel - i; crossViewHeaderDescriptor.cellsize = MeasuresCount; } else { crossViewHeaderDescriptor.levelsize = YAxisFieldsCount - i; crossViewHeaderDescriptor.cellsize = 1; } cell += crossViewHeaderDescriptor.cellsize; Rows.Add(crossViewHeaderDescriptor); if ((crossViewHeaderDescriptor.level + crossViewHeaderDescriptor.levelsize == YAxisFieldsCount)) { Array.Resize(ref rowTerminalIndexes, rowTerminalIndexes.Length + 1); rowTerminalIndexes[rowTerminalIndexes.Length - 1] = Rows.Count - 1; } } } if (Rows.Count == 0) { crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", "", false, true, false); crossViewHeaderDescriptor.level = 0; crossViewHeaderDescriptor.levelsize = 1; crossViewHeaderDescriptor.cell = 0; crossViewHeaderDescriptor.cellsize = 1; Rows.Add(crossViewHeaderDescriptor); Array.Resize(ref columnDescriptorsIndexes, columnDescriptorsIndexes.Length + 1); columnDescriptorsIndexes[columnDescriptorsIndexes.Length - 1] = Rows.Count - 1; Array.Resize(ref rowTerminalIndexes, rowTerminalIndexes.Length + 1); rowTerminalIndexes[rowTerminalIndexes.Length - 1] = Rows.Count - 1; } CrossViewCellDescriptor crossViewCellDescriptor; for (int i = 0; i < columnTerminalIndexes.Length; i++) { for (int j = 0; j < rowTerminalIndexes.Length; j++) { crossViewCellDescriptor = new CrossViewCellDescriptor(Columns[columnTerminalIndexes[i]].fieldName, Rows[rowTerminalIndexes[j]].fieldName, Columns[columnTerminalIndexes[i]].measureName + Rows[rowTerminalIndexes[j]].measureName, Columns[columnTerminalIndexes[i]].isTotal, Rows[rowTerminalIndexes[j]].isTotal, Columns[columnTerminalIndexes[i]].isGrandTotal, Rows[rowTerminalIndexes[j]].isGrandTotal); crossViewCellDescriptor.x = i; crossViewCellDescriptor.y = j; Cells.Add(crossViewCellDescriptor); } } } internal CrossViewHeaderDescriptor GetRowDescriptor(int index) { int tempXAxisFieldsCount = (!SourceAssigned) ? 1 : XAxisFieldsCount; if (index < tempXAxisFieldsCount) { return Columns[rowDescriptorsIndexes[index]]; } else { return Rows[rowTerminalIndexes[index - tempXAxisFieldsCount]]; } } internal CrossViewHeaderDescriptor GetColumnDescriptor(int index) { int tempYAxisFieldsCount = (!SourceAssigned) ? 1 : YAxisFieldsCount; if (index < tempYAxisFieldsCount) { return Rows[columnDescriptorsIndexes[index]]; } else { return Columns[columnTerminalIndexes[index - tempYAxisFieldsCount]]; } } #endregion #region Properties /// /// Gets a collection of column descriptors. /// /// /// Note: after you change something in this collection, call the /// method to refresh the CrossView. /// public CrossViewHeader Columns { get { return columns; } } /// /// Gets a collection of row descriptors. /// /// /// Note: after you change something in this collection, call the /// method to refresh the CrossView. /// public CrossViewHeader Rows { get { return rows; } } /// /// Gets a collection of data cell descriptors. /// /// /// Note: after you change something in this collection, call the /// method to refresh the CrossView. /// public CrossViewCells Cells { get { return cells; } } #endregion #region Public Methods #endregion internal CrossViewData() { columns = new CrossViewHeader(); columns.Name = "CrossViewColumns"; rows = new CrossViewHeader(); rows.Name = "CrossViewRows"; cells = new CrossViewCells(); cells.Name = "CrossViewCells"; CreateDescriptors(); } } }