コード例 #1
0
ファイル: TfsQueryService.cs プロジェクト: thnk2wn/TfsStates
        public async Task <TfsQueryResult> Query(TfsKnownConnection knownConn, TfsStatesViewModel model)
        {
            var sw            = Stopwatch.StartNew();
            var vssConnection = knownConn.ToVssConnection();

            this.workItemClient = vssConnection.GetClient <WorkItemTrackingHttpClient>();
            var wiql           = TfsQueryBuilder.BuildQuery(model);
            var tfsQueryResult = await this.workItemClient.QueryByWiqlAsync(new Wiql { Query = wiql });

            var workItems = tfsQueryResult.WorkItems.ToList();

            this.totalCount = workItems.Count();

            var queue        = new ConcurrentQueue <TfsInfo>();
            var asyncOptions = GetAsyncOptions();

            var getRevsBlock = new ActionBlock <WorkItemReference>(
                async workItemRef =>
            {
                var tfsInfo = await ProcessWorkItemRevisions(workItemRef);

                if (tfsInfo.TransitionCount > model.MinTransitions)
                {
                    queue.Enqueue(tfsInfo);
                }
            },
                asyncOptions);

            foreach (var wiRef in workItems)
            {
                getRevsBlock.Post(wiRef);
            }

            getRevsBlock.Complete();
            await getRevsBlock.Completion;

            var list = queue
                       .OrderBy(i => i.Iteration)
                       .ThenBy(i => i.Id)
                       .ToList();

            sw.Stop();

            var result = new TfsQueryResult
            {
                TfsItems       = list,
                TotalWorkItems = this.processedCount,
                TotalRevisions = this.revisionsCount
            };

            return(result);
        }
コード例 #2
0
ファイル: ChartService.cs プロジェクト: thnk2wn/TfsStates
        public Chart CreateBarChart(TfsQueryResult queryResult)
        {
            Chart chart = new Chart
            {
                Type = "bar"
            };

            Data data = new Data
            {
                Labels = new List <string>()
            };

            var counts = queryResult
                         .TfsItems
                         .GroupBy(t => t.TransitionCount)
                         .OrderBy(t => t.Key)
                         .Select(c => c.Key)
                         .ToList();

            var rawData = new List <double>();

            foreach (var count in counts)
            {
                data.Labels.Add($"{"cycle".ToQuantity(count)}");
                var itemCount = queryResult.TfsItems.Count(t => t.TransitionCount == count);
                rawData.Add(itemCount);
            }

            BarDataset dataset = new BarDataset()
            {
                Label           = "# work items with cycle",
                Data            = rawData,
                BackgroundColor = new List <string>()
                {
                    "rgba(255, 99, 132, 0.2)",
                    "rgba(54, 162, 235, 0.2)",
                    "rgba(255, 206, 86, 0.2)",
                    "rgba(75, 192, 192, 0.2)",
                    "rgba(153, 102, 255, 0.2)",
                    "rgba(255, 159, 64, 0.2)"
                },
                BorderColor = new List <string>()
                {
                    "rgba(255,99,132,1)",
                    "rgba(54, 162, 235, 1)",
                    "rgba(255, 206, 86, 1)",
                    "rgba(75, 192, 192, 1)",
                    "rgba(153, 102, 255, 1)",
                    "rgba(255, 159, 64, 1)"
                },
                BorderWidth = new List <int>()
                {
                    1
                },
            };

            data.Datasets = new List <Dataset>
            {
                dataset
            };

            chart.Data = data;

            BarOptions options = new BarOptions()
            {
                Scales        = new Scales(),
                BarPercentage = 0.7,
                Title         = new Title
                {
                    Display = true,
                    Text    = "Frequency of Cycles (transitions)"
                },
            };

            Scales scales = new Scales()
            {
                YAxes = new List <Scale>()
                {
                    new CartesianScale()
                    {
                        Ticks = new CartesianLinearTick()
                        {
                            BeginAtZero = true
                        }
                    }
                }
            };

            options.Scales = scales;
            chart.Options  = options;

            chart.Options.Layout = new Layout()
            {
                Padding = new Padding()
                {
                    PaddingObject = new PaddingObject()
                    {
                        Left  = 10,
                        Right = 12
                    }
                }
            };

            return(chart);
        }
