public AliasColorScheme(IColorPalette sourceColorPalette, IAliasMapping aliasMapping) { _sourceColorPalette = sourceColorPalette; _aliasMapping = aliasMapping; InitAliasColorMappings(); }
public HierarchicalDataContext AnalyzeKnowledge(IBrushFactory brushFactory, IAliasMapping aliasMapping) { LoadHistory(); LoadMetrics(); LoadContributions(false); var localFileToContribution = AliasTransformContribution(_contributions, aliasMapping); var summary = _history.GetArtifactSummary(GetDisplayFilter(), aliasMapping); var fileToMainDeveloper = localFileToContribution.ToDictionary(pair => pair.Key, pair => pair.Value.GetMainDeveloper()); // Assign a color to each developer var mainDevelopers = fileToMainDeveloper.Select(pair => pair.Value.Developer).Distinct().ToList(); var legend = new LegendBitmap(mainDevelopers, brushFactory); legend.CreateLegendBitmap(Path.Combine(_outputPath, "knowledge_color.bmp")); // Build the knowledge data var builder = new KnowledgeBuilder(); var hierarchicalData = builder.Build(summary, _metrics, fileToMainDeveloper); var dataContext = new HierarchicalDataContext(hierarchicalData, brushFactory); dataContext.AreaSemantic = Strings.LinesOfCode; dataContext.WeightSemantic = Strings.NotAvailable; return(dataContext); }
internal List <string> GetMainDevelopers(IAliasMapping aliasMapping) { LoadContributions(false); var localFileToContribution = AliasTransformContribution(_contributions, aliasMapping); var mainDevelopers = localFileToContribution.Select(x => x.Value.GetMainDeveloper().Developer).Distinct(); return(mainDevelopers.ToList()); }
private static Dictionary <string, uint> AliasTransformWork(IAliasMapping aliasMapping, Dictionary <string, uint> developerToWork) { var aliasToWork = new Dictionary <string, uint>(); // Group by alias var groups = developerToWork.GroupBy(pair => aliasMapping.GetAlias(pair.Key)); foreach (var group in groups) { var sumContribution = (uint)group.Sum(g => g.Value); var alias = group.Key; aliasToWork.Add(alias, sumContribution); } return(aliasToWork); }
/// <summary> /// Analyzes the fragmentation per file. /// </summary> public HierarchicalDataContext AnalyzeFragmentation(IAliasMapping aliasMapping) { LoadContributions(false); var localFileToContribution = AliasTransformContribution(_contributions, aliasMapping); var summary = _history.GetArtifactSummary(_extendedDisplayFilter, aliasMapping); var fileToFractalValue = localFileToContribution.ToDictionary(pair => pair.Key, pair => pair.Value.CalculateFractalValue()); var builder = new FragmentationBuilder(); var hierarchicalData = builder.Build(summary, _metrics, fileToFractalValue); var dataContext = new HierarchicalDataContext(hierarchicalData); dataContext.AreaSemantic = Strings.LinesOfCode; dataContext.WeightSemantic = Strings.Fragmentation; return(dataContext); }
public List <object> ExportSummary(IAliasMapping aliasMapping) { LoadContributions(true); // silent var summary = _history.GetArtifactSummary(_extendedDisplayFilter, aliasMapping); var hotspotCalculator = new HotspotCalculator(summary, _metrics); var orderedByLocalPath = summary.OrderBy(x => x.LocalPath).ToList(); var gridData = new List <object>(); foreach (var artifact in orderedByLocalPath) { gridData.Add(CreateDataGridFriendlyArtifact(artifact, hotspotCalculator, aliasMapping)); } var now = DateTime.Now.ToIsoShort(); Csv.Write(Path.Combine(_outputPath, $"summary-{now}.csv"), gridData); return(gridData); }
public void ShowColorEditorViewViewer(IColorSchemeManager colorSchemeManager, IAliasMapping aliasMapping) { var view = new ColorEditorView(); var viewModel = new ColorEditorViewModel(colorSchemeManager, aliasMapping); view.Owner = _mainWindow; view.DataContext = viewModel; view.WindowStartupLocation = WindowStartupLocation.CenterOwner; //view.SizeToContent = SizeToContent.WidthAndHeight; //view.ResizeMode = ResizeMode.NoResize; view.ShowDialog(); }
private object CreateDataGridFriendlyArtifact(Artifact artifact, HotspotCalculator hotspotCalculator, IAliasMapping aliasMapping) { var linesOfCode = (int)hotspotCalculator.GetLinesOfCode(artifact); if (_contributions != null) { var result = new DataGridFriendlyArtifact(); var localFileToContribution = AliasTransformContribution(_contributions, aliasMapping); var key = artifact.LocalPath.ToLowerInvariant(); if (localFileToContribution.ContainsKey(key)) { var contribution = localFileToContribution[key]; var mainDev = contribution.GetMainDeveloper(); // Work related information result.FractalValue = contribution.CalculateFractalValue(); result.MainDev = mainDev.Developer; result.MainDevPercent = mainDev.Percent; } else { result.MainDev = "???"; //Warnings.Add(new WarningMessage("", $"Cannot find contribution for file {key}")); } result.LocalPath = artifact.LocalPath; result.Commits = artifact.Commits; result.Committers = artifact.Committers.Count; result.LOC = linesOfCode; result.WorkItems = artifact.WorkItems.Count; result.CodeAge_Days = (DateTime.Now - artifact.Date).Days; result.Hotspot = hotspotCalculator.GetHotspotValue(artifact); return(result); } else { var result = new DataGridFriendlyArtifactBasic(); result.LocalPath = artifact.LocalPath; result.Commits = artifact.Commits; result.Committers = artifact.Committers.Count; result.LOC = linesOfCode; result.WorkItems = artifact.WorkItems.Count; result.CodeAge_Days = (DateTime.Now - artifact.Date).Days; result.Hotspot = hotspotCalculator.GetHotspotValue(artifact); return(result); } }
/// <summary> /// Same as knowledge but uses a different color scheme /// </summary> public HierarchicalDataContext AnalyzeKnowledgeLoss(string developer, IBrushFactory brushFactory, IAliasMapping aliasMapping) { LoadHistory(); LoadMetrics(); LoadContributions(false); var localFileToContribution = AliasTransformContribution(_contributions, aliasMapping); developer = aliasMapping.GetAlias(developer); var summary = _history.GetArtifactSummary(GetDisplayFilter(), aliasMapping); var fileToMainDeveloper = localFileToContribution.ToDictionary(pair => pair.Key, pair => pair.Value.GetMainDeveloper()); // Build the knowledge data var builder = new KnowledgeBuilder(developer); var hierarchicalData = builder.Build(summary, _metrics, fileToMainDeveloper); var dataContext = new HierarchicalDataContext(hierarchicalData, brushFactory); dataContext.AreaSemantic = Strings.LinesOfCode; dataContext.WeightSemantic = Strings.NotAvailable; return(dataContext); }
public string AnalyzeWorkOnSingleFile(string fileName, IBrushFactory brushFactory, IAliasMapping aliasMapping) { var workByDeveloper = _sourceProvider.CalculateDeveloperWork(fileName); var workByAlias = AliasTransformWork(aliasMapping, workByDeveloper); var bitmap = new FractionBitmap(); var fi = new FileInfo(fileName); var path = Path.Combine(_outputPath, fi.Name) + ".bmp"; // TODO atr bitmap? bitmap.Create(path, workByAlias, brushFactory, true); return(path); }
/// <summary> /// The contributions are calculated by the source control providers. /// In order to use developer aliases we have to transform the contributions, too. /// If two developers are mapped to the same alias their contribution is shared. /// </summary> /// <returns></returns> public Dictionary <string, Contribution> AliasTransformContribution(Dictionary <string, Contribution> localFilesToContribution, IAliasMapping aliasMapping) { var localFileToAliasContribution = new Dictionary <string, Contribution>(); foreach (var fileToContribution in localFilesToContribution) { var localFile = fileToContribution.Key; var developerToWork = fileToContribution.Value.DeveloperToContribution; var aliasToWork = AliasTransformWork(aliasMapping, developerToWork); localFileToAliasContribution.Add(localFile, new Contribution(aliasToWork)); } // local file -> contribution return(localFileToAliasContribution); }
public static IColorScheme ForAlias(this IColorScheme palette, IAliasMapping aliasMapping) { return(new AliasColorScheme(palette, aliasMapping)); }
/// <summary> /// Returns a flat summary of all artifacts found in the commit history. /// </summary> public List <Artifact> GetArtifactSummary(IFilter filter, IAliasMapping aliasMapping) { // Item id -> artifact var artifacts = new Dictionary <string, Artifact>(); var set = new HashSet <string>(); // Files we already know we skip are not checked again! var ignoredIds = new HashSet <string>(); foreach (var changeset in ChangeSets) { if (changeset.WorkItems.Count >= Thresholds.MaxWorkItemsPerCommitForSummary) { // Ignore monster merges. // Note: We may lose files for the summary when the last merge with many work items contains a final rename. // Maybe write a warning or make further analysis. continue; } Debug.Assert(set.Add(changeset.Id)); // Change set appears only once foreach (var item in changeset.Items) { // The first time we see a file (id) it is the latest version of the file. // Either add it to the summary or ignore list. var id = item.Id; if (ignoredIds.Contains(id)) { // Files we already know to be skipped are not checked again! (Performance) continue; } if (filter != null && !filter.IsAccepted(item.LocalPath)) { ignoredIds.Add(id); continue; } if (!artifacts.ContainsKey(id)) { // The changeset where we see the item the first time is the latest revision! if (!Exists(item)) { // This may still happen because we skip large merges that may contain a final rename. // So we have a code metric but still believe that the file is at its former location // TODO show as warning! Trace.WriteLine($"Ignored file: '{item.LocalPath}'. It should exist. Possible cause: Ignored commit with too much work items containing a final rename."); ignoredIds.Add(id); continue; } artifacts[id] = CreateArtifact(changeset, item); } else { // Changesets seen first are expected so have newer dates. Debug.Assert(artifacts[id].Date >= changeset.Date); } var artifact = artifacts[id]; var committerAlias = aliasMapping.GetAlias(changeset.Committer); // Aggregate information from earlier commits (for example number of commits etc) // TODO ApplyTeams(teamClassifier, artifact, changeset); ApplyCommits(artifact); ApplyCommitter(artifact, committerAlias); ApplyWorkItems(artifact, changeset); } } // Remove entries that exist on hard disk but are removed form TFS! // Flatten the structure and return only the artifacts. return(artifacts.Where(pair => !pair.Value.IsDeleted).Select(pair => pair.Value).ToList()); }