public static HashSet <object> AsSet(this object value) { var str = value.ToString(); if (str.StartsWith("[") && str.EndsWith("]")) { return(JsonConvention.DeserializeObject <HashSet <object> >(str)); } return(new HashSet <object>() { value }); }
/// <summary> /// Assumes layout has been already applied /// Note: method mutates graph and graphLayout /// </summary> public void ImproveAppliedLayout(SigmaGraphModel graph, GraphLayout graphLayout, LayoutSettings layoutSettings, TimeSpan duration) { using (var engine = new V8ScriptEngine()) { try { var v8Graph = new V8GraphModel(); v8Graph.LoadSigma(graph); engine.AddHostObject("log", _log); engine.Execute("var graph = " + JsonConvention.SerializeObject(v8Graph) + ";"); engine.Execute("var settings = " + JsonConvention.SerializeObject(layoutSettings) + ";"); engine.Execute("var duration = " + JsonConvention.SerializeObject(duration.TotalMilliseconds) + ";"); var baseDirectory = AppDomain.CurrentDomain.BaseDirectory; var forceAtlas2 = engine.Compile(File.ReadAllText($@"{baseDirectory}\App\Graph\Layout\ForceAtlas2.js")); var serviceScript = engine.Compile(File.ReadAllText($@"{baseDirectory}\App\Graph\Layout\GraphLayoutService.js")); engine.Execute(forceAtlas2); engine.Execute(serviceScript); var nodesJson = engine.Evaluate("JSON.stringify(nodes)").ToString(); var nodes = JsonConvention.DeserializeObject <V8NodeModel[]>(nodesJson); for (int i = 0; i < nodes.Length; i++) { var node = graph.Nodes[i]; node.X = nodes[i].x; node.Y = nodes[i].y; var id = node.Entity; if (id.HasValue) { graphLayout[id.Value] = new GraphLayout.Coords() { X = nodes[i].x, Y = nodes[i].y }; } } } catch (ScriptEngineException e) { _log.Error("V8 exception: " + e.ErrorDetails); throw; } } }
internal static void AssertGraphsEqual(string expected, string actual) { AssertGraphsEqual(JsonConvention.DeserializeObject <PropertyGraphModel>(expected), JsonConvention.DeserializeObject <PropertyGraphModel>(actual)); }
public Dictionary <Tuple <Guid, Guid, string>, ConcurrentEdgeModel> GenerateConcurrentEdgeModel(GraphSchemaModel schema, InternalGraphEdgesResult edges) { // var uriNameDictionary = schema.EdgeSchema.ToDictionary(e => e.Uri, e => e.Name); // source, target, edgeName, propName => timestamp var propTimestamps = new Dictionary <Tuple <Guid, Guid, string, string>, DateTime>(); // edges var edgesResult = new Dictionary <Tuple <Guid, Guid, string>, ConcurrentEdgeModel>(); foreach (var relationshipSchema in schema.EdgeSchema) { // możliwe jest wiele relacji do różnych węzłów (a każda może mieć wiele propsów) Dictionary <Tuple <Guid, Guid>, InternalGraphEdgesResult.InternalEdgeModel> edgeBucket; if (!edges.Edges.TryGetValue(relationshipSchema.Uri, out edgeBucket)) { continue; } foreach (var edge in edgeBucket) { var edgeKey = new Tuple <Guid, Guid, string>(edge.Key.Item1, edge.Key.Item2, uriNameDictionary[relationshipSchema.Uri]); // find model ConcurrentEdgeModel edgeModel; if (!edgesResult.TryGetValue(edgeKey, out edgeModel)) { edgeModel = new ConcurrentEdgeModel() { Id = edge.Value.Id, SourceVertexId = edge.Value.SourceId, TargetVertexId = edge.Value.TargetId, Name = relationshipSchema.Name, Props = new ConcurrentDictionary <string, object>(StringComparer.OrdinalIgnoreCase) }; edgesResult.Add(edgeKey, edgeModel); } if (relationshipSchema.PropsSchema != null) { foreach (var propSchema in relationshipSchema.PropsSchema) { if (!edge.Value.PropsJson.ContainsKey(propSchema.Uri)) { continue; } if (edgeModel.Props.ContainsKey(propSchema.Name)) { continue; } var prop = edge.Value.PropsJson[propSchema.Uri]; if (!edgeModel.Props.ContainsKey(propSchema.Name)) { var value = JsonConvention.DeserializeObject(prop.JsonValue); edgeModel.Props.TryAdd(propSchema.Name, value); } else { // check timestamp for update (newer props override older) var timestampKey = new Tuple <Guid, Guid, string, string>(edgeModel.SourceVertexId, edgeModel.TargetVertexId, edgeModel.Name, propSchema.Name); var timestamp = propTimestamps[timestampKey]; if (timestamp < prop.TimeStamp) { var value = JsonConvention.DeserializeObject(prop.JsonValue); edgeModel.Props.TryAdd(propSchema.Name, value); } } } } } } return(edgesResult); }
public Dictionary <Guid, ConcurrentVertexModel> GenerateConcurrentVertexModel(GraphSchemaModel schema, InternalGraphVerticesResult vertices) { var vertexIdPropNameTimeStamp = new Dictionary <Tuple <Guid, String>, DateTime>(new TupeGuidStringComparer()); var verticesResult = new Dictionary <Guid, ConcurrentVertexModel>(); var processedPropUris = new HashSet <string>(); foreach (var sectionSchema in schema.VertexSchema) { if (sectionSchema.PropsSchema != null) { foreach (var propSchema in sectionSchema.PropsSchema) { List <InternalGraphVerticesResult.InternalVertexPropModel> propsBucket; if (!vertices.WithProps.TryGetValue(propSchema.Uri, out propsBucket)) { continue; } processedPropUris.Add(propSchema.Uri); foreach (var prop in propsBucket) { ConcurrentVertexModel vertex; if (!verticesResult.TryGetValue(prop.VertexId, out vertex)) { vertex = new ConcurrentVertexModel() { Id = prop.VertexId, Props = new ConcurrentDictionary <string, object>(StringComparer.OrdinalIgnoreCase) }; verticesResult.Add(prop.VertexId, vertex); } if (!vertex.Props.ContainsKey(propSchema.Name)) { var value = JsonConvention.DeserializeObject(prop.JsonValue); vertex.Props.TryAdd(propSchema.Name, value); vertexIdPropNameTimeStamp.Add(new Tuple <Guid, string>(vertex.Id, propSchema.Name), prop.TimeStamp); } else { // should we override the value? DateTime lastTimeStamp = vertexIdPropNameTimeStamp[new Tuple <Guid, string>(vertex.Id, propSchema.Name)]; if (lastTimeStamp < prop.TimeStamp) { var value = JsonConvention.DeserializeObject(prop.JsonValue); vertex.Props[propSchema.Name] = value; } } } } } } // handle props outside schema var outsideSchema = vertices.WithProps.Where(v => !processedPropUris.Contains(v.Key)); foreach (var propsBucket in outsideSchema) { var name = propsBucket.Key.Split('/').Last(); foreach (var prop in propsBucket.Value) { ConcurrentVertexModel vertex; if (!verticesResult.TryGetValue(prop.VertexId, out vertex)) { vertex = new ConcurrentVertexModel() { Id = prop.VertexId, Props = new ConcurrentDictionary <string, object>(StringComparer.OrdinalIgnoreCase) }; verticesResult.Add(prop.VertexId, vertex); } if (!vertex.Props.ContainsKey(name)) { var value = JsonConvention.DeserializeObject(prop.JsonValue); vertex.Props.TryAdd(name, value); vertexIdPropNameTimeStamp.Add(new Tuple <Guid, string>(vertex.Id, name), prop.TimeStamp); } else { // should we override the value? DateTime lastTimeStamp = vertexIdPropNameTimeStamp[new Tuple <Guid, string>(vertex.Id, name)]; if (lastTimeStamp < prop.TimeStamp) { var value = JsonConvention.DeserializeObject(prop.JsonValue); vertex.Props[name] = value; } } } } // vertices witour props foreach (var withoutProp in vertices.WithoutProps) { verticesResult.Add(withoutProp, new ConcurrentVertexModel() { Id = withoutProp, Props = new ConcurrentDictionary <string, object>(StringComparer.OrdinalIgnoreCase) }); } return(verticesResult); }