Visulaization on web interface in ArangoDb not working as expected - arangodb

I am testing ArangoDb for using the graph features provided by the framework.
I am trying to create a very simple graph like below, similar to the Java driver example provided here, https://github.com/arangodb/arangodb-java-driver/
List<EdgeDefinitionEntity> edgeDefinitions = new ArrayList<EdgeDefinitionEntity>();
EdgeDefinitionEntity edgeDefinition = new EdgeDefinitionEntity();
edgeDefinition.setCollection("myEdgeCollection");
List<String> from = new ArrayList<String>();
from.add("myCollection1");
edgeDefinition.setFrom(from);
List<String> to = new ArrayList<String>();
to.add("myCollection2");
edgeDefinition.setTo(to);
edgeDefinitions.add(edgeDefinition);
GraphEntity graph = arangoDriver.createGraph("myGraph",
edgeDefinitions, null, true);
User myObject1 = new User("Homer", 38);
User myObject2 = new User("Bart", 36);
User myObject3 = new User("Marge", 39);
User myObject4 = new User("Lisa", 40);
DocumentEntity<User> vertexFrom1 = arangoDriver.graphCreateVertex(
"myGraph", "myCollection1", myObject1, true);
DocumentEntity<User> vertexFrom2 = arangoDriver.graphCreateVertex(
"myGraph", "myCollection1", myObject2, true);
DocumentEntity<User> vertexTo1 = arangoDriver.graphCreateVertex(
"myGraph", "myCollection2", myObject3, true);
DocumentEntity<User> vertexTo2 = arangoDriver.graphCreateVertex(
"myGraph", "myCollection2", myObject4, true);
EdgeEntity<?> edge1 = arangoDriver.graphCreateEdge("myGraph",
"myEdgeCollection", null, vertexFrom1.getDocumentHandle(),
vertexTo1.getDocumentHandle(), null, null);
EdgeEntity<?> edge2 = arangoDriver.graphCreateEdge("myGraph",
"myEdgeCollection", null, vertexFrom2.getDocumentHandle(),
vertexTo2.getDocumentHandle(), null, null);
The edge collection seems to have a right mapping,
{"_from":"myCollection1/1544266710","_to":"myCollection2/1544987606"}
{"_from":"myCollection1/1544528854","_to":"myCollection2/1545249750"}
I am trying to visualise this graph in the web interface. Graph visualization is showing some weird behaviour which I do not understand. In the above setup, I expect four nodes in the graph with edges between "Homer" -- "Marge" and "Bart" -- "Lisa" but I see only two nodes and one edge, i.e. Homer -- Marge.
Visulaization view itself sometimes shows that there are no nodes and on revisit to the same page nodes appear.

The graph viewer starts with a random vertex. That means it probably uses a totally different start vertex whenever it's opened.
This is because a graph in the general case can contain many vertices and displaying all of them together is not an option because it may take a long time to render or even crash the browser. Which vertex to put into the center of the display at start is also not really easy to determine because this would require the graph viewer to know which vertex is more important than others or most important to the users. As it doesn't know that, there is the random start vertex selection.
You can select a different start/center vertex by clicking on the filter icon in the top right of the graph viewer. This will bring up a search input field that you can use to select a start vertex by any attribute (e.g. name == Homer if your vertices contain a name attribute).
If such vertex exists, it will be put into the center of the screen, along with all its directly connected vertices. Note that only relationships/edges from the start vertex to its directly connected vertices will be shown. Indirect connections will not be shown in the graph viewer by default. Clicking on any of the vertices displayed will expand (or contract) them and may bring up further relationships.
Again all of this is done because it may not be possible to display the entire graph at start (imagine a graph with a few million nodes). But as your question indicates, the current solution may not be intuitive.

Related

Unexpected behaviour of geometry in Earth Engine

