public override TableDefinition Content(ReportData reportData, Dictionary <string, string> options) { int count = 0; string[] qidList = options.GetOption("QID")?.Split('|'); string[] sidList = options.GetOption("SID")?.Split('|'); string[] bidList = options.GetOption("BID")?.Split('|'); // we can add the header only after getting the data, because names are in the data var rowData = new List <string>(); #region get Metric names Dictionary <string, string> names = new Dictionary <string, string>(); if (qidList != null) { foreach (string id in qidList) { if (names.Keys.Contains(id)) { continue; } if (string.IsNullOrEmpty(BusinessCriteriaUtility.GetMetricName(reportData.CurrentSnapshot, int.Parse(id)))) { continue; } names[id] = BusinessCriteriaUtility.GetMetricName(reportData.CurrentSnapshot, int.Parse(id)); } } if (sidList != null) { foreach (string id in sidList) { if (names.Keys.Contains(id)) { continue; } if (string.IsNullOrEmpty(MeasureUtility.GetSizingMeasureName(reportData.CurrentSnapshot, int.Parse(id)))) { continue; } names[id] = MeasureUtility.GetSizingMeasureName(reportData.CurrentSnapshot, int.Parse(id)); } } // No background facts for technologies if (bidList != null) { foreach (string id in bidList) { if (names.Keys.Contains(id)) { continue; } Result bfResult = reportData.SnapshotExplorer.GetBackgroundFacts(reportData.CurrentSnapshot.Href, id, true, true).FirstOrDefault(); if (bfResult == null || !bfResult.ApplicationResults.Any()) { continue; } if (string.IsNullOrEmpty(bfResult.ApplicationResults[0].Reference.Name)) { continue; } names[id] = bfResult.ApplicationResults[0].Reference.Name; } } rowData.Add(" "); rowData.AddRange(names.Values); #endregion int nbSnapshots = reportData?.Application.Snapshots?.Count() ?? 0; if (nbSnapshots > 0) { // ReSharper disable once PossibleNullReferenceException // ReSharper disable once AssignNullToNotNullAttribute foreach (Snapshot snapshot in reportData.Application.Snapshots.OrderBy(_ => _.Annotation.Date.DateSnapShot)) { rowData.Add(snapshot.Annotation.Date.DateSnapShot?.ToOADate().ToString(CultureInfo.CurrentCulture) ?? string.Empty); Dictionary <string, string> values = new Dictionary <string, string>(); // iterate in QID if (qidList != null) { foreach (string id in qidList) { if (!names.Keys.Contains(id)) { continue; } ApplicationResult res = reportData.SnapshotExplorer.GetQualityIndicatorResults(snapshot.Href, id.Trim())?.FirstOrDefault()?.ApplicationResults?.FirstOrDefault(); string idValue = res?.DetailResult?.Grade?.ToString("N2") ?? Constants.Zero; if (!values.Keys.Contains(id)) { values.Add(id, idValue); } } } // iterate in SID if (sidList != null) { foreach (string id in sidList) { if (!names.Keys.Contains(id)) { continue; } ApplicationResult res = reportData.SnapshotExplorer.GetSizingMeasureResults(snapshot.Href, id.Trim())?.FirstOrDefault()?.ApplicationResults?.FirstOrDefault(); string idValue = res?.DetailResult?.Value?.ToString("F0") ?? Constants.Zero; if (!values.Keys.Contains(id)) { values.Add(id, idValue); } } } // iterate in BID if (bidList != null) { foreach (string id in bidList) { if (!names.Keys.Contains(id)) { continue; } ApplicationResult res = reportData.SnapshotExplorer.GetBackgroundFacts(snapshot.Href, id.Trim())?.FirstOrDefault()?.ApplicationResults?.FirstOrDefault(); // F0 as format to avoid the ',' that make graph build crash string idValue = res?.DetailResult?.Value?.ToString("F0") ?? Constants.Zero; if (!values.Keys.Contains(id)) { values.Add(id, idValue); } } } rowData.AddRange(values.Values); } count = nbSnapshots; } #region just 1 snapshot // if there is only one snapshot, a fake snapshot is added with same data to have a line and not a point in the graph if (count == 1) { string[] range = new string[names.Count + 1]; for (int k = 0; k < names.Count + 1; k++) { range[k] = rowData[k + names.Count + 1]; } rowData.AddRange(range); count = count + 1; } #endregion just 1 snapshot TableDefinition resultTable = new TableDefinition { HasRowHeaders = true, HasColumnHeaders = false, NbRows = count + 1, NbColumns = names.Count + 1, Data = rowData }; return(resultTable); }