Sorting GetSortBy() { MatrixEntry me = null; foreach (MatrixEntry m in this.HashData.Values) { // just get the first one me = m; break; } if (me == null) { return(null); } Sorting sb = null; if (me.RowGroup != null) { if (me.RowGroup.DynamicRows != null) { sb = me.RowGroup.DynamicRows.Sorting; } } else if (me.ColumnGroup != null) { if (me.ColumnGroup.DynamicColumns != null) { sb = me.ColumnGroup.DynamicColumns.Sorting; } } return(sb); }
Rows _Data; // set dynamically when needed internal MatrixEntry(MatrixEntry p, int rowCount) { _HashData = new Hashtable(); _ColumnGroup = null; _RowGroup = null; _SortedData = null; _Data = null; _rowCount = rowCount; _Rows = null; _Parent = p; _FirstRow = -1; _LastRow = -1; }
Rows _Data; // set dynamically when needed internal MatrixEntry(Row r, string hash, MatrixEntry p, int rowCount) { _r = r; _hash = hash; _HashData = new Dictionary <string, MatrixEntry>(); _ColumnGroup = null; _RowGroup = null; _SortedData = null; _Data = null; _rowCount = rowCount; _Rows = null; _Parent = p; _FirstRow = -1; _LastRow = -1; }
void RunColumnHeaders(Report rpt, WorkClass wc, MatrixEntry m, MatrixCellEntry[,] matrix, Rows _Data, int iRow, ref int iColumn, int level) { foreach (MatrixEntry ame in m.GetSortedData(rpt)) { matrix[iRow, iColumn] = RunGetColumnHeader(rpt, ame, _Data); matrix[iRow, iColumn].Width = RunGetColumnWidth(matrix[iRow, iColumn]); matrix[iRow, iColumn].Height = ame.ColumnGroup.Height == null? 0: ame.ColumnGroup.Height.Points; if (ame.GetSortedData(rpt) != null) { RunColumnHeaders(rpt, wc, ame, matrix, _Data, iRow+1, ref iColumn, level+1); } else iColumn++; } ColumnGrouping cg = (ColumnGrouping) (_ColumnGroupings.Items[level]); // if we need subtotal on the group if (cg.DynamicColumns != null && cg.DynamicColumns.Subtotal != null) { ReportItem ri = cg.DynamicColumns.Subtotal.ReportItems.Items[0]; matrix[iRow, iColumn] = new MatrixCellEntry(_Data, ri); matrix[iRow, iColumn].Height = cg.Height.Points; matrix[iRow, iColumn].Width = RunGetColumnWidth(matrix[iRow, iColumn]); RunColumnStaticHeaders(rpt, wc, matrix, _Data, iRow, iColumn, level); iColumn += this.CountMatrixCells; } }
int RunCountSubtotalRows(Report rpt, WorkClass wc, MatrixEntry m, int level) { // Get the number of static columns int srCount = Math.Max(1, this._RowGroupings.StaticCount); int count = 0; // Increase the row count when subtotal is requested at this level RowGrouping rg = (RowGrouping) (_RowGroupings.Items[level]); if (rg.DynamicRows != null && rg.DynamicRows.Subtotal != null) count = srCount; if (m.GetSortedData(rpt) == null || level+1 >= _RowGroupings.Items.Count) return count; // Now dive into the data foreach (MatrixEntry ame in m.GetSortedData(rpt)) { count += RunCountSubtotalRows(rpt, wc, ame, level+1); } return count; }
void HandleColumnGrouping(Report rpt, WorkClass wc, Rows rows, Row r, MatrixEntry m, int cgi, int iRow, ref int maxColumns) { while (cgi < _ColumnGroupings.Items.Count) { ColumnGrouping cg = _ColumnGroupings.Items[cgi] as ColumnGrouping; Grouping grp=null; string result; if (cg.StaticColumns != null) // handle static columns { for (int sci=0; sci < cg.StaticColumns.Items.Count; sci++) { result = Convert.ToChar(Convert.ToInt32('a')+sci).ToString() + terminal; // static column; put all data in it StaticColumn sc = cg.StaticColumns.Items[sci] as StaticColumn; MatrixEntry ame; m.HashData.TryGetValue(result, out ame); if (ame == null) { ame = new MatrixEntry(r, result, m, rows.Data.Count); ame.ColumnGroup = cg; ame.StaticColumn = sci; m.HashData.Add(result, ame); if (cg == LastCg) // Add a column when we add data at lowest level maxColumns++; } ame.Rows.Set(iRow, true); // Logic in FirstRow and Last row determine whether value gets set ame.FirstRow = iRow; ame.LastRow = iRow; HandleColumnGrouping(rpt, wc, rows, r, ame, cgi+1, iRow, ref maxColumns); } break; // handled ones below it recursively } else // handle dynamic columns { grp = cg.DynamicColumns.Grouping; StringBuilder sb = new StringBuilder(); foreach (GroupExpression ge in grp.GroupExpressions.Items) { string temp = ge.Expression.EvaluateString(rpt, r); if (temp == null || temp == "") sb.Append(nullterminal); else sb.Append(temp); sb.Append(terminal); // mark end of group } result = sb.ToString(); MatrixEntry ame; m.HashData.TryGetValue(result, out ame); if (ame == null) { ame = new MatrixEntry(r, result, m, rows.Data.Count); ame.ColumnGroup = cg; m.HashData.Add(result, ame); if (cg == LastCg) // Add a column when we add data at lowest level maxColumns++; } ame.Rows.Set(iRow, true); // Logic in FirstRow and Last row determine whether value gets set ame.FirstRow = iRow; ame.LastRow = iRow; m = ame; // now go down a level cgi++; } } }
internal MatrixEntry ME; // Used at runtime to contain data values internal WorkClass() { ME=null; }
internal MatrixEntry ME; // Used at runtime to contain data values internal WorkClass() { ME = null; }
void RunDataRow(Report rpt, WorkClass wc, MatrixEntry rm, MatrixEntry cm, MatrixCellEntry[,] matrix, Rows _Data, ref int iRow, int iColumn, int level) { int saveColumn; int headerRows = _ColumnGroupings.Items.Count; // number of column headers we have int rgsCount = this.RowGroupings.StaticCount; // count of static row groups foreach (MatrixEntry ame in rm.GetSortedData(rpt)) { if (ame.RowGroup != LastRg) { RunDataRow(rpt, wc, ame, cm, matrix, _Data, ref iRow, iColumn, level+1); continue; } saveColumn = iColumn; int rowcell = rgsCount == 0? 0: (iRow - headerRows) % rgsCount; RunDataColumn(rpt, wc, ame, cm, matrix, _Data, iRow, ref saveColumn, 0, rowcell); iRow++; } // do we need to subtotal this? RowGrouping rg = (RowGrouping) (_RowGroupings.Items[level]); if (rg.DynamicRows != null && rg.DynamicRows.Subtotal != null) { for (int i=0; i < this.CountMatrixRows; i++) { saveColumn = iColumn; RunDataColumn(rpt, wc, rm, cm, matrix, _Data, iRow, ref saveColumn, 0, i); iRow++; } } }
MatrixCellEntry RunGetMatrixCell(Report rpt, MatrixEntry me, int rcell, int ccell, Rows _Data, BitArray rows, int firstRow, int lastRow) { MatrixRow mr = this._MatrixRows.Items[rcell]; MatrixCell mc = mr.MatrixCells.Items[ccell]; ReportItem ri = mc.ReportItems.Items[0]; Rows subData = new Rows(rpt, _Data, firstRow, lastRow, rows); MatrixCellEntry mce = new MatrixCellEntry(subData, ri); return mce; }
MatrixCellEntry RunGetMatrixCell(Report rpt, MatrixEntry me, int iRow, Rows _Data, BitArray rows, int firstRow, int lastRow) { int headerRows = _ColumnGroupings.Items.Count; // number of column headers we have int rgsCount = this.RowGroupings.StaticCount; // count of static row groups int rowcell = rgsCount == 0? 0: (iRow - headerRows) % rgsCount; return RunGetMatrixCell(rpt, me, rowcell, me.StaticColumn, _Data, rows, firstRow, lastRow); }
MatrixCellEntry RunGetRowHeader(Report rpt, MatrixEntry me, Rows _Data) { ReportItem ri; if (me.RowGroup.StaticRows != null) { // Handle static row reference StaticRow sr = me.RowGroup.StaticRows.Items[me.StaticRow] as StaticRow; ri = sr.ReportItems.Items[0]; } else // handle dynamic row reference ri = me.RowGroup.DynamicRows.ReportItems.Items[0]; Rows subData = new Rows(rpt, _Data, me.FirstRow, me.LastRow, me.Rows); MatrixCellEntry mce = new MatrixCellEntry(subData, ri); return mce; }
int RunCountSubtotalColumns(WorkClass wc, MatrixEntry m, int level) { // Get the number of static columns int scCount = Math.Max(1, this._ColumnGroupings.StaticCount); int count = 0; // Increase the column count when subtotal is requested at this level ColumnGrouping cg = (ColumnGrouping) (_ColumnGroupings.Items[level]); if (cg.DynamicColumns != null && cg.DynamicColumns.Subtotal != null) count = scCount; if (m.SortedData == null || level+1 >= _ColumnGroupings.Items.Count) return count; // Now dive into the data foreach (MatrixEntry ame in m.SortedData.Values) { count += RunCountSubtotalColumns(wc, ame, level+1); } return count; }
void HandleRowGrouping(Report rpt, WorkClass wc, Rows rows, Row r, MatrixEntry m, int rgi, int iRow, ref int maxRows) { while (rgi < _RowGroupings.Items.Count) { RowGrouping rg = _RowGroupings.Items[rgi] as RowGrouping; Grouping grp=null; string result; if (rg.StaticRows != null) // handle static rows { for (int sri=0; sri < rg.StaticRows.Items.Count; sri++) { result = Convert.ToChar(Convert.ToInt32('a')+sri).ToString() + terminal; // static row; put all data in it StaticRow sr = rg.StaticRows.Items[sri] as StaticRow; MatrixEntry ame = (MatrixEntry) (m.HashData[result]); if (ame == null) { ame = new MatrixEntry(m, rows.Data.Count); ame.RowGroup = rg; ame.StaticRow = sri; m.HashData.Add(result, ame); if (rg == LastRg) // Add a row when we add data at lowest level maxRows++; } ame.Rows.Set(iRow, true); // Logic in FirstRow and Last row determine whether value gets set ame.FirstRow = iRow; ame.LastRow = iRow; HandleRowGrouping(rpt, wc, rows, r, ame, rgi+1, iRow, ref maxRows); } break; // handled ones below it recursively } else // handle dynamic columns { grp = rg.DynamicRows.Grouping; StringBuilder sb = new StringBuilder(); foreach (GroupExpression ge in grp.GroupExpressions.Items) { string temp = ge.Expression.EvaluateString(rpt, r); if (temp == null || temp == "") sb.Append(nullterminal); else sb.Append(temp); sb.Append(terminal); // mark end of group } result = sb.ToString(); MatrixEntry ame = (MatrixEntry) (m.HashData[result]); if (ame == null) { ame = new MatrixEntry(m, rows.Data.Count); ame.RowGroup = rg; m.HashData.Add(result, ame); if (rg == LastRg) // Add a row when we add data at lowest level maxRows++; } ame.Rows.Set(iRow, true); // Logic in FirstRow and Last row determine whether value gets set ame.FirstRow = iRow; ame.LastRow = iRow; m = ame; // now go down a level rgi++; } } }
MatrixCellEntry RunGetColumnHeader(Report rpt, MatrixEntry me, Rows _Data) { ReportItem ri; if (me.ColumnGroup.StaticColumns != null) { // Handle static column reference StaticColumn sc = me.ColumnGroup.StaticColumns.Items[me.StaticColumn] as StaticColumn; ri = sc.ReportItems.Items[0]; } else ri = me.ColumnGroup.DynamicColumns.ReportItems.Items[0]; // dynamic column Rows subData = new Rows(rpt, _Data, me.FirstRow, me.LastRow, me.Rows); MatrixCellEntry mce = new MatrixCellEntry(subData, ri); return mce; }
void RunDataColumn(Report rpt, WorkClass wc, MatrixEntry rm, MatrixEntry cm, MatrixCellEntry[,] matrix, Rows _Data, int iRow, ref int iColumn, int level, int rowcell) { BitArray andData; MatrixRow mr = this.MatrixRows.Items[rowcell] as MatrixRow; float height = mr.Height == null? 0: mr.Height.Points; foreach (MatrixEntry ame in cm.GetSortedData(rpt)) { if (ame.ColumnGroup != LastCg) { RunDataColumn(rpt, wc, rm, ame, matrix, _Data, iRow, ref iColumn, level+1, rowcell); continue; } andData = new BitArray(ame.Rows); // copy the data andData.And(rm.Rows); // because And is destructive matrix[iRow, iColumn] = RunGetMatrixCell(rpt, ame, iRow, _Data, andData, Math.Max(rm.FirstRow, ame.FirstRow), Math.Min(rm.LastRow, ame.LastRow)); matrix[iRow, iColumn].Height = height; matrix[iRow, iColumn].Width = RunGetColumnWidth(matrix[iRow, iColumn]); matrix[iRow, iColumn].ColumnME = ame; matrix[iRow, iColumn].RowME = rm; iColumn++; } // do we need to subtotal this? ColumnGrouping cg = (ColumnGrouping) (_ColumnGroupings.Items[level]); if (cg.DynamicColumns != null && cg.DynamicColumns.Subtotal != null) { andData = new BitArray(cm.Rows); // copy the data andData.And(rm.Rows); // because And is destructive for (int i=0; i < this.CountMatrixCells; i++) { matrix[iRow, iColumn] = RunGetMatrixCell(rpt, cm, rowcell, i, _Data, andData, Math.Max(rm.FirstRow, cm.FirstRow), Math.Min(rm.LastRow, cm.LastRow)); matrix[iRow, iColumn].Height = height; matrix[iRow, iColumn].Width = RunGetColumnWidth(matrix[iRow, iColumn]); matrix[iRow, iColumn].ColumnME = cm; matrix[iRow, iColumn].RowME = rm; iColumn++; } } }
private void SetGroupingValuesInit(Report rpt, Rows data, MatrixEntry rme, MatrixEntry cme) { // handle the column grouping if (cme != null) { foreach (ColumnGrouping cg in this.ColumnGroupings.Items) { if (cg.DynamicColumns != null) SetGrouping(rpt, cg.DynamicColumns.Grouping, cme, data); } } // handle the row grouping if (rme != null) { foreach (RowGrouping rg in this.RowGroupings.Items) { if (rg.DynamicRows != null) SetGrouping(rpt, rg.DynamicRows.Grouping, rme, data); } } }
void RunRowHeaders(Report rpt, WorkClass wc, MatrixEntry m, MatrixCellEntry[,] matrix, Rows _Data, ref int iRow, int iColumn, int level) { foreach (MatrixEntry ame in m.GetSortedData(rpt)) { matrix[iRow, iColumn] = RunGetRowHeader(rpt, ame, _Data); matrix[iRow, iColumn].Height = RunRowHeight(iRow); matrix[iRow, iColumn].Width = ame.RowGroup.Width == null? 0: ame.RowGroup.Width.Points; if (ame.GetSortedData(rpt) != null) { RunRowHeaders(rpt, wc, ame, matrix, _Data, ref iRow, iColumn+1, level+1); } else iRow++; } RowGrouping rg = (RowGrouping) (_RowGroupings.Items[level]); // do we need to subtotal this if (rg.DynamicRows != null && rg.DynamicRows.Subtotal != null) { // TODO need to loop thru static?? ReportItem ri = rg.DynamicRows.Subtotal.ReportItems.Items[0]; matrix[iRow, iColumn] = new MatrixCellEntry(_Data, ri); matrix[iRow, iColumn].Width = rg.Width.Points; matrix[iRow, iColumn].Height = RunRowHeight(iRow); RunRowStaticHeaders(rpt, wc, matrix, _Data, iRow, level); iRow += Math.Max(1,this.RowGroupings.StaticCount); } }
private void SetGroupingValuesMe(Report rpt, Rows data, MatrixEntry me) { if (me == null) return; // handle the column grouping if (me.ColumnGroup != null && me.ColumnGroup.DynamicColumns != null) SetGrouping(rpt, me.ColumnGroup.DynamicColumns.Grouping, me, data); // handle the row grouping if (me.RowGroup != null && me.RowGroup.DynamicRows != null) SetGrouping(rpt, me.RowGroup.DynamicRows.Grouping, me, data); if (me.Parent != null) // go up the tree?? SetGroupingValuesMe(rpt, data, me.Parent); }
internal void SetME(Report rpt, MatrixEntry me) { WorkClass wc = GetWC(rpt); wc.ME = me; }
private void SetGrouping(Report rpt, Grouping g, MatrixEntry me, Rows data) { if (g == null) return; if (me.Data == null) me.Data = new Rows(rpt, data, me.FirstRow, me.LastRow, me.Rows); g.SetRows(rpt, me.Data); }
// RunBuild is used by both Matrix.Run and Chart.Run to obtain the necessary data // used by their respective rendering interfaces internal MatrixCellEntry[,] RunBuild(Report rpt, out int numRows, out int numCols) { WorkClass wc = GetValue(rpt); Rows _Data = wc.Data; // loop thru all the data; // form bitmap arrays for each unique data value of each grouping (row and column) value int maxColumns = _RowGroupings.Items.Count; // maximum # of columns in matrix // at top we need a row per column grouping int maxRows = _ColumnGroupings.Items.Count; // maximum # of rows in matrix // at left we need a column per row grouping MatrixEntry mcg = new MatrixEntry(null, "", null, _Data.Data.Count); _ColumnGroupings.SetME(rpt, mcg); mcg.FirstRow=0; mcg.LastRow=_Data.Data.Count-1; mcg.Rows = new BitArray(_Data.Data.Count, true); // all data MatrixEntry mrg = new MatrixEntry(null, "", null, _Data.Data.Count); _RowGroupings.SetME(rpt, mrg); mrg.FirstRow=0; mrg.LastRow=_Data.Data.Count-1; mrg.Rows = new BitArray(_Data.Data.Count, true); // all data int iRow=0; // row counter foreach (Row r in _Data.Data) { // Handle the column values HandleColumnGrouping(rpt, wc, _Data, r, mcg, 0, iRow, ref maxColumns); // Handle the row values HandleRowGrouping(rpt, wc, _Data, r, mrg, 0, iRow, ref maxRows); iRow++; } // Determine how many subtotal columns are needed maxColumns += RunCountSubtotalColumns(rpt, wc, mcg, 0); // Determine how many subtotal rows are needed maxRows += RunCountSubtotalRows(rpt, wc, mrg, 0); ///// // Build and populate the 2 dimensional table of MatrixCellEntry // that constitute the matrix ///// MatrixCellEntry[,] matrix = new MatrixCellEntry[maxRows, maxColumns]; // Do the column headings int iColumn = _RowGroupings.Items.Count; RunColumnHeaders(rpt, wc, mcg, matrix, _Data, 0, ref iColumn, 0); // Do the row headings iRow = _ColumnGroupings.Items.Count; RunRowHeaders(rpt, wc, mrg, matrix, _Data, ref iRow, 0, 0); // Do the row/column data iRow = _ColumnGroupings.Items.Count; RunDataRow(rpt, wc, mrg, mcg, matrix, _Data, ref iRow, _RowGroupings.Items.Count, 0); // Do the corner matrix[0, 0] = RunCorner(_Data); // now return the matrix data numRows = maxRows; numCols = maxColumns; return matrix; }