I am analysing solar farms and have defined two areas of geometry. In the example below, for a site called 'Stateline', I have drawn the boundary of the site and saved the geometry as a variable 'Stateline_boundary'. I have drawn around the solar panels within the boundary, which exist in two distinct groups and saved the geometry as a variable 'Stateline_panels'.
Stateline_panels has two co-ordinate lists (as there are two areas of panels).
When I try to subtract the area covered by the panels from the area within the boundary only the first of the two lists in the 'Stateline_panels' geometry is used (see code below and attached image).
var mask = Stateline_boundary
var mask_no_panels = mask.difference(Stateline_panels);
Map.addLayer(mask_no_panels,{},'Stateline_mask_no_panels',false);
I don't understand the behaviour of the geometry. Specifically why when adding the 'Stateline_panels' geometry to the map it displays in its entirety, but when used as a mask breaks the geometry and only uses the first of two lists of coordinates.
I was going to write a longer question asking why the geometry variables seem to behave differently when they are imported into the script rather than listed within the script (which I don't think should make a difference, but it does). However I think this is an earlier manifestation of whatever is going on.
The methodology that I found worked in the end was to create geometry assets individually with the polygon tool in the Earth Engine IDE - ensuring that each is on a different layer (using the line tool, then converting to polygons never worked).
Not only was this more flexible, it was also easier to manage on Earth Engine as editing geometries is not easy. I read about the importance of winding clockwise - though never determined if that was part of the issue here. If I always drew polygons clockwise the issue never occured.
I ended up with my aoi covered in polygons like this (each colour a different named layer/geometry object):
Once this was done, manipulating each geometry object in the code editor was relatively straightforward. They can be converted to FeatureCollections and merged (or subtracted) using simple code - see below for my final code.
It was also then easy to share them between scripts by importing the generated code.
I hope that helps someone - first attempt at answering a question (even if its my own). :)
// Convert panel geometries to Feature Collections and merge to create one object.
var spw = ee.FeatureCollection(stateline_panels_west);
var spe = ee.FeatureCollection(stateline_panels_east);
var stateline_panels = spw.merge(spe);
// Convert 'features to mask' geometries to Feature Collections.
var gc = ee.FeatureCollection(golf_course);
var sp = ee.FeatureCollection(salt_pan);
var sc = ee.FeatureCollection(solar_concentrator);
var h1 = ee.FeatureCollection(hill_1);
var h2 = ee.FeatureCollection(hill_2);
var h3 = ee.FeatureCollection(hill_3);
var mf = ee.FeatureCollection(misc_features);
// Merge geometries to create mask
var features_to_mask = gc.merge(sp).merge(sc).merge(h1).merge(h2).merge(h3).merge(mf);
// Convert 'Features_to_mask' to geometry (needed to create mask)
var features_to_mask = features_to_mask.geometry();
// Change name
var mask = features_to_mask
///// If site has other solar panels nearby need to add these separately & buffer by 1km
var extra_mask = ee.Feature(solar_concentrator);
var extra_mask = extra_mask.buffer(1000);
var extra_mask = extra_mask.geometry();
///// Join mask & extra mask into single feature using .union()
// Geometry objects
var mask = mask.union(extra_mask);

Fabric.js - Programmatically transforming group objects relative to a central image object

