Konva Find name of the Group that a shape is within - konvajs

Example demo
Within the 'dragmove' event listener, is there a way to return the name (in this example the name is group created within the createShape function) of the group that the shapes are added to at the start?
Ultimate need for this is to be able to identify the groups within a collision detection and then use the .moveTo function to combine them. I can use the .moveTo statically but it would be better to have it dynamic for future shapes being added.
I've searched the API but can't find a way to return the group name that a shape is linked with

Each Konva Node object has a name() function which returns the name of the node.
Being part of a group means being a child of a node. So the group is the parent of your node. To get a parent element you can use the getParent() function.
Therefore node.getParent().name() should do the job.
I help I understood your question correctly. If not feel free to comment.

Related

Custom function to calculate on all events in an Esper window

I am wondering what is the best or most idiomatic way to expose all events in a window to a custom function. The following example is constructed following the stock price style examples used in the Esper online documentation.
Suppose we have the following Esper query:
select avg(price), custom_function(price) from OrderEvent#unique(symbol)
The avg(price) part returns an average of the most recent price for each symbol. Suppose we want custom_function to work in a similar manner, but it needs complex logic - it would want to iterate over every value in the window each time the result is needed (eg outlier detection methods might need such an algorithm).
To be clear, I'm requiring the algorithm look something like:
custom_function(window):
for each event in window:
update calculation
and there is no clever way to update the calculation as events enter or leave the window.
A custom aggregation could achieve this by pushing and popping events to a set, but this becomes problematic when primitive types are used. It also feels wasteful, as presumably esper already has the collection of events in the window so we prefer not to duplicate that.
Esper docs mention many ways to customize things, see this Solution Pattern, for example. Also mentioned is that the 'pull API' can iterate all events in a window.
What approaches are considered best to solve this type of problem?
For access to all events at the same time use window(*) or prevwindow(*).
select MyLibrary.computeSomething(window(*)) from ...
The computeSomething is a public static method of class MyLibrary (or define a UDF).
For access to individual event-at-a-time you could use an enumeration method. The aggregate-method has an initial value and accumulator lambda. There is an extension API to extend the existing enumeration methods that you could also use.
select window(*).aggregate(..., (value, eventitem) => ...) from ...
link to window(*) doc and
link to enum method aggregate doc and
link to enum method extension api doc

In a linked list, why don't we give a name to each node?

I see people usually use a temp node to manipulate a linked list. For example, create a new node whose pointer is stored in temp, point previous block to temp, then use temp for the next node.
Why not keep a designated name to each node(keep a variable that stores its address), so that we can access that node by simply dereferencing its name. This way, we can still insert a new node by pointing the previous node to it and pointing it to the next node.
I know there is a reason why linked list is not made this way, I just can't figure out why.
The linked list data type is simply not made for having a name for each item. In many cases you simply just don't need to name everything. If you need such behavior you can extend the type for your needs.
It all comes down to: Use the data structure which fits to your actual use case.
In Java for example there is a pre-defined type which does exactly, what you have described:
LinkedHashMap<K, V>

Visual Studio REST API Iteration and Area ID's

