public async Task <GraphGetRp> GetGraphExperience(int productId, DatePeriodValue period) { GraphGetRp result = new GraphGetRp(); var product = await this._dbContext.FullLoadProductWithSourceItems(productId, period.Start, period.End); result.Name = product.Name; result.Id = product.Id.Value; result.Avatar = product.Avatar; foreach (var journey in product.Journeys) { var measure = journey.Measure(); var snode = new GraphNode { Id = string.Format("journey_{0}", journey.Id), Avatar = journey.Avatar, Name = string.Format("{0} [ {1} | {2} ]", journey.Name, Math.Round(journey.ExperienceSlo, 2), Math.Round(measure.Experience, 2)), Value = measure.Experience, Group = "journeys", Slo = journey.ExperienceSlo, Budget = measure.ExperienceErrorBudget }; result.Nodes.Add(snode); foreach (var map in journey.FeatureMap) { var featureMeasure = map.Feature.Measure(); var Id = string.Format("feature_{0}", map.Feature.Id); var fnode = result.Nodes.SingleOrDefault(c => c.Id == Id); if (fnode == null) { fnode = new GraphNode { Id = Id, Avatar = map.Feature.Avatar, Name = map.Feature.Name, Value = featureMeasure.Experience, Group = "features" }; result.Nodes.Add(fnode); } var fedge = new GraphEdge() { From = snode.Id, To = fnode.Id, Value = QualityUtils.MeasureBudget(fnode.Value, journey.ExperienceSlo), Tags = new Dictionary <string, object>() { { "Latency", fnode.Value } } }; result.Edges.Add(fedge); } } return(result); }