protected override bool RenderInternal(ref MemoryStream chunk, out string mime) { mime = null; try { /* this is about rendering: * what does the user want us to render -> * see if this renderer can do what she asks for */ if (Outputformat == FileType.ft_html) { /* expect this to be delivered: */ mime = SetResultDisposition(ResultFileBasename + ".html", FileType.ft_html); if (chunk == null) { chunk = new MemoryStream(); } /* employ a html rendering engine */ var engine = new HtmlTemplateEngine(chunk); /* compose the parts */ if (DoRenderHeaderUsingTemplate) { engine.RenderHeader( this, PresentationOptions.HasFlag(ReportPresentationOptions.ShowTitle), PresentationOptions.HasFlag(ReportPresentationOptions.ShowLogo) ); } if (DoRenderMetaUsingTemplate) { engine.RenderMetadata( this, PresentationOptions.HasFlag(ReportPresentationOptions.ShowMetadata), PresentationOptions.HasFlag(ReportPresentationOptions.ShowCriteria), PresentationOptions.HasFlag(ReportPresentationOptions.ShowQRCode) ); } /* the actual content (report rendition) */ RenderBody(engine); /* submit everything */ engine.SubmitToStream(this); } else if (Outputformat == FileType.ft_pdf) { /* use TEX to render as a pdf */ } else { /* cannot render that... */ throw new NotSupportedException(Outputformat.ToString()); } /* succeeded */ return(true); } catch (Exception ex) { /* some error */ OnBuiltinReportError(ex.Message, ex); return(false); } }
/// <summary> /// [pkosec 20140417] creating an image on fly, resembling a 2-dimensional table (=matrix) /// </summary> /// <param name="category"></param> /// <param name="rptds"></param> protected Image CreateCrosstabImg(string category, List <rpt.builtin.msdbrpt_datasources.ReportStatistics001Matrix> rptds) { var dicColumnHeading = new Dictionary <string, float>(); var dicRowHeading = new Dictionary <string, float>(); var lstRowValues = new List <decimal>(); var lstRowValuesWidth = new List <int>(); Font font = null; SolidBrush blackBrush = null; SolidBrush maroonBrush = null; SolidBrush whiteBrush = null; Pen blackPen = null; Pen silverPen = null; Bitmap bmp = null; Rectangle rect; PointF point; int xPos, yPos; float minCellWidth; int firstCellOffset; int ImgWidth; int cellHeight; int percentageWidth; try { using (var bmp_unity = new Bitmap(1, 1, PixelFormat.Format32bppArgb)) { using (var g = Graphics.FromImage(bmp_unity)) { font = new Font("Arial", 14); blackBrush = new SolidBrush(Color.Black); maroonBrush = new SolidBrush(Color.Maroon); whiteBrush = new SolidBrush(Color.White); blackPen = new Pen(Color.Black); silverPen = new Pen(Color.Silver); cellHeight = (int)g.MeasureString("M", font).Height; /* em :-) */ percentageWidth = (int)g.MeasureString(" (%)", font).Width; /* iterate [dlatikay 20140417] only once */ foreach (var item in rptds) { /* populate column headings */ if (!dicColumnHeading.ContainsKey(item.Series)) { dicColumnHeading.Add(item.Series, (int)g.MeasureString(item.Series, font).Width); } /* populate row headings */ if (!dicRowHeading.ContainsKey(item.Category)) { dicRowHeading.Add(item.Category, (int)g.MeasureString(item.Category, font).Width); } /* populate row values */ lstRowValues.Add(item.Value); /* - !! - would be good if there is a precision check which evaluates the max. number of significant digits */ lstRowValuesWidth.Add((int)g.MeasureString(item.Value.ToString(), font).Width); } /* image structure example with percentage computation: * -------------------------------------------------------------------------------------------- * | category caption | series name 1 | series name 1 (%) | series name 2 | series name 2 (%) | * -------------------------------------------------------------------------------------------- * | category name 1 | value 1 | value 1 in % | value 2 | value 2 in % | * -------------------------------------------------------------------------------------------- * | category name 2 | value 3 | value 3 in % | value 4 | value 4 in % | * -------------------------------------------------------------------------------------------- */ /* compute min. cell width */ minCellWidth = dicColumnHeading.Min(x => x.Value) > lstRowValuesWidth.Min() ? dicColumnHeading.Min(x => x.Value) : lstRowValuesWidth.Min(); /* compute first cell */ firstCellOffset = (int)dicRowHeading.Max(x => x.Value) < (int)g.MeasureString(category, font).Width ? (int)g.MeasureString(category, font).Width : (int)dicRowHeading.Max(x => x.Value); /* compute image size */ ImgWidth = firstCellOffset + (int)dicColumnHeading.Sum(x => { /* column width is less than cell width */ if (x.Value < lstRowValuesWidth.Min()) { return(lstRowValuesWidth.Min()); /* take min. cell width */ } else { return(x.Value); /* else take column width */ } }); /* adding additional columns' width when showing the percentage */ if (PresentationOptions.HasFlag(ReportPresentationOptions.AsPercentages)) { ImgWidth += (int)dicColumnHeading.Sum(x => { if (x.Value < lstRowValuesWidth.Min()) { return(lstRowValuesWidth.Min() + percentageWidth); } else { return(x.Value + percentageWidth); } }); } } } int ImgHeight = cellHeight * (dicRowHeading.Count + 1); /* create image */ bmp = new Bitmap(ImgWidth, ImgHeight, PixelFormat.Format32bppArgb); /* load graphics and draw */ using (var g = Graphics.FromImage(bmp)) { g.Clear(Color.White); /* set white background */ /* high quality image parameters */ g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit; /* starting position */ xPos = yPos = 0; /* draw first cell */ rect = new Rectangle(xPos, yPos, firstCellOffset, cellHeight); g.FillRectangle(maroonBrush, rect); rect = new Rectangle(xPos, yPos, firstCellOffset, cellHeight); g.DrawRectangle(blackPen, rect); point = new PointF(xPos, yPos); g.DrawString(category, font, whiteBrush, point); /* move right */ xPos = firstCellOffset; /* draw column headings */ foreach (var column in dicColumnHeading) { /* draw heading background */ rect = new Rectangle(xPos, yPos, Max((int)column.Value, (int)minCellWidth), cellHeight); g.FillRectangle(maroonBrush, rect); /* draw heading border */ rect = new Rectangle(xPos, yPos, Max((int)column.Value, (int)minCellWidth), cellHeight); g.DrawRectangle(silverPen, rect); /* draw heading text */ point = new PointF(xPos, yPos); g.DrawString(column.Key, font, whiteBrush, point); /* move right */ xPos += Max((int)column.Value, (int)minCellWidth); /* draw percentage column if necessary */ if (PresentationOptions.HasFlag(ReportPresentationOptions.AsPercentages)) { /* draw heading background */ rect = new Rectangle(xPos, yPos, Max((int)column.Value + percentageWidth, (int)minCellWidth), cellHeight); g.FillRectangle(maroonBrush, rect); /* draw heading border */ rect = new Rectangle(xPos, yPos, Max((int)column.Value + percentageWidth, (int)minCellWidth), cellHeight); g.DrawRectangle(silverPen, rect); /* draw heading text */ point = new PointF(xPos, yPos); g.DrawString(column.Key + " (%)", font, whiteBrush, point); /* move right */ xPos += Max((int)column.Value + percentageWidth, (int)minCellWidth); } } yPos = cellHeight; /* move down */ int j = 0; StringFormat stringFormat = new StringFormat(); stringFormat.Alignment = StringAlignment.Far; stringFormat.LineAlignment = StringAlignment.Far; /* draw row headings and values */ foreach (var row in dicRowHeading) { xPos = 0; /* reset */ point = new PointF(xPos, yPos); /* drawing location */ g.DrawString(row.Key, font, blackBrush, point); /* draw row heading */ rect = new Rectangle(xPos, yPos, firstCellOffset, cellHeight); g.DrawRectangle(silverPen, rect); xPos += firstCellOffset; /* move right */ /* always iterate through columns, because the width of a column * must match the width of a cell value */ foreach (var column in dicColumnHeading) { /* drawing location */ point = new PointF(xPos, yPos); /* right cell value alignment via StringFormat */ rect = new Rectangle(xPos, yPos, Max((int)column.Value, (int)minCellWidth), cellHeight); /* [pkosec 20140418] detect if the value must be shown as a percentage (PK20140418ADSKADOKAFHIOWD) */ /* and draw the value with right alignment (finding current cell via index) */ g.DrawString(lstRowValues[j].ToString(this.Culture), font, blackBrush, rect, stringFormat); /* draw cell border */ g.DrawRectangle(silverPen, rect); /* use column width to move right */ xPos += Max((int)column.Value, (int)minCellWidth); /* draw percentage value if necessary */ if (PresentationOptions.HasFlag(ReportPresentationOptions.AsPercentages)) { point = new PointF(xPos, yPos); rect = new Rectangle(xPos, yPos, Max((int)column.Value + percentageWidth, (int)minCellWidth), cellHeight); g.DrawString(ComputePercentage(lstRowValues, lstRowValues[j], dicColumnHeading.Count, j), font, blackBrush, rect, stringFormat); xPos += Max((int)column.Value + percentageWidth, (int)minCellWidth); g.DrawRectangle(silverPen, rect); } /* next cell value */ j++; } yPos += cellHeight; /* move down */ } /* draw a black table outter-border */ rect = new Rectangle(0, 0, ImgWidth - 1, ImgHeight - 1); g.DrawRectangle(blackPen, rect); } /* resulting img: caller is responsible of disposing */ return(bmp); } catch (Exception ex) { /* some error */ OnBuiltinReportError(ex.Message, ex); throw; } finally { /* clean up */ if (font != null) { font.Dispose(); } if (blackBrush != null) { blackBrush.Dispose(); } if (maroonBrush != null) { maroonBrush.Dispose(); } if (whiteBrush != null) { whiteBrush.Dispose(); } if (blackPen != null) { blackPen.Dispose(); } if (silverPen != null) { silverPen.Dispose(); } } }
/// <summary> /// Returns a transformed data table, similar layout as CreateCrosstabImg /// </summary> /// <param name="rptds"></param> /// <returns></returns> protected DataTable TransformMatrix(string category, List <rpt.builtin.msdbrpt_datasources.ReportStatistics001Matrix> rptds) { var lstColumnHeading = new List <string>(); var lstRowHeading = new List <string>(); var lstRowValues = new List <decimal>(); DataTable dt = new DataTable(); var column_is_percentage = new Dictionary <int, bool>(); int colindex = 0; /* 1. data lookup */ foreach (var item in rptds) { if (!lstColumnHeading.Contains(item.Series)) { /* attention: category label = content of first cell is not part of the lstColumnHeading */ lstColumnHeading.Add(item.Series); column_is_percentage.Add(++colindex, false); if (PresentationOptions.HasFlag(ReportPresentationOptions.AsPercentages)) { lstColumnHeading.Add(item.Series + " (%)"); column_is_percentage.Add(++colindex, true); } } if (!lstRowHeading.Contains(item.Category)) { lstRowHeading.Add(item.Category); } lstRowValues.Add(item.Value); } /* 2. creating columns */ dt.Columns.Add("Category"); /* first column (Category) */ /* the number of columns can vary (Series) */ for (int i = 1; i <= lstColumnHeading.Count; i++) { if (column_is_percentage[i]) { /* when a percentage computation is instructed by a user, we need to add additional columns */ dt.Columns.Add("SeriesPercentage" + i); } else { dt.Columns.Add("Series" + i); } } /* 3. re-arranging data */ int k = -1; int count_of_nonpercentage_columns = (from c in column_is_percentage where c.Value == false select c).Count(); /* move vertically */ for (int j = 0; j <= lstRowHeading.Count; j++) { /* create new row */ DataRow dr = dt.NewRow(); string colname; /* move horizontally */ for (int i = 0; i <= lstColumnHeading.Count; i++) { /* in the first iteration */ if (j == 0) { /* we set the caption of our category */ if (i == 0) { dr["Category"] = category; } else { /* and next the captions of our series */ if (column_is_percentage[i]) { colname = "SeriesPercentage" + i; } else { colname = "Series" + i; } dr[colname] = lstColumnHeading[i - 1]; } } /* for upcoming other iterations (second row onwards) */ else { /* we set the values of our category */ if (i == 0) { dr["Category"] = lstRowHeading[j - 1]; } /* and next the values of our series */ else { if (column_is_percentage[i]) { colname = "SeriesPercentage" + i; } else { colname = "Series" + i; } if (column_is_percentage[i]) { dr[colname] = ComputePercentage(lstRowValues, lstRowValues[k], count_of_nonpercentage_columns, k); } else { dr[colname] = lstRowValues[++k].ToString(this.Culture); } } } } /* add row */ dt.Rows.Add(dr); } /* 4. deliver result */ return(dt); }
protected override bool RenderInternal(ref MemoryStream chunk, out string mime) { mime = null; var tmpfilename = String.Format("{0}.xlsx", Guid.NewGuid().ToString()); var cutoff = this.DateGenerated; bool with_detailed_history = PresentationOptions.HasFlag(ReportPresentationOptions.ShowSubrecords); bool suppress_zerolines = PresentationOptions.HasFlag(ReportPresentationOptions.Suppresszero); try { /* 1. convert the flat data into a less entropic form */ var emps = new Employees(); var tops = new Topics(); /* 1a. persons */ DataTable tab_pers = Data.Tables[ReportDatatableIdentifiers.REPORT_DATATABLE_TRA001_OVERVIEW_PER]; foreach (DataRow dr in tab_pers.Rows) { var middlename = dr["Middlename"].ToString(); var orgabbrev = dr["OrgAbbrev"].ToString(); var orgshortcap = dr["OrgShortCap"].ToString(); /* (not used) */ var orglongcap = dr["OrgLongCap"].ToString(); var orgcap = orgabbrev; if (orglongcap != orgabbrev) { orgcap = String.Format("{0} {1}", orgcap, orglongcap).TrimEnd(); } var emp = new Employee() { PerID = Convert.ToInt32(dr["PerID"]), Lastname = dr["Lastname"].ToString(), Firstname = dr["Firstname"].ToString(), PersNr = dr["PersNr"].ToString(), Company = dr["Companyname"].ToString(), OrgCap = orgcap, }; if (String.IsNullOrEmpty(middlename) == false) { emp.Lastname = String.Format("{0} {1}", middlename, emp.Lastname).TrimEnd(); /* van den Bosch */ } emps.Add(emp.PerID, emp); } /* alleviate memory pressure */ Data.Tables.Remove(tab_pers); tab_pers = null; /* 1b. all the rest (topics, participations) */ DataTable tab_patn = Data.Tables[ReportDatatableIdentifiers.REPORT_DATATABLE_TRA001_OVERVIEW_PTN]; foreach (DataRow dr in tab_patn.Rows) { /* harvest */ var PerID = Convert.ToInt32(dr["PerID"]); var TopicID = Convert.ToInt32(dr["TopicID"]); var Caption = dr["Caption"].ToString(); DateTime DateTraining = dr["DateTraining"].Equals(DBNull.Value) ? Convert.ToDateTime(dr["DateMeasure"]) : Convert.ToDateTime(dr["DateTraining"]); DateTime?dateattended = dr["DateAttended"].Equals(DBNull.Value) ? (DateTime?)null : Convert.ToDateTime(dr["DateAttended"]); var hasattended = Convert.ToInt32(dr["HasAttended"]) > 0; int? validityfactor = null; Timeunit?validityunit = null; if (dr["RequirementValidityFactor"].Equals(DBNull.Value) == false) { validityfactor = Convert.ToInt32(dr["RequirementValidityFactor"]); validityunit = (Timeunit)Convert.ToInt32(dr["RequirementValidityUnit"]); } /* logic rule: if attended, but no specific date given, value with assumption training date = attendance date */ if (hasattended && dateattended.HasValue == false) { dateattended = DateTraining; } /* logic rule: if a date attended is given, but the checkmark is not set, it may not count (C-1512-0454.1) */ if (hasattended == false && dateattended.HasValue) { dateattended = null; } /* slotify: * 1c. the employee */ if (emps.ContainsKey(PerID)) { var empX = emps[PerID]; if (empX.Attendances.Count(a => a.Key.Item1 == DateTraining && a.Key.Item2 == TopicID) == 0) /* [dlatikay 20170131] previously, this had only been checking for date, causing follow-up troubles mdettmarg @ C-1611-0558 */ { var attendancestatus = StatisticalAttendanceStatus.WHITENotPlanned; if (dateattended.HasValue) { attendancestatus = StatisticalAttendanceStatus.GREENAttended; } else { if (DateTraining >= cutoff) { attendancestatus = StatisticalAttendanceStatus.WHITEPlanned; } else { attendancestatus = StatisticalAttendanceStatus.REDOverdue; } } var attx = new Attendance() { PerID = PerID, attended_when = dateattended, DateTraining = DateTraining, TopicID = TopicID, Participation = attendancestatus }; empX.Attendances.Add(new Tuple <DateTime, int>(DateTraining, TopicID), attx); /* is this a (better) most recent attendance of this person? * [dlatikay 20160402] likely the site of C-1512-0454.II.N */ if ((attx.attended_when ?? attx.DateTraining) <= cutoff && attx.Participation != StatisticalAttendanceStatus.WHITENotPlanned) { if (empX.MostRecentAttendance.ContainsKey(TopicID) == false) { empX.MostRecentAttendance.Add(TopicID, attx); } else { var cand = empX.MostRecentAttendance[TopicID]; if ((cand.attended_when ?? cand.DateTraining) < (attx.attended_when ?? attx.DateTraining)) { empX.MostRecentAttendance.Remove(TopicID); empX.MostRecentAttendance.Add(TopicID, attx); } } } } } /* 1d. the topic */ if (tops.ContainsKey(TopicID) == false) { tops.Add(TopicID, new Topic() { TopicID = TopicID, Caption = Caption, ValidityFactor = validityfactor ?? ValidityFactorDefault, ValidityUnit = validityunit ?? ValidityUnitDefault }); } var top = tops[TopicID]; if (top.AttendanceSlots.Contains(DateTraining) == false) { top.AttendanceSlots.Add(DateTraining); } } /* alleviate */ Data.Tables.Remove(tab_patn); tab_patn = null; /* 2. instantiate the epplus templating engine */ var template = new FileInfo(Path.Combine(CustomAbsPath, String.Format("{0}.xlsx", ResultFileBasename))); var dest = new FileInfo(Path.Combine(RptTmpBasepath, tmpfilename)); using (var package = new ExcelPackage(dest, template)) { ExcelWorkbook wbk = package.Workbook; ExcelWorksheet sht = wbk.Worksheets[1]; /* 2. populate the template into the new file */ //var dt = Data.Tables[ReportDatatableIdentifiers.REPORT_DATATABLE_HARDCOPY_SAFETY_003].Rows[0]; wbk.Names["Title"].Value = m(5483); /* Excel® Training Overview */ wbk.Names["lCriteria"].Value = m(4494, ReportQueryDateLocal); /* Data as per {0} */ wbk.Names["PersNr"].Value = m(588); /* Employee # */ wbk.Names["Name"].Value = m(744); /* Name */ wbk.Names["lFirstname"].Value = m(478); /* First name */ wbk.Names["lDepartment"].Value = m(2279); /* Department */ wbk.Names["Company"].Value = m(746); /* Company */ /* 2a. write the topics with their date slot headings horizontally */ var columnmap = new Dictionary <int, Dictionary <DateTime, int> >(); var col = 6; foreach (var top in from t in tops.Values orderby t.Caption, t.TopicID select t) { /* write topic header, 1 = most recent */ var spanning = 1 + top.AttendanceSlots.Count; sht.Cells[4, col].Value = top.Caption; sht.Cells[5, col].Value = "Letzte absolvierte Unterweisung"; columnmap.Add(top.TopicID, new Dictionary <DateTime, int>()); columnmap[top.TopicID].Add(DateTime.MinValue, col); /* this maps to the current topic's "most recent training" column */ ++col; /* write topic date slots */ if (with_detailed_history) { bool first = true; foreach (var dat in from d in top.AttendanceSlots orderby d select d) { if (dat >= DateFrom && dat <= DateTo) { if (first) { sht.Cells[5, col].Value = "Plandatum"; first = false; } sht.Cells[5, col].Value = dat; columnmap[top.TopicID].Add(dat, col); /* this maps to that "planned date" column of the current topic */ sht.Cells[5, col].Style.Numberformat.Format = "dd.mm.yyyy"; sht.Cells[5, col].Style.TextRotation = 90; ++col; } } } } /* 2b. write the employee names and static associated data vertically, omitting those with no data if we should */ int row = 7; foreach (var emp in from e in emps.Values orderby e.Lastname, e.Firstname, e.PersNr, e.PerID select e) { if (suppress_zerolines == false || emp.Attendances.Count > 0) { sht.Cells[row, 1].Value = emp.PersNr; sht.Cells[row, 2].Value = emp.Lastname; sht.Cells[row, 3].Value = emp.Firstname; sht.Cells[row, 4].Value = emp.OrgCap; sht.Cells[row, 5].Value = emp.Company; /* fill the topic/date slot-matrix body; * write date of most recent training per topic */ foreach (var mra in from mrae in emp.MostRecentAttendance select mrae) { var topicid = mra.Key; col = columnmap[topicid][DateTime.MinValue]; var status = emp.MostRecentAttendanceStatus(tops[topicid], cutoff); if (status != StatisticalAttendanceStatusRecent.WHITENeverPlannedNorAttended) { sht.Cells[row, col].Value = mra.Value.attended_when ?? mra.Value.DateTraining; sht.Cells[row, col].Style.Numberformat.Format = "dd.mm.yyyy"; if (status == StatisticalAttendanceStatusRecent.GREENDoneAndValidToday) { sht.Cells[row, col].Style.Fill.PatternType = ExcelFillStyle.Solid; sht.Cells[row, col].Style.Fill.BackgroundColor.SetColor(Color.Green); } else if (status == StatisticalAttendanceStatusRecent.REDDoneButExpired) { sht.Cells[row, col].Style.Fill.PatternType = ExcelFillStyle.Solid; sht.Cells[row, col].Style.Fill.BackgroundColor.SetColor(Color.Red); } } } /* if asked for, render the entire topic history of that empoyee */ if (with_detailed_history) { foreach (var att in from a in emp.Attendances.Values select a) { if (att.DateTraining >= DateFrom && att.DateTraining <= DateTo) { col = columnmap[att.TopicID][att.DateTraining]; if (att.Participation != StatisticalAttendanceStatus.WHITENotPlanned) { sht.Cells[row, col].Value = att.attended_when ?? att.DateTraining; sht.Cells[row, col].Style.Numberformat.Format = "dd.mm.yyyy"; if (att.Participation == StatisticalAttendanceStatus.REDOverdue) { sht.Cells[row, col].Style.Fill.PatternType = ExcelFillStyle.Solid; sht.Cells[row, col].Style.Fill.BackgroundColor.SetColor(Color.Red); } else if (att.Participation == StatisticalAttendanceStatus.GREENAttended) { sht.Cells[row, col].Style.Fill.PatternType = ExcelFillStyle.Solid; sht.Cells[row, col].Style.Fill.BackgroundColor.SetColor(Color.Green); } } } } } /* outer (pers/employee) advance */ ++row; } } /* format properly */ sht.Cells.AutoFitColumns(); sht.View.FreezePanes(7, 1); /* limit column 4=D in width */ sht.Column(4).Width = 38.29; /* increase line 5 in height */ sht.Row(5).Height = 66.75; /* 3. render the report into the desired format */ package.SaveAs(chunk); if (chunk.CanSeek) { chunk.Seek(0, SeekOrigin.Begin); } GeneratedFileType = FileType.ft_xls; mime = sherm.core.formatting.mime.GetMIMEFromFiletype(Outputformat); TargetFilename = String.Format("{0}{1}", ResultFileBasename, template.Extension); } /* succeeded */ return(true); } catch (Exception ex) { /* some error */ OnBuiltinReportError(ex.Message, ex); return(false); } finally { /* cleanup */ try { if (File.Exists(tmpfilename)) { File.Delete(tmpfilename); } } catch (Exception ef) { Tracing.ErrorBkg("{0}", ef.ToString()); } } }
protected override bool RenderInternal(ref MemoryStream chunk, out string mime) { mime = null; try { /* this is about rendering: * what does the user want us to render -> * see if this renderer can do what she asks for */ if (Outputformat == FileType.ft_html || Outputformat == FileType.ft_pdf) { /* expect this to be delivered: */ mime = SetResultDisposition(ResultFileBasename, Outputformat); if (chunk == null) { chunk = new MemoryStream(); } /* employ a html rendering engine */ var engine = new HtmlTemplateEngine(chunk); /* compose the parts */ engine.RenderHeader( this, PresentationOptions.HasFlag(ReportPresentationOptions.ShowTitle), PresentationOptions.HasFlag(ReportPresentationOptions.ShowLogo) ); engine.RenderMetadata( this, PresentationOptions.HasFlag(ReportPresentationOptions.ShowMetadata), PresentationOptions.HasFlag(ReportPresentationOptions.ShowCriteria), PresentationOptions.HasFlag(ReportPresentationOptions.ShowQRCode) ); /* maybe some charts */ bool trendline = PresentationOptions.HasFlag(ReportPresentationOptions.Trendline); if (Presentation.HasFlag(ReportDefPresentations.Linechart)) { /* draw data into a line chart */ var line = RenderChart(ReportDefPresentations.Linechart); engine.SubmitChart(line); } if (Presentation.HasFlag(ReportDefPresentations.Barchart)) { /* draw data into a bar chart */ var bar = RenderChart(ReportDefPresentations.Barchart); engine.SubmitChart(bar); } if (Presentation.HasFlag(ReportDefPresentations.Piechart)) { /* draw data into a pie chart */ var pie = RenderChart(ReportDefPresentations.Piechart); engine.SubmitChart(pie); } /* maybe some tabular data */ if (Presentation.HasFlag(ReportDefPresentations.Crosstab)) { /* make a HTML crosstab out of the data */ //engine.SubmitCrosstab(AsCrosstab); } /* submit everything */ engine.SubmitToStream(this); } else { /* cannot render that... */ throw new NotSupportedException(Outputformat.ToString()); } /* succeeded */ return(true); } catch (Exception ex) { /* some error */ OnBuiltinReportError(ex.Message, ex); return(false); } }
private Chart RenderChart(ReportDefPresentations charttype) { var chart = new Chart(m) { GraphType = charttype }; /* generate series */ //var matrix = AsCrosstab; //if (matrix.ColumnHeadersDiscrete == null) //{ // /* single-series version: each X col header is a graph: // * a. one series per data row */ // int seriesordinal = 0; // foreach (var seriesitem in matrix.Rows) // chart.Series.Add(new ChartSeries() { Ordinal = ++seriesordinal, Seriesname = seriesitem.CompositeLabel }); // /* b. one graph per column */ // int graphordinal = 0; // foreach (var label in matrix.ColumnHeadersTopMerged) // { // var graph = new ChartGraph() // { // GraphType = charttype, // Ordinal = graphordinal + 1, // Title = label.ColumnDisplayname, // Color = GraphColor(graphordinal + 1) // }; // chart.Graphs.Add(graph); // /* assign the values from the matrix */ // seriesordinal = 0; // foreach (var row in matrix.Rows) // { // var val = row.Values[graphordinal]; // graph.Values.Add(++seriesordinal, new ChartValue() // { // SeriesOrdinal = seriesordinal, // iValue = val.iValue, // cValue = val.cValue, // sValue = row.Values[graphordinal].sValue // }); // } // /* next graph */ // ++graphordinal; // } // /* add a pareto graph? */ // if (PresentationOptions.HasFlag(ReportPresentationOptions.Pareto)) // { // Debug.Assert(PresentationOptions.HasFlag(ReportPresentationOptions.AsPercentages)); // var graph = new ChartGraph() // { // GraphType = ReportDefPresentations.Linechart, // Ordinal = ++graphordinal, // Title = OnBuiltinReportLiteral(2862), /* Pareto line */ // Color = Color.Maroon // }; // /* the data for the pareto line is in a separate data table */ // var pareto = Data.Tables[ReportDatatableIdentifiers.REPORT_DATATABLE_INCRCA_PARETOLINE]; // seriesordinal = 0; // foreach (DataRow row in pareto.Rows) // { // var val = Convert.ToInt32(row["Y"]); // graph.Values.Add(++seriesordinal, new ChartValue() // { // SeriesOrdinal = seriesordinal, // iValue = val, // sValue = val.ToString() // }); // } // if (seriesordinal > 0) // chart.Graphs.Add(graph); // } //} //else //{ // /* multi-series variation */ //} /* chart general props - the same for single- as well as for multi-series */ string sTitle; if (chart.Graphs.Count == 1) { sTitle = chart.Graphs[0].Title; } else { sTitle = String.Format(OnBuiltinReportLiteral(2846), chart.Graphs.Count.ToString()); /* {0} incident key performance indicators */ } chart.Title = String.Format(OnBuiltinReportLiteral(2845), sTitle); /* Chart 1. {0} */ chart.Stacked = PresentationOptions.HasFlag(ReportPresentationOptions.BarsStacked); chart.Animated = base.Animated; /* deliver */ return(chart); }