I was trying to get which vertex of a Feature has been modified. It seems that featuremodified event does not supply this information.
this is important because I will have to post the modification to the server. I dont want to post the whole feature object because of one single vertex change.
I am using OpenLayers v2.13.1
You need to hook into the vertexmodified callback of OpenLayers.Layer.Vector. This is triggered by the dragVertex function of OpenLayers.Control.ModifyFeature, see line 479 here http://trac.osgeo.org/openlayers/browser/trunk/openlayers/lib/OpenLayers/Control/ModifyFeature.js
The vertexmodified function receives a vertex, a feature and a pixel, so you would write something like this, assuming an OpenLayers.Layer.Vector called vector:
vector.events.register('vertexmodified', this, function(vertex, feature, pixel){
//do something with the vertex
});
Related
I’m trying to create a new dataset type Powerapps Component (PCF). For the moment I am using it to display a view of the records that are available in an entity in Microsoft Dynamics CRM.
I wish to make the view sort itself when I click on the grid column headers (in a similar way that the default CRM grid view does). I'm trying to figure out how to apply a sort to the dataset so that I can refresh it as indicated by the documentation for the dataset.refresh() function:
Refreshes the dataset based on filters, sorting, linking, new column.
New data will be pushed to control in another 'updateView' cycle.
The dataset object does have a “sorting” property, but changing its value and then refreshing the dataset doesn’t seem to have any effect. After the refresh, the sorting property reverts to the value it had before I changed it.
In short, the click handler for the grid header does something like the following bit of code. The refresh gets done and my updateView() function gets called as expected but the sorting was not applied.
dataset.sorting = [{name: 'createdon', sortDirection: 1}];
dataset.refresh();
Any help on getting the dataset sorting to work would be appreciated.
I've been experimenting with PowerApps Component Framework a little bit recently and I can confirm that the following code won't be working:
dataSet.sorting = [ { name: "columnName", sortDirection: 0 } ];
However, I managed to get this one working for me:
dataSet.sorting.pop(); // you may want to clean up the whole collection
dataSet.sorting.push({ name: "columnName", sortDirection: 0 });
I haven't really figured out the reason of this behavior. The sorting array may be implemented as some form of observable collection in the background.
I hope this will guide you to a functioning solution.
The documentation is pretty abysmal here, but here is my best guess from putting a few different pieces of information together.
TLDR: I think there is some kind of extra method that needs to be called on the .sorting property, but I can't find out what it is called. Maybe something like:
dataset.sorting.setSorting({name: 'createdon', sortDirection: 1});
I think you're going to have to try a bunch of likely method names and see what works.
Background and links:
The only reference I could find to dataset.sorting was from here:
In this preview for canvas apps, only a limited set of filtering and sortStatus methods are supported. Filter and sort can be applied to dataset on primary type columns except for the GUID. Filter and sorting can be applied in the same way as in model-driven apps.To retrieve the dataset with filtering and sorting information, call
the methods in context.parameters.[dataset_property_name].filtering
and context.parameters.[dataset_property_name].sorting, then invoke
the context.parameters.[dataset_property_name].refresh().
So it seems that the .filtering and .sorting properties are handled similarly, and that there are some methods attached to them, and only some are supported. That is about as vague as they could make it...
I did find an example of how .filtering is used:
_context.parameters.sampleDataset.filtering.setFilter({
conditions: conditionArray,
filterOperator: 1, // Or
});
There is a brief reference to .setFilter() in the docs, as well as FilterExpression
There is a SortStatus reference, but it doesn't have any corresponding methods explicitly called out. It is possible that this is not yet a supported feature in the public preview, or the documentation is lacking and the name and syntax of the method you need to call on .sorting is not yet documented.
I am trying to update nodes and links but would like to not use d3's enter pattern. The reason is that I want the svelte framework to do this instead as well as handle all the rendering, I just want to use d3-force for calculations.
I get the initial render to work just fine, but adding links and nodes has the following issues:
adding links makes the network grow
the links don't seem to have any effect on the graph layout, i.e. they don't seem to be added to the force.simulation
first adding nodes seems to work, but when adding nodes after adding a link they don't seem to excert forces on the other nodes.
Here's my functions for adding nodes and links:
function addNode(){
force.forceSimulation(data.nodes.push({"id": "116", "group": 5, "index":data.nodes.length, "x":0, "y":0, "vx":0, "vy":0}))
data=data
graph.alpha(1.0).update()
graph.restart()
}
function addLink(){
let n=getRandomInt(0, data.nodes.length-1)
let tn=getRandomInt(0, n)
let sn=getRandomInt(n, data.nodes.length-1)
graph.force("link", force.forceLink(data.links.push({'source':data.nodes[sn], 'target':data.nodes[tn],'index':data.links.length, 'value':getRandomInt(1, 7)})))
data=data
graph.alpha(1.0).update()
graph.restart()
}
I found this answer but they use merge and tie it to DOM elements. I don't understand how I can do this without relating to the DOM, just updating the array of nodes and links in javascript to have d3-force include it in the simulation.
Here I have the current simulation in a svelte REPL, you can fork and edit it.
Luckily disassociating a d3-force layout from the DOM is fairly easy: the force layout itself has no interaction with the DOM, it simply is a physics calculation based on some data's properties. Adding and removing data points (nodes/links) can be a bit tricky though, but is the same regardless of whether D3 renders the DOM, something else does, or you don't render the force at all.
Here's where you add links and nodes:
function addNode(){
force.forceSimulation(data.nodes.push({"id": "116", "group": 5, "index":data.nodes.length, "x":0, "y":0, "vx":0, "vy":0}))
data=data
graph.alpha(1.0).update()
graph.restart()
}
function addLink(){
let n=getRandomInt(0, data.nodes.length-1)
let tn=getRandomInt(0, n)
let sn=getRandomInt(n, data.nodes.length-1)
graph.force("link", force.forceLink(data.links.push({'source':data.nodes[sn], 'target':data.nodes[tn],'index':data.links.length, 'value':getRandomInt(1, 7)})))
data=data
graph.alpha(1.0).update()
graph.restart()
}
There are a few issues here:
Array.push() does not return an array. It modifies an array in place, returning the length of the array after pushing an item. This means you aren't actually adding nodes to the force layout. This will cause issues as the force layout requires objects rather than primitives to represent nodes. Instead just push the node/link, then pass the node/link array to .nodes() or .links()
force.forceSimulation() will create a new force layout generator, this is not what you want. You want to add nodes to the existing nodes, so we can use graph.nodes() instead.
There is no force.update(), this causes an error and is why you are unable to restart the simulation once it is done cooling down. We can just drop this part.
Let's see what these two functions look like correcting for this:
function addNode(){
data.nodes.push({"id": "116", "group": 5, "index":data.nodes.length, "x":0, "y":0, "vx":0, "vy":0})
graph.nodes(data.nodes)
data=data
graph.alpha(1.0).restart()
}
function addLink(){
let n=getRandomInt(0, data.nodes.length-1)
let tn=getRandomInt(0, n)
let sn=getRandomInt(n, data.nodes.length-1)
data.links.push({'source':data.nodes[sn], 'target':data.nodes[tn],'index':data.links.length, 'value':getRandomInt(1, 7)})
graph.force("link", force.forceLink(data.links))
data=data
graph.alpha(1.0).restart()
}
I'm not sure why you have data=data, I see no difference without it, I'll quietly assume it's a quirk of the framework
A small alternative for updating links:
You can access the force you've named 'link' and assign it new links with:
graph.force("link").links(data.links)
Rather than:
graph.force("link", force.forceLink(data.links))
The latter recreates a force, where as the first simply modifies it.
I am creating my first project that uses ui-router.
My project has about 10 views, each with their own controller and state. I am trying to modularise/encapsulate/decouple as best as possible but I am having trouble working out where to put the onExit and onEnter state callbacks.
The first option is to put it in app.js which is currently defining all of my states, however I feel that this would not be a good place as it could cause this file to blow up and become hard to read as more states are introduced and the logic gets more complex.
The second option I looked into was to put it into a controller (I have one for each state), however from researching it doesn't seem to be best practice to do this.
The third option is to create a service that is resolved, however with this option I would end up with either a giant service full of state change functions for each of the states (not decoupled) or an additional service per state which would contain the state change functionality, and I worry that would increase project complexity.
What is the standard way to achieve this?
Are there any other options that I am missing?
Our strategy for this has been to disregard the onEnter and onExit on the state object, because as you are discovering, they feel like they are in the wrong place in terms of separation of concerns (app.js).
For onEnter: we handle setup in an activate() function in each controller, which we manually execute inside the controller. This happens to also match the callback that will get executed in Angular 2.0, which was not an accident ;).
function activate() {
// your setup code here
}
// execute it. this line can be removed in Angular 2.0
activate();
For onExit: We rarely need an exit callback, but when we do, we listen for the $scope $destroy event.
$scope.$on("$destroy", function() {
if (timer) {
$timeout.cancel(timer);
}
});
I wonder how could I get the correct palm rotation angle (along Y-axis) from Leap Motion (I'm using the latest LeapJS API)?
I have tried both rotationAngle(sinceFrame) method and the frame._rotation. However, the rotationAngle() returns a very small value close to 0, which seems to be the rotation angle calculated based on the current frame (how to define the sinceFrame in Leap.loop(function(frame)){}, as it seems only records data from current frame).
And the frame._rotation returns a 3*3 matrix (which I've no idea about what is it, as it's not included in the API documentation). Therefore, I wonder if there's any way to get the correct rotation angle of Y-axis from these methods?
The latest version of the leap.js library includes a roll() function as a member of the Hand object. (It also has pitch() and yaw(), if roll() isn't all you want.) The roll() function is defined as:
Hand.prototype.roll = function() {
return Math.atan2(this.palmNormal[0], -this.palmNormal[1]);
}
As an aside, since you don't need to use rotationAngle() to get the current palm angles, the rotationAngle() function gives you the rotation that has occurred between two frames. For sinceFrame, you can either store a reference to the starting frame or get a past frame from the history buffer maintained by the Controller object. Although the Leap.loop() function doesn't give you access to its Controller object directly, you should be able to create your own. Note that frame._rotation is an internal variable that is used in the calculation of the transformations between two frames. It isn't much use on its own.
I have some data being loaded from a server, but there's no guarantee that I'll have it all when the UI starts to display it to the user. Every frame there's a tick function. When new data is received a flag is set so I know that it's time to load it into my data structure. Which of the following ways is a more sane way to decide when to actually run the function?
AddNewStuffToList()
{
// Clear the list and reload it with new data
}
Foo_Tick()
{
if (updated)
AddNewStuffToList();
// Rest of tick function
}
Versus:
AddNewStuffToList()
{
if (updated)
{
// Clear the list and reload it with new data
}
}
Foo_Tick()
{
AddNewStuffToList();
// Rest of tick function
}
I've omitted a lot of the irrelevant details for the sake of the example.
IMHO first one. This version separates:
when to update data (Foo_Tick)
FROM
how to loading data (AddNewStuffToList()).
2nd option just mixing all things together.
You should probably not run the function until it is updated. That way, the function can be used for more purposes.
Let's say you have 2 calls that both are going to come and put in data to the list. With the first set up, checking the variable inside of the function, you could only check if one call has came in. Instead, if you check it in the function that calls the data, you can have as many input sources as you want, without having to change the beginning function.
Functions should be really precise on what they are doing, and should avoid needing information created by another function unless it is passed in.
In the first version the simple variable check "updated" will be checked each time and only if true would AddNewStuffToList be called.
With the second version you will call AddNewStuffToList followed by a check to "updated" every time.
In this particular instance, given that function calls are generally expensive compared to a variable check I personally prefer the first version.
However, there are situations when a check inside the function would be better.
e.g.
doSomething(Pointer *p){
p->doSomethingElse();
}
FooTick(){
Pointer *p = new Pointer();
// do stuff ...
// lets do something
if (p){
doSomething(p);
}
}
This is clumbsy because every time you call doSomething you should really check you're
not passing in a bad pointer. What if this is forgotten? we could get an access violation.
In this case, the following is better as you're only writing the check in one place and
there is no extra overhead added because we always want to ensure we're not passing in a bad pointer.
doSomething(Pointer *p){
if (p){
p->doSomethingElse();
}
}
So in general, it depends on the situation. There are no right and wrong answers, just pros and cons here.