private void GenerateProductNetwork(XmlWriter writer) { var items = categories.GroupBy(x => x.Project) .Select(x => new { Project = x.Key, Contributors = x.SelectMany(y => y.Contributions.Select(z => z.Contributor).Distinct()).ToList() }).ToList(); // Setup reporting var totalCount = items.Count * items.Count * 3 / 2; var count = 0; var progress = 0; // Build grid var grid = new int[items.Count, items.Count]; for (var row = 0; row < items.Count; row++) { for (var col = row + 1; col < items.Count; col++) { var intersectCount = items[row].Contributors.Intersect(items[col].Contributors).Count(); grid[row, col] = intersectCount; // Report count++; progress = count * 100 / totalCount; ReportProgress(progress); } } // Setup header writer.CreateRow() .WriteCell(string.Empty); foreach (var item in items) writer.WriteCell(item.Project, true); writer.CloseRow(); // populate data for (var row = 0; row < items.Count; row++) { writer.CreateRow() .WriteCell(items[row].Project, true); for (var col = 0; col < items.Count; col++) { if (col == row) writer.WriteCell(string.Empty); else if (col < row) writer.WriteCell(grid[col, row].ToString()); else writer.WriteCell(grid[row, col].ToString()); // Report count++; progress = count * 100 / totalCount; ReportProgress(progress); } writer.CloseRow(); } }