Using Fabric.js, I have an image object that acts like a background where other group objects (consisting of rectangle and text) can be placed over it.
I would like to be able to programmatically rotate the image (90 degrees clockwise or counter-clockwise) when user clicks the corresponding button, and then rotate all other group objects relative to the image.
I was able to get this to work with the Fabric.js group feature, but the performance progressively degraded over a few rotations even with just one group object.
Looking for alternatives, I changed to use the approach described in the tranformation example here: http://fabricjs.com/using-transformations. However, the group object is not placed in the expected position after rotation.
Would anyone have any pointers on what the problem might be?
Here's the relevant code that handles just one group object for simplicity:
private rotateObjects(rotationAngle: number): void
{
let groups = this.Canvas.getObjects().filter(x => x !== this.ActiveImage);
let imageTransform = this.ActiveImage.calcTransformMatrix();
let invertedImageTransform = fabric.util.invertTransform(imageTransform);
let annotationRelationship = fabric.util.multiplyTransformMatrices(invertedImageTransform, (groups[0]).calcTransformMatrix());
this.ActiveImage.rotate(rotationAngle);
let newTransform = fabric.util.multiplyTransformMatrices(this.ActiveImage.calcTransformMatrix(), annotationRelationship);
let options = fabric.util.qrDecompose(newTransform);
groups[0].set({
flipX: false,
flipY: false,
});
groups[0].setPositionByOrigin(new fabric.Point(options.translateX, options.translateY),
"center",
"center"
);
groups[0].set(options);
groups[0].setCoords();
this.Canvas.renderAll();
}
Here are screenshots of before and after rotation. Notice that the yellow group rectangle is not placed exactly over the words "Manny Bello".
Before rotation: https://imgur.com/RcS4ekZ
After rotation: https://imgur.com/nk8gStf

Create Dimensions from edge of wall, to sides of openings, to other edge of wall

I've been struggling with this issue off and on for the better part of a year.
As the title says, i wish to dimension from one side of a wall, to both sides of openings (door openings), then terminate at the other end of the wall (vertically and horizontally). I also wish to dimension to all families hosted in the wall, but i have been able to accomplish this using ScottWilson's voodo magic helper class. Found Here: http://thebuildingcoder.typepad.com/blog/2016/04/stable-reference-string-magic-voodoo.html
foreach (ElementId ele in selSet) {
FamilyInstance fi = doc.GetElement(ele) as FamilyInstance;
Reference reference = ScottWilsonVoodooMagic.GetSpecialFamilyReference(fi,ScottWilsonVoodooMagic.SpecialReferenceType.CenterLR,doc);
refs.Append(reference);
pts[i] = ( fi.Location as LocationPoint ).Point;
i++;
}
XYZ offset = new XYZ(0,0,4);
Line line = Line.CreateBound( pts[0]+offset, pts[selSet.Count - 1]+offset );
using( Transaction t = new Transaction( doc ) )
{
t.Start( "dimension embeds" );
Dimension dim = doc.Create.NewDimension(doc.ActiveView, line, refs );
t.Commit();
}
The problem lies in determining the appropriate stable references to the wall faces. I am able to find all faces on a wall, but this gives me 100+ faces to sort through.
If anyone can help me it would be greatly appreciated!
Side note: The closest of gotten is using a casting a ray trace through my panel, then using a reference intersector method to determine references. But i'm really struggling with implementation: http://thebuildingcoder.typepad.com/blog/2015/12/retrieving-wall-openings-and-sorting-points.html
These two posts should provide more than enough to solve all your issues:
Dimension walls by iterating their faces
Dimension walls by shooting a ray
Basically, you need to obtain references to the faces or edges that you wish to attach the dimensioning to. These references can be obtained in several ways. Two common and easy approaches are:
Retrieve the element geometry using the option ComputeReferences set to true and extract the specific face required.
Shoot a ray through the model to determine the required element and its face using the 2017
ReferenceIntersector Class.

Hololens Placing Objects With Spatial Understanding

I have been running SpatialUnderstandingExample scene from holo-toolkit. Couldnt figure out how to place my objects into the scene. I want to replace those small boxes that comes default with my own objects. How can I do that?
Thanks
edit: found the draw box but how do i push my object there?
edit2: finally pushed an object at the position but still code is very complicated its messing up with the size and shape of my object. Will try to make it clean and neat.
It's been a while since I've looked at that example so hopefully I remember its method name's correctly. It contains a "DrawBox" method that is called after a successful call to get a location from spatial understanding. The call that creates the box looks something like this:
DrawBox(toPlace, Color.red);
Replace this call with the following (assuming "toPlace" contains the results from the spatial understanding call and "model" contains the model you are trying to place there):
var rotation = Quaternion.LookRotation(toPlace.Normal, Vector3.up);
// Stay center in the square but move down to the ground
var position = toPlace.Postion - new Vector3(0, RequestedSize.y * .5f, 0);
// instantiate the hologram from a model
GameObject newObject = Instantiate(model, position, rotation) as GameObject;
if (newObject != null)
{
// Set the parent of the new object the GameObject it was placed on
newObject.transform.parent = gameObject.transform;
}