I am working with the VSO REST API and have a question on how Iteration and Area ID's are assigned. Specifically, why is it when I assign a work item to the root Iteration or Area the ID that is returned for the WIT is not returned when I query the classification nodes?
For example, imagine I have this hierarchy when I query /DefaultCollection/my project/_apis/wit/classificationnodes?$depth=2
My Project: id=1234
Area 1: id=5678
Area 2: id= 9012
And I then query for a work item using /DefaultCollection/_apis/wit/workItems/1?$expand=all
If the work item is in Area 1 or Area 2, the System.AreaId field is as expected (5678 and 9012, respectively). However, if I assign the work item to My Project, the System.AreaID is some value that is not included when I query for all classification nodes. There appears to be some kind of relationship between the ID's as they are serial (e.g. the ID returned by the classification node query is 1232 for the area and 1233 for the iteration), but I can't seem to find a way to query to get the actual ID returned by the work item query.
In fact, not only is the ID returned for a work item not present when I query for all classification nodes, if I assign the work item to both the root iteration and area, the ID returned for both fields is the same value that is not included in the classification node query.
What I need is a way to look at a work item and figure out the area and iteration it belongs to. I could probably do something with the path field strings that are returned, but that seems error prone since users can change them.
****Edit****
The above appears to be a bug in the REST API, but for anyone who comes across this post there is a way to get a usable iteration ID by the path string. Structure your REST call like so:
/DefaultCollection/[Project Name]/_apis/wit/classificationnodes/iterations/Release 1/Sprint 1 (etc.)
I have never done this with ID. I only use the path. In the classification service you can get the node by path easily enough.
For example, using the REST API - you can access this url to get the data about a specific iteration:
/DefaultCollection/[Project Name]/_apis/wit/classificationnodes/iterations/[Release X]/[Sprint Y]
Note that trying to access the default iteration path (the project name instead of a specific iteration) will return an error:
/DefaultCollection/[Project Name]/_apis/wit/classificationnodes/iterations/[Project Name]
will give :
{"$id":"1","innerException":null,"message":"VS402485: The node name is not recognized: [Project Name]","typeName":"Microsoft.TeamFoundation.WorkItemTracking.Server.Metadata.WorkItemTrackingTreeNodeNotFoundException, Microsoft.TeamFoundation.WorkItemTracking.Server","typeKey":"WorkItemTrackingTreeNodeNotFoundException","errorCode":0,"eventId":3200}
So if you do batch work, you have to filter those before querying the api.
There are three ways of identifying an Area (everything I post equally applies to Iterations also). The Path (string), the ID (int) and a Guid. each of them are used in different ways, and have different ramifications.
For example renaming an Area, does NOT change it's identity, therefore does not update a work item (the path returned for in a workitem is dynamic).
It is also possible to delete and recreate and identical path, but it will have a different ID.
The GUID is used primarily for the Excel Reports (such as are parent of the SharePoint portal)
Depending on how you want things to react determines the appropriate element to use.
I have not seen any issues with the ID that you mention, and if you could create a simple repro, I would be glad to look at it.
david(dot)corbin(at)dynconcepts(dot)com

Find all sub-graphes containing at least one node having a certain property

My graph is composed of multiple "sub-graphes" that are disconnected from one another. These sub-graphes are composed of nodes that are connected with a given relation type.
I would like to get (for example) the list of sub-graphes that contain at least one node that has the property "name" equals "John".
It's equivalent to finding one node per subgraph having this property.
One solution would be to find all the nodes having this property and loop through this list to only pick the ones that are not connected to the previously picked ones. But that would be ugly and quite heavy. Is there an elegant way to do that with Cypher?
I'm trying with something along this direction but have no success so far:
START source=node:user('name:"John"')
MATCH source-[r?:KNOWS*]-target
WHERE r is null
RETURN source
Try this one it may help
START source=node:user('name:"John"')
MATCH source-[r:KNOWS]-()-[r2:KNOWS]-target
WHERE NOT(source-[r:KNOWS]-target)
RETURN target

Setting the Index of a Node in VirtualStringTree?

I am trying to change the index of a node, because there are some specific nodes that at all times needs to be at the bottom of my tree. I tried to change the Node.Index, but that did not change anything. So my question is: How do I change the Index of a PVirtualNode?
Thanks! - Jeff
To change the index of node A, find the node B that has the index you want A to have, and then call Tree.MoveTo(A, B, amInsertBefore, False). B and everything after it will shift down by one to make room for A, and their Index fields will be recalculated. This works even if A doesn't yet exist in the tree (such as just after calling MakeNewNode).
If you're using Index to associate each node with its corresponding data value in a list or array, then you'll find this largely ineffective for re-ordering the displayed values.
You canot change the index of a node. Normally when using VirtualStringTree you hold your data in your own data structure separate from the tree and access the data from the events.
You can also store data directly in the nodes (using a record), but I prefer the other approach because it keeps the logic out of the tree view.
For example, you could store the data in a list and access this list in the GetText handler (you can use Node.Index). Then, if you want to reorder the items, just reorder your list and everything else will happen automatically (you might have to call Invalidate on the tree).
Pseudocode:
Initializing:
Tree.RootNodeCount := MyList.Count;
In the GetTextevent:
NodeText := MyList [Node.Index];
Reordering:
Reorder (MyList);
Tree.Invalidate;
Given that you are still using the tree view control as a container, the ideal solution offered by Smasher is not available to you.
One rather obvious solution, given that your tree view has no hierarchy (i.e. it's a list) would be to use the Sort method with your own compare function (OnCompareNodes).
The other blindingly obvious strategy would be to add the node that you want at the bottom last. If you need to add other nodes later, then insert them above the special last node with InsertNode. This simple approach will probably suffice for the problem as you have described it.
TVirtualNode is a doubly-linked list, it's not a index-based structure: you change the index of a node by removing it and adding it where you want it.
Look into DeleteNode and AddChild.

Resources