コード例 #3
0
ファイル: HomeController.cs プロジェクト: thnk2wn/TfsStates
        public async Task <IActionResult> RunReport(TfsStatesViewModel viewModel)
        {
            if (viewModel.ConnectionId == Guid.Empty)
            {
                ModelState.AddModelError(nameof(viewModel.ConnectionId), "Connection is required");
            }

            if (string.IsNullOrEmpty(viewModel.Project) || viewModel.Project == NoProjectSelected)
            {
                ModelState.AddModelError(nameof(viewModel.Project), "Project is required");
            }

            if (string.IsNullOrEmpty(viewModel.Iteration) || viewModel.Iteration == NoIterationSelected)
            {
                ModelState.AddModelError(
                    nameof(viewModel.Iteration),
                    "Iteration Under is required (you can select a parent iteration container)");
            }

            await LoadLookups(viewModel);

            if (!ModelState.IsValid)
            {
                return(View(ViewName, viewModel));
            }

            var sw = Stopwatch.StartNew();
            await FileUtility.Cleanup();

            TfsQueryResult queryResult = null;

            var knownConn = await this.settingsService.GetConnection(viewModel.ConnectionId);

            try
            {
                SendProgress($"Querying project {viewModel.Project}, iteration under {viewModel.Iteration}...");
                queryResult = await this.tfsQueryService.Query(knownConn, viewModel);
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex);
                var settingsUrl = Url.Action("Index", "Settings");
                viewModel.RunReadyState.NotReady(
                    $"Error querying TFS. Verify <a href='{settingsUrl}'>TFS settings</a> " +
                    $"and your connectivity and try again.");
                return(View(ViewName, viewModel));
            }

            if (queryResult.TfsItems.Count > 0)
            {
                var fName    = $"TfsStates_{DateTime.Now.Ticks}.xlsx";
                var filename = await FileUtility.GetFilename(fName);

                SendProgress($"Writing {filename}...");

                var projectUrl = $"{knownConn.Url}/{viewModel.Project}";
                this.excelWriterService.Write(filename, queryResult.TfsItems, projectUrl);

                SendProgress($"Launching {filename}...");
                System.Threading.Thread.Sleep(1000);

                viewModel.ResultFilename = fName;

                await Electron.Shell.OpenExternalAsync(filename);
            }

            // eat file in use exception
            try
            {
                await this.reportHistoryService.Record(knownConn.Id, viewModel.Project, viewModel.Iteration);
            }
            catch (IOException ioEx) { }

            if (queryResult.TfsItems.Count > 0)
            {
                var chart = chartService.CreateBarChart(queryResult);
                ViewData["chart"] = chart;
            }

            sw.Stop();
            var items            = queryResult.TfsItems;
            var totalTransitions = items.Sum(x => x.TransitionCount);
            var avgTransitions   = items.Count > 0
                ? Math.Round(items.Average(x => x.TransitionCount), 0)
                : 0;

            viewModel.FinalProgress = new ReportProgress
            {
                WorkItemsProcessed = queryResult.TotalWorkItems,
                Message            = $"Processed {"work item".ToQuantity(queryResult.TotalWorkItems, "###,##0")} and " +
                                     $"{"revision".ToQuantity(queryResult.TotalRevisions, "###,##0")} in {sw.Elapsed.Humanize()}. " +
                                     $"{"transition".ToQuantity(totalTransitions, "###,##0")}. " +
                                     $"Average work item transitions: {avgTransitions}"
            };

            return(View(ViewName, viewModel));
        }