// todo クラス化 private IGraphModel MakeTrendChartModel(IProject project, ISprintToGraphModel sprintToGraphModel) { var sx = project.Sprints; // todo グラフデータに変換 // xは日付 // yはValue var gx = (from s in sx let g = sprintToGraphModel.Make(s) select g).ToArray(); // マージする var merged = new GraphModel { Pv = gx.Select(x => x.Pv).Foldl(Enumerable.Empty<IGraphPoint>(), (a, x) => sprintToGraphModel.Merge(a, x)).ToArray(), Ev = gx.Select(x => x.Ev).Foldl(Enumerable.Empty<IGraphPoint>(), (a, x) => sprintToGraphModel.Merge(a, x)).ToArray(), Ac = gx.Select(x => x.Ac).Foldl(Enumerable.Empty<IGraphPoint>(), (a, x) => sprintToGraphModel.Merge(a, x)).ToArray(), }; // 抜けてる日付をorする var allDays = merged.Pv.Concat(merged.Ev).Concat(merged.Ac).Select(x => x.Day).Distinct(); var filledBlank = new GraphModel { Pv = sprintToGraphModel.ToFillBlank(merged.Pv, allDays).ToArray(), Ev = sprintToGraphModel.ToFillBlank(merged.Ev, allDays).ToArray(), Ac = sprintToGraphModel.ToFillBlank(merged.Ac, allDays).ToArray(), }; // 値を積み上げる var stacked = new GraphModel { Pv = sprintToGraphModel.ToStacked(filledBlank.Pv).ToArray(), Ev = sprintToGraphModel.ToStacked(filledBlank.Ev).ToArray(), Ac = sprintToGraphModel.ToStacked(filledBlank.Ac).ToArray(), }; return stacked; }
public ProjectModule(IEventAggregator eventAgg, ITaskToTextFactory taskToText, ISprintToGraphModel sprintToGraphModel) : base("/project/") { this.eventAgg = eventAgg; this.sprintToGraphModel = sprintToGraphModel; this.RequiresAuthentication(); Get["/{id}"] = prms => { var id = prms.id; var project = eventAgg.GetEvent <GetProjectEvent>().Get(x => x.Id == id).FirstOrDefault(); var withRecord = ToWithRecordsProject(project); var user = eventAgg.GetEvent <GetUserEvent>().Get(u => u.Id == Context.CurrentUser.UserName).FirstOrDefault(); return(View["Views/Project", new { Auth = user, Project = withRecord }]); }; Get["/create"] = prms => { return(View["Views/CreateProject"]); }; Get["/{id}/board"] = prms => { var a = "/project/" + prms.id as string; return (Response.AsRedirect(a)); }; Get["/{id}/edit"] = prms => { var id = prms.id; var project = eventAgg.GetEvent <GetProjectEvent>().Get(x => x.Id == id).FirstOrDefault(); var sprintText = taskToText.Make(project.Sprints); var user = eventAgg.GetEvent <GetUserEvent>().Get(u => u.Id == Context.CurrentUser.UserName).FirstOrDefault(); return(View["Views/ProjectEdit" , new { Auth = user , Project = project , SprintText = sprintText }]); }; Post["/{id}/save"] = prms => { var id = prms.id; var project = eventAgg.GetEvent <GetProjectEvent>().Get(x => x.Id == id).FirstOrDefault(); // todo 競合や削除の警告 var json = this.Request.Body.ToStreamString(); var jObj = JObject.Parse(json); var sprints = taskToText.Make(jObj["edittext"].Value <string>()); project.Sprints = sprints; eventAgg.GetEvent <UpdateProjectEvent>().Publish(project); //var user = // eventAgg.GetEvent<GetUserEvent>().Get(u => u.Id == Context.CurrentUser.UserName).FirstOrDefault(); return (Response.AsJson(json, HttpStatusCode.OK)); }; Get["/{id}/report"] = prms => { var id = prms.id; var project = eventAgg.GetEvent <GetProjectEvent>().Get(x => x.Id == id).FirstOrDefault(); var trendChartModel = MakeTrendChartModel(ToWithRecordsProject(project)); var piChartModel = MakePiChartModel(trendChartModel); var totalValue = project.Sprints.SelectMany(x => x.Tasks).Where(x => x.Value.HasValue).Sum(x => x.Value.Value); var progressValue = project.Sprints.SelectMany(x => x.Tasks).OfType <ITaskWithRecord>() .SelectMany(x => x.Records) .Sum(x => x.Value); var toDayPv = trendChartModel.Pv.Reverse().Where(x => x.Day <= DateTime.Now).Select(x => x.Value).FirstOrDefault(); var workDays = project.Sprints.Select(sprintToGraphModel.Make) .Aggregate(new GraphModel(), (a, b) => new GraphModel { Pv = sprintToGraphModel.Merge(a.Pv, b.Pv), Ev = sprintToGraphModel.Merge(a.Ev, b.Ev), Ac = sprintToGraphModel.Merge(a.Ac, b.Ac), }).Pv.Where(x => x.Value != 0).Count(); return(View["Views/ProjectReport" , new { Project = project, Days = string.Join(",", trendChartModel.Pv.Select(x => string.Format("'{0}'", x.Day.ToString("yyyy/MM/dd"))).ToArray()), Trend = new { Pv = string.Join(",", trendChartModel.Pv.Select(x => x.Value.ToString()).ToArray()), Ev = string.Join(",", trendChartModel.Ev.Select(x => x.Value.ToString()).ToArray()), Ac = string.Join(",", trendChartModel.Ac.Select(x => x.Value.ToString()).ToArray()), }, PI = new { Spi = string.Join(",", piChartModel.Item1.Select(x => x.Value.ToString()).ToArray()), Cpi = string.Join(",", piChartModel.Item2.Select(x => x.Value.ToString()).ToArray()), }, Spi = piChartModel.Item1.Reverse().FirstOrDefault(x => x.Day <= DateTime.Now), Cpi = piChartModel.Item2.Reverse().FirstOrDefault(x => x.Day <= DateTime.Now), Progress = progressValue - toDayPv, Remaining = totalValue - progressValue, Average = (totalValue - progressValue) / workDays, }]); }; }
public SprintReportViewModel(IEventAggregator eventAgg , ISprintToGraphModel debug) // todo これはWeb側でやるべき { this.eventAgg = eventAgg; this.debug = debug; }