FastReport
568 строк · 25.9 Кб
1using System;
2using System.Collections;
3using FastReport.Data;
4
5namespace FastReport.CrossView
6{
7/// <summary>
8/// Contains a set of properties and methods to hold and manipulate the CrossView descriptors.
9/// </summary>
10/// <remarks>
11/// This class contains three collections of descriptors such as <see cref="Columns"/>,
12/// <see cref="Rows"/> and <see cref="Cells"/>. Descriptors are filled from FastCube Slice.
13/// </remarks>
14public class CrossViewData
15{
16#region Fields
17private CrossViewHeader columns;
18private CrossViewHeader rows;
19private CrossViewCells cells;
20internal int[] columnDescriptorsIndexes;
21internal int[] rowDescriptorsIndexes;
22internal int[] columnTerminalIndexes;
23internal int[] rowTerminalIndexes;
24#endregion
25
26#region FastCube properties (temporary)
27private CubeSourceBase cubeSource;
28/// <summary>
29///
30/// </summary>
31public int XAxisFieldsCount { get { return cubeSource != null ? cubeSource.XAxisFieldsCount : 0; } }
32/// <summary>
33///
34/// </summary>
35public int YAxisFieldsCount { get { return cubeSource != null ? cubeSource.YAxisFieldsCount : 0; } }
36/// <summary>
37///
38/// </summary>
39public int MeasuresCount { get { return cubeSource != null ? cubeSource.MeasuresCount : 0; } }
40/// <summary>
41///
42/// </summary>
43public int MeasuresLevel { get { return cubeSource != null ? cubeSource.MeasuresLevel : 0; } }
44/// <summary>
45///
46/// </summary>
47public bool MeasuresInXAxis { get { return cubeSource != null ? cubeSource.MeasuresInXAxis : false; } }
48/// <summary>
49///
50/// </summary>
51public bool MeasuresInYAxis { get { return cubeSource != null ? cubeSource.MeasuresInYAxis : false; } }
52/// <summary>
53///
54/// </summary>
55public int DataColumnCount { get { return cubeSource != null ? cubeSource.DataColumnCount : 0; } }
56/// <summary>
57///
58/// </summary>
59public int DataRowCount { get { return cubeSource != null ? cubeSource.DataRowCount : 0; } }
60/// <summary>
61///
62/// </summary>
63public bool SourceAssigned { get { return cubeSource != null; } }
64#if !DOTNET_4
65private string intArrayToString(int[] intArray)
66{
67string res = "";
68foreach (int item in intArray)
69{
70if (res != "")
71res += ",";
72res += item.ToString();
73}
74return res;
75}
76private int[] stringToIntArray(string str)
77{
78string[] strArray = str.Split(',');
79int[] res = new int[strArray.Length];
80for (int i = 0; i < strArray.Length; i++)
81{
82res[i] = int.Parse(strArray[i]);
83}
84return res;
85}
86#endif
87/// <summary>
88///
89/// </summary>
90public string ColumnDescriptorsIndexes
91{
92#if DOTNET_4
93get { return string.Join(",", columnDescriptorsIndexes); }
94set { columnDescriptorsIndexes = Array.ConvertAll(value.Split(','), int.Parse); }
95#else
96get { return intArrayToString(columnDescriptorsIndexes); }
97set { columnDescriptorsIndexes = stringToIntArray(value); }
98#endif
99}
100/// <summary>
101///
102/// </summary>
103public string RowDescriptorsIndexes
104{
105#if DOTNET_4
106get { return string.Join(",", rowDescriptorsIndexes); }
107set { rowDescriptorsIndexes = Array.ConvertAll(value.Split(','), int.Parse); }
108#else
109get { return intArrayToString(rowDescriptorsIndexes); }
110set { rowDescriptorsIndexes = stringToIntArray(value); }
111#endif
112}
113/// <summary>
114///
115/// </summary>
116public string ColumnTerminalIndexes
117{
118#if DOTNET_4
119get { return string.Join(",", columnTerminalIndexes); }
120set { columnTerminalIndexes = Array.ConvertAll(value.Split(','), int.Parse); }
121#else
122get { return intArrayToString(columnTerminalIndexes); }
123set { columnTerminalIndexes = stringToIntArray(value); }
124#endif
125}
126/// <summary>
127///
128/// </summary>
129public string RowTerminalIndexes
130{
131#if DOTNET_4
132get { return string.Join(",", rowTerminalIndexes); }
133set { rowTerminalIndexes = Array.ConvertAll(value.Split(','), int.Parse); }
134#else
135get { return intArrayToString(rowTerminalIndexes); }
136set { rowTerminalIndexes = stringToIntArray(value); }
137#endif
138}
139internal CubeSourceBase CubeSource
140{
141get { return cubeSource; }
142set
143{
144if (cubeSource != value)
145{
146cubeSource = value;
147}
148}
149}
150internal void CreateDescriptors()
151{
152columnDescriptorsIndexes = new int[0];
153rowDescriptorsIndexes = new int[0];
154columnTerminalIndexes = new int[0];
155rowTerminalIndexes = new int[0];
156CrossViewHeaderDescriptor crossViewHeaderDescriptor;
157Columns.Clear();
158Rows.Clear();
159Cells.Clear();
160
161if (!SourceAssigned)
162return;
163int cell = 0;
164for (int i = 0; i < XAxisFieldsCount; i++)
165{
166cell = 0;
167if (MeasuresInXAxis && (MeasuresLevel <= i))
168{
169if (MeasuresLevel == i)
170{
171for (int k = 0; k <= i; k++)
172{
173for (int j = 0; j < MeasuresCount; j++)
174{
175if (k == i)
176{
177crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", CubeSource.GetMeasureName(j), false, false, true);
178crossViewHeaderDescriptor.cellsize = 1;
179crossViewHeaderDescriptor.levelsize = XAxisFieldsCount - i;
180}
181else
182{
183crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetXAxisFieldName(k), CubeSource.GetMeasureName(j), false, false, true);
184crossViewHeaderDescriptor.cellsize = (XAxisFieldsCount - i);
185crossViewHeaderDescriptor.levelsize = 1;
186}
187crossViewHeaderDescriptor.level = i;
188crossViewHeaderDescriptor.cell = cell;
189cell += crossViewHeaderDescriptor.cellsize;
190Columns.Add(crossViewHeaderDescriptor);
191if ((j == 0) && (k == 0))
192{
193Array.Resize(ref rowDescriptorsIndexes, rowDescriptorsIndexes.Length + 1);
194rowDescriptorsIndexes[rowDescriptorsIndexes.Length - 1] = Columns.Count - 1;
195}
196if ((k == i) || (i == (XAxisFieldsCount - 1)))
197{
198Array.Resize(ref columnTerminalIndexes, columnTerminalIndexes.Length + 1);
199columnTerminalIndexes[columnTerminalIndexes.Length - 1] = Columns.Count - 1;
200}
201}
202}
203}
204else
205{
206for (int j = 0; j < MeasuresCount; j++)
207{
208crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetXAxisFieldName(i), "", false, false, false);
209crossViewHeaderDescriptor.level = i;
210crossViewHeaderDescriptor.levelsize = 1;
211crossViewHeaderDescriptor.cell = cell;
212crossViewHeaderDescriptor.cellsize = XAxisFieldsCount - i;
213cell += crossViewHeaderDescriptor.cellsize;
214Columns.Add(crossViewHeaderDescriptor);
215if (j == 0)
216{
217Array.Resize(ref rowDescriptorsIndexes, rowDescriptorsIndexes.Length + 1);
218rowDescriptorsIndexes[rowDescriptorsIndexes.Length - 1] = Columns.Count - 1;
219}
220
221if (i == 1)
222{
223crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", "", false, true, false);
224}
225else
226if (i == (MeasuresLevel + 1))
227{
228crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetXAxisFieldName(i - 2), "", true, false, false);
229}
230else
231{
232crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetXAxisFieldName(i - 1), "", true, false, false);
233}
234crossViewHeaderDescriptor.level = i;
235crossViewHeaderDescriptor.levelsize = XAxisFieldsCount - i;
236crossViewHeaderDescriptor.cell = cell;
237crossViewHeaderDescriptor.cellsize = 1;
238cell += crossViewHeaderDescriptor.cellsize;
239Columns.Add(crossViewHeaderDescriptor);
240
241if ((crossViewHeaderDescriptor.level + crossViewHeaderDescriptor.levelsize == XAxisFieldsCount))
242{
243Array.Resize(ref columnTerminalIndexes, columnTerminalIndexes.Length + 1);
244columnTerminalIndexes[columnTerminalIndexes.Length - 1] = Columns.Count - 1;
245}
246}
247}
248}
249else
250{
251crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetXAxisFieldName(i), "", false, false, false);
252crossViewHeaderDescriptor.level = i;
253crossViewHeaderDescriptor.levelsize = 1;
254crossViewHeaderDescriptor.cell = cell;
255if (MeasuresInXAxis)
256{
257crossViewHeaderDescriptor.cellsize = (XAxisFieldsCount - i - 1) * MeasuresCount;
258if (crossViewHeaderDescriptor.cellsize == 0)
259crossViewHeaderDescriptor.cellsize = MeasuresCount;
260}
261else
262{
263crossViewHeaderDescriptor.cellsize = XAxisFieldsCount - i;
264}
265cell += crossViewHeaderDescriptor.cellsize;
266Columns.Add(crossViewHeaderDescriptor);
267if ((crossViewHeaderDescriptor.level + crossViewHeaderDescriptor.levelsize == XAxisFieldsCount))
268{
269Array.Resize(ref columnTerminalIndexes, columnTerminalIndexes.Length + 1);
270columnTerminalIndexes[columnTerminalIndexes.Length - 1] = Columns.Count - 1;
271}
272
273Array.Resize(ref rowDescriptorsIndexes, rowDescriptorsIndexes.Length + 1);
274rowDescriptorsIndexes[rowDescriptorsIndexes.Length - 1] = Columns.Count - 1;
275
276if (i == 0)
277{
278crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", "", false, true, false);
279}
280else
281{
282crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetXAxisFieldName(i - 1), "", true, false, false);
283}
284crossViewHeaderDescriptor.level = i;
285crossViewHeaderDescriptor.cell = cell;
286if (MeasuresInXAxis)
287{
288crossViewHeaderDescriptor.levelsize = MeasuresLevel - i;
289crossViewHeaderDescriptor.cellsize = MeasuresCount;
290}
291else
292{
293crossViewHeaderDescriptor.levelsize = XAxisFieldsCount - i;
294crossViewHeaderDescriptor.cellsize = 1;
295}
296cell += crossViewHeaderDescriptor.cellsize;
297Columns.Add(crossViewHeaderDescriptor);
298
299if ((crossViewHeaderDescriptor.level + crossViewHeaderDescriptor.levelsize == XAxisFieldsCount))
300{
301Array.Resize(ref columnTerminalIndexes, columnTerminalIndexes.Length + 1);
302columnTerminalIndexes[columnTerminalIndexes.Length - 1] = Columns.Count - 1;
303}
304}
305}
306if (Columns.Count == 0)
307{
308crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", "", false, true, false);
309crossViewHeaderDescriptor.level = 0;
310crossViewHeaderDescriptor.levelsize = 1;
311crossViewHeaderDescriptor.cell = 0;
312crossViewHeaderDescriptor.cellsize = 1;
313Columns.Add(crossViewHeaderDescriptor);
314Array.Resize(ref rowDescriptorsIndexes, rowDescriptorsIndexes.Length + 1);
315rowDescriptorsIndexes[rowDescriptorsIndexes.Length - 1] = Columns.Count - 1;
316Array.Resize(ref columnTerminalIndexes, columnTerminalIndexes.Length + 1);
317columnTerminalIndexes[columnTerminalIndexes.Length - 1] = Columns.Count - 1;
318}
319
320for (int i = 0; i < YAxisFieldsCount; i++)
321{
322cell = 0;
323if (MeasuresInYAxis && (MeasuresLevel <= i))
324{
325if (MeasuresLevel == i)
326{
327for (int k = 0; k <= i; k++)
328{
329for (int j = 0; j < MeasuresCount; j++)
330{
331if (k == i)
332{
333crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", CubeSource.GetMeasureName(j), false, false, true);
334crossViewHeaderDescriptor.cellsize = 1;
335crossViewHeaderDescriptor.levelsize = YAxisFieldsCount - i;
336}
337else
338{
339crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetYAxisFieldName(k), CubeSource.GetMeasureName(j), false, false, true);
340crossViewHeaderDescriptor.cellsize = (YAxisFieldsCount - i);
341crossViewHeaderDescriptor.levelsize = 1;
342}
343crossViewHeaderDescriptor.level = i;
344crossViewHeaderDescriptor.cell = cell;
345cell += crossViewHeaderDescriptor.cellsize;
346Rows.Add(crossViewHeaderDescriptor);
347if ((j == 0) && (k == 0))
348{
349Array.Resize(ref columnDescriptorsIndexes, columnDescriptorsIndexes.Length + 1);
350columnDescriptorsIndexes[columnDescriptorsIndexes.Length - 1] = Rows.Count - 1;
351}
352if ((k == i) || (i == (YAxisFieldsCount - 1)))
353{
354Array.Resize(ref rowTerminalIndexes, rowTerminalIndexes.Length + 1);
355rowTerminalIndexes[rowTerminalIndexes.Length - 1] = Rows.Count - 1;
356}
357}
358}
359}
360else
361{
362for (int j = 0; j < MeasuresCount; j++)
363{
364crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetYAxisFieldName(i), "", false, false, false);
365crossViewHeaderDescriptor.level = i;
366crossViewHeaderDescriptor.levelsize = 1;
367crossViewHeaderDescriptor.cell = cell;
368crossViewHeaderDescriptor.cellsize = YAxisFieldsCount - i;
369cell += crossViewHeaderDescriptor.cellsize;
370Rows.Add(crossViewHeaderDescriptor);
371if (j == 0)
372{
373Array.Resize(ref columnDescriptorsIndexes, columnDescriptorsIndexes.Length + 1);
374columnDescriptorsIndexes[columnDescriptorsIndexes.Length - 1] = Rows.Count - 1;
375}
376
377if (i == 1)
378{
379crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", "", false, true, false);
380}
381else
382if (i == (MeasuresLevel + 1))
383{
384crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetYAxisFieldName(i - 2), "", true, false, false);
385}
386else
387{
388crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetYAxisFieldName(i - 1), "", true, false, false);
389}
390crossViewHeaderDescriptor.level = i;
391crossViewHeaderDescriptor.levelsize = YAxisFieldsCount - i;
392crossViewHeaderDescriptor.cell = cell;
393crossViewHeaderDescriptor.cellsize = 1;
394cell += crossViewHeaderDescriptor.cellsize;
395Rows.Add(crossViewHeaderDescriptor);
396
397if ((crossViewHeaderDescriptor.level + crossViewHeaderDescriptor.levelsize == YAxisFieldsCount))
398{
399Array.Resize(ref rowTerminalIndexes, rowTerminalIndexes.Length + 1);
400rowTerminalIndexes[rowTerminalIndexes.Length - 1] = Rows.Count - 1;
401}
402}
403}
404}
405else
406{
407crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetYAxisFieldName(i), "", false, false, false);
408crossViewHeaderDescriptor.level = i;
409crossViewHeaderDescriptor.levelsize = 1;
410crossViewHeaderDescriptor.cell = cell;
411if (MeasuresInYAxis)
412{
413crossViewHeaderDescriptor.cellsize = (YAxisFieldsCount - i - 1) * MeasuresCount;
414if (crossViewHeaderDescriptor.cellsize == 0)
415crossViewHeaderDescriptor.cellsize = MeasuresCount;
416}
417else
418{
419crossViewHeaderDescriptor.cellsize = YAxisFieldsCount - i;
420}
421cell += crossViewHeaderDescriptor.cellsize;
422Rows.Add(crossViewHeaderDescriptor);
423if ((crossViewHeaderDescriptor.level + crossViewHeaderDescriptor.levelsize == YAxisFieldsCount))
424{
425Array.Resize(ref rowTerminalIndexes, rowTerminalIndexes.Length + 1);
426rowTerminalIndexes[rowTerminalIndexes.Length - 1] = Rows.Count - 1;
427}
428
429Array.Resize(ref columnDescriptorsIndexes, columnDescriptorsIndexes.Length + 1);
430columnDescriptorsIndexes[columnDescriptorsIndexes.Length - 1] = Rows.Count - 1;
431
432if (i == 0)
433{
434crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", "", false, true, false);
435}
436else
437{
438crossViewHeaderDescriptor = new CrossViewHeaderDescriptor(CubeSource.GetYAxisFieldName(i - 1), "", true, false, false);
439}
440crossViewHeaderDescriptor.level = i;
441crossViewHeaderDescriptor.cell = cell;
442if (MeasuresInYAxis)
443{
444crossViewHeaderDescriptor.levelsize = MeasuresLevel - i;
445crossViewHeaderDescriptor.cellsize = MeasuresCount;
446}
447else
448{
449crossViewHeaderDescriptor.levelsize = YAxisFieldsCount - i;
450crossViewHeaderDescriptor.cellsize = 1;
451}
452cell += crossViewHeaderDescriptor.cellsize;
453Rows.Add(crossViewHeaderDescriptor);
454
455if ((crossViewHeaderDescriptor.level + crossViewHeaderDescriptor.levelsize == YAxisFieldsCount))
456{
457Array.Resize(ref rowTerminalIndexes, rowTerminalIndexes.Length + 1);
458rowTerminalIndexes[rowTerminalIndexes.Length - 1] = Rows.Count - 1;
459}
460}
461}
462if (Rows.Count == 0)
463{
464crossViewHeaderDescriptor = new CrossViewHeaderDescriptor("", "", false, true, false);
465crossViewHeaderDescriptor.level = 0;
466crossViewHeaderDescriptor.levelsize = 1;
467crossViewHeaderDescriptor.cell = 0;
468crossViewHeaderDescriptor.cellsize = 1;
469Rows.Add(crossViewHeaderDescriptor);
470Array.Resize(ref columnDescriptorsIndexes, columnDescriptorsIndexes.Length + 1);
471columnDescriptorsIndexes[columnDescriptorsIndexes.Length - 1] = Rows.Count - 1;
472Array.Resize(ref rowTerminalIndexes, rowTerminalIndexes.Length + 1);
473rowTerminalIndexes[rowTerminalIndexes.Length - 1] = Rows.Count - 1;
474}
475CrossViewCellDescriptor crossViewCellDescriptor;
476for (int i = 0; i < columnTerminalIndexes.Length; i++)
477{
478for (int j = 0; j < rowTerminalIndexes.Length; j++)
479{
480crossViewCellDescriptor = 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);
481crossViewCellDescriptor.x = i;
482crossViewCellDescriptor.y = j;
483Cells.Add(crossViewCellDescriptor);
484}
485}
486}
487
488internal CrossViewHeaderDescriptor GetRowDescriptor(int index)
489{
490int tempXAxisFieldsCount = (!SourceAssigned) ? 1 : XAxisFieldsCount;
491if (index < tempXAxisFieldsCount)
492{
493return Columns[rowDescriptorsIndexes[index]];
494}
495else
496{
497return Rows[rowTerminalIndexes[index - tempXAxisFieldsCount]];
498}
499}
500
501internal CrossViewHeaderDescriptor GetColumnDescriptor(int index)
502{
503int tempYAxisFieldsCount = (!SourceAssigned) ? 1 : YAxisFieldsCount;
504if (index < tempYAxisFieldsCount)
505{
506return Rows[columnDescriptorsIndexes[index]];
507}
508else
509{
510return Columns[columnTerminalIndexes[index - tempYAxisFieldsCount]];
511}
512}
513#endregion
514
515#region Properties
516/// <summary>
517/// Gets a collection of column descriptors.
518/// </summary>
519/// <remarks>
520/// Note: after you change something in this collection, call the
521/// <see cref="CrossViewObject.BuildTemplate"/> method to refresh the CrossView.
522/// </remarks>
523public CrossViewHeader Columns
524{
525get { return columns; }
526}
527
528/// <summary>
529/// Gets a collection of row descriptors.
530/// </summary>
531/// <remarks>
532/// Note: after you change something in this collection, call the
533/// <see cref="CrossViewObject.BuildTemplate"/> method to refresh the CrossView.
534/// </remarks>
535public CrossViewHeader Rows
536{
537get { return rows; }
538}
539
540/// <summary>
541/// Gets a collection of data cell descriptors.
542/// </summary>
543/// <remarks>
544/// Note: after you change something in this collection, call the
545/// <see cref="CrossViewObject.BuildTemplate"/> method to refresh the CrossView.
546/// </remarks>
547public CrossViewCells Cells
548{
549get { return cells; }
550}
551
552#endregion
553
554#region Public Methods
555#endregion
556
557internal CrossViewData()
558{
559columns = new CrossViewHeader();
560columns.Name = "CrossViewColumns";
561rows = new CrossViewHeader();
562rows.Name = "CrossViewRows";
563cells = new CrossViewCells();
564cells.Name = "CrossViewCells";
565CreateDescriptors();
566}
567}
568}