Styling NSOutlineView Rows

I have a Document based Core Data app with an NSTreeController supplying the content to a view based NSOutlineView. I am "styling" (setting text colour, background colour etc.) the rows based on persistent "transformable" NSColor and NSFont attributes in my data model which the end use can modify. When a new row is popped up, it displays things with the colours/fonts set in the data model. Here is the delegate/datasource code that sets the row background colour:
- (void) outlineView:(NSOutlineView *)outlineView
didAddRowView:(NSTableRowView *)rowView
forRow:(NSInteger)row
{
// Get the relevant nodeType which contains the attributes
QVItem *aNode = [[outlineView itemAtRow:row] representedObject];
if (aNode.backColor)
{
rowView.backgroundColor = aNode.backColor;
}
}
However when the style attributes change I want the associated visible rows to be redrawn with the new style values. Each time a "style" attribute is changed, I am using NSNotificationCenter to send a notification to the Outline view delegate, with the model object whose row needs to be redrawn with the changed style. This is the code in the delegate that receives the notification.
-(void) styleHasChanged: (NSNotification *)aNotification
{
NSTreeNode *aTreeNode = [myTreeController treeNodeForModelObject:aNotification.object];
[myOutlineView reloadItem:aTreeNode];
}
My assumption here is that I can navigate the tree controller to find the tree node which is representing my model object and then ask the outline view to redraw the row for that tree node. This is the "additions" code in the tree controller which walks the tree to find the object - not super efficient, but I don't think there is another way.
#implementation NSTreeController (QVAdditions)
- (NSTreeNode *)treeNodeForModelObject:(id)aModelObject
{
return [self treeNodeForModelObject:aModelObject inNodes:[[self arrangedObjects] childNodes]];
}
- (NSTreeNode *)treeNodeForModelObject:(id)aModelObject inNodes:(NSArray*)nodes
{
for(NSTreeNode* node in nodes)
{
if([node representedObject] == aModelObject)
return node;
if([[node childNodes] count])
{
NSTreeNode * treeNode = [self treeNodeForModelObject:aModelObject inNodes:[node childNodes]];
return treeNode;
}
}
return nil;
}
So sometimes this works and the row redraws, and sometimes it doesn't. The delegate method "styleHasChanged:" is always called, and the tree controller always returns a corresponding tree node (Actually of a subclass of NSTreeNode). But more often than not the outline view does not recognise the tree node, and the row is not redrawn. Its like the tree controller has given back a different tree node object to the one it gave the outline view in the past. But weirdly sometimes it does work and the right row is redrawn with the new background colour. If I collapse the row out of view and pop it open again, it is redrawn correctly.
Anyone any idea why it works sometimes and not other times?
It would be nice to be able to bind the colour/font attributes to the row and columns in some way, so that the outline view did this styling automatically with KVO, but I don't think that is possible - is it?
You spend hours/days trying to work out what you've done wrong; You write the question out; Post it; Sleep on it; and think how stupid can you be.
So I asked the NSTableRowView to redraw itself, but I had not set the new background colour. So here is the new improved (and works) version of styleHasChanged:
-(void) styleHasChanged: (NSNotification *)aNotification
{
QVItem *modelItem = aNotification.object;
NSTreeNode *aTreeNode = [myTreeController treeNodeForModelObject:modelItem];
NSInteger rowIndex = [myOutlineView rowForItem:aTreeNode];
if !(rowIndex == -1)
{
NSTableRowView *rowViewToBeUpdated = [myOutlineView rowViewAtRow:rowIndex makeIfNecessary:YES];
rowViewToBeUpdated.backgroundColor = modelItem.backColor;
}
}
Duh!

Resources