I want to move nodes in Sigma JS on click event. Say from position x 0.7 to position x -0.7.
Is it possible to move nodes in Sigma js, and if it is, kindly guide me to achieve that.
Yes, it is possible. I created a jsfiddle showing how to change node position, size, and color on mouse click here:
http://jsfiddle.net/kaliatech/P255K/
You can bind to custom "downnodes" events like this:
sigInst.bind('downnodes',onNodeDown);
The event callback contains an array of selected node ids. I don't know when it would be more than one when clicking. Perhaps when zoomed out in a complex graph.
One of the more subtle issues when using sigmajs, is that most methods, such as getNodes, return clones, not the instances themselves. This is to protect "private" data in the graph I think, especially data that can not be redrawn after initialization. To actually modify properties, you need to use the iterator methods. Even then, you are only given clones. The library updates the actual node instances using a list of predefined allowable properties. (See the checkNode function in graph.js).
After properties have been set, you then need to refresh/redraw the graph. While the "refresh" method would seem to be an obvious candidate, it did not work. I was able to get it to redraw using the draw method though. You will need to review the source code to understand the different parameters. Example:
function onNodeDown(evt) {
var sigmajs = evt.target;
var nodeId = evt.content[0];
sigmajs.iterNodes(function(n){
n.size = 10;
n.color = "#0000FF";
},[nodeId]);
sigmajs.draw(2, 2, 2, true);
};
For more advanced needs, the sigmajs website includes plugin examples showing other ways of getting mouse events and updating nodes dynamically. One is the advanced plugin example for a fisheye effect:
http://sigmajs.org/examples/a_plugin_example_advanced.html
Another is the example for accessing node attributes:
http://sigmajs.org/examples/more_node_info.html
The sigmajs documentation is weak, so you will need to review the source code to understand things.
There are plugins permitting to move isolated nodes from the graph.
Check
https://github.com/Linkurious/linkurious.js/blob/develop/examples/lasso.html
Related
I want to disable the hover effect on certain data points of a dataset under certain conditions using Chart.js.
I basically need to modify the dataset before drawing the line graph so it looks in the way i want. (e.g extending the line along x axis) And i don't want the hover effect to take place on some of those data points.
After implementing the business logic, I've looked for a scriptable option
so i can use the context regarding the data point the user is on. I've came across solutions for basically cancelling all the hover effects on a single graph but not conditionally just like I've mentioned.
I've tried to use onHover with the context and set the hoverRadius conditionally and it looks as i expected but it gives me an error saying "Cannot assign to read only property 'hoverRadius' of object".
// in the options object
onHover: function (event, context) {
if (!isEmpty(context)) {
context[0]._options.hoverRadius = 0;
}
}
Most probably, the regarding object has been made immutable intentionally.
So what's the correct way of implementing this behavior in Chart.js?
Question:
I've been using the AutoDesk View and Data API, and I've been curious to know if it was possible to return geometric information about a selected element. Ideally, I want the position, size, angle, type of shape, etc., of a selected element so that I could compare, for instance, two lines. I don't mind how this information is represented, so long as two shapes could be compared.
Objective:
If there was a line, such that (psuedo-representation):
(x1=0,y1=0),(x2=10,y2=0), a 2d straight line of length 10;
and another line, such that:
(x1=20,y1=20),(x2=30,y2=20), another 2d straight line of length 10.
Then I would be able to say that these two lines are similar from this information and deduce their angle. There would obviously need to be some indication of the type of entity that is selected also. That's the desired outcome of my question.
What I've tried:
So far, I've found several useful functions within Viewer3d.js, but none seem to return any data about the geometric position of a single selected shape:
Viewing.Extension.SomeExtension = function (viewer, options)
{
...
var shapeRenderData = viewer.impl.getRenderProxy(viewer, dbId);
var shapeFragmentData = viewer.impl.getFragmentProxy(viewer, dbId);
}
I already understand how to include the onSelect event, and that is left out for clarity of the question.
Both of these return a JSON object with properties of fragId, scale, quaternion and position - although with exception of fragId, these properties have null values.
Extra:
I am basing the extension I've created off of this GitHub tutorial from the AutoDesk team:
https://github.com/Developer-Autodesk/tutorial-getting.started-view.and.data/blob/master/chapter-3.md#Step5
Please note the fifth step includes code for the onSelect event I'm discussing, should you wish to recreate the question to help me solve this.
I've wrote that blog post about geometry snapping and selection commands. I think it should provide some elements of answer to your question:
Geometry snapping and selection commands with View & Data API
I am testing Cesiumjs to see if it can reflect a near-real-time expreience - for example: position of airplanes.
For that, I need to draw billboards and make them move - which I know is possible with cesium, just not sure how.
The code looks like this:
var billboards = scene.primitives.add(new Cesium.BillboardCollection());
var billboard = {
image : '/path/to/logo.png',
position : Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)
};
billboards.add(billboard);
My question is how do I change the position of the billboard. I couldn't find ant documentation that would explain.
I thought doing:
billboard.position = ... //new position
but how will cesium know that I've changed the position attribute unless it somehow turns that reference into a observable object.
So how do I update the location?
Thanks.
Cesium does indeed listen for changes to billboard.position
(source code here), so it is correct behavior for apps to simply write a new position.
Note that you must write the whole position at once, meaning you may not write to billboard.position.x. Instead, keep a "scratch" Cartesian3 around (don't create a new one every animation frame at 60fps), write to the x,y,z properties of your scratch variable, and then assign your scratch variable to billboard.position. You can see in the source that the assigned value will be cloned into another pre-existing Cartesian3, so you may immediately reuse the scratch variable.
Here's an example:
// Just once at app startup. Don't call "new" at 60fps.
var scratchCartesian3 = new Cesium.Cartesian3();
var ellipsoid = viewer.scene.mapProjection.ellipsoid;
function onTick() {
// This is safe to call at 60fps.
billboard.position = Cesium.Cartesian3.fromDegrees(
lon, lat, alt, ellipsoid, scratchCartesian3);
}
Also note that your question and the above answer are focused on the "Graphics Primitive" layer of the Cesium API. Cesium has one higher layer, called the "Entity" API, that you can use if you want Cesium to handle the concept of user-selectable objects with pop-up descriptions etc. Here's a Sandcastle demo showing how to add a billboard as a property of an entity, instead of as a primitive. This allows you to add other properties to the same entity, for example a name, description, label, 3D model, etc, and have them all be controlled from the same position property, and have Cesium take care of popup descriptions. The position property is more complex for entities than for primitives, for example it can be constant or sampled. This allows entities to change position over time when the timeline is shown.
This question is related with one I asked before here. I'm currently using KineticJS 4.0.5 and I'm using multiple layers to display some shapes with different properties. Since I need to change the layers contents frequently I'm using removeChildren to remove a layer content, but it seems that removeChildren also removes the events associated to childrens. I would like to remove the layer childrens without removing their events because I may have to add them to the layer again.
I tried to set the layer.childrens attribute equal to an empty Array instead of using the removeChildren function. At first it seemed to work but on some cases, some weird things happen :/ Some shapes disappear and the only way to get them back is by setting their Z index. I think the main problem with this approach is related with some properties that must be reseted when contents are removed from the layer, but I don't know which are they.
I also tried to set the events again on each shape before drawing them but it doesn't work... They remain static on the screen... I event tried to use the setDraggable(true) on all shapes before drawing them but no luck... Do I need to create the objects again and apply the events to them again each time I want to redraw a layer with shapes I used before? Or would it be a good approach to store layers for each screen on my application? (I can have a lot of different screens, which would result in a lot of layers and only one would be displayed at a time...)
If you know a solution for this problem please tell me. I really need to solve this problem because it is very important for my project to be able to draw and redraw :/
Thank you!
Sounds to me that what you need is a way to visually remove objects from layers, but not actually delete them. Instead of using remove, try creating a new layer specifically for storage, where your main group within that layer is hidden. You'll want this group, and its layer, to be globals for easy access. Then, when you need to remove an object from view, use moveTo to move it into storage, and moveTo again to restore it to view.
var gObj = {storage : '', storageGroup : ''};
gObj.storage = new Kinetic.Layer();
gObj.storageGroup = new Kinetic.Group({name:'storage', x:0, y:0});
gObj.storage.add(gObj.storageGroup);
// assumes stage is already built
stage.add(gObj.storage);
gObj.storageGroup.hide();
function wareHouse(obj, group, store) {
// obj is an object to store when store === true, otherwise it's a name or id when retreiving, group is the group where object either is or needs to be, store is a boolean value
if (store) {
obj.moveTo(gObj.storageGroup);
} else {
// change the dot to pound ('.' = '#') if using id's
var box = gObj.storageGroup.get('.' + obj)[0];
box.moveTo(group);
}
var parent = group.getLayer();
parent.draw();
}
On a web page, I want to show a list of albums and next to each album name i want to show a stacked list of pictures on top of each other. What is the best way to dynamically take a list of pictures and have them stacked on top of each other
Here is an example:
Why not just build one? it wouldn't be hard. Here is a small rotate prototype i've worked up (took maybe 5 minutes to write)
Element.prototype.rotate = function(d) {
var s = "rotate(" + d + "deg)";
if (this.style) { // regular DOM Object
this.style.MozTransform = s;
this.style.WebkitTransform = s;
this.style.OTransform = s;
this.style.transform = s;
}
this.setAttribute("rotation", d);
};
then you can use to it rotate a list of images.. see (not very good :P) example here
Better Example
Best Example
Looks like the OP wants more
How is this for close-to-the-example? i think a few angles may be off...
Or click here
To rotate the images you either need the new CSS3 features or a canvas element, new to HTML5.
Writing some JS functions to aid you in the rotating process it's a matter of minutes.
I would say the best library is the one you write.
Anyway, if I had to choose one I would choose Raphael.
Libraries will just help you out with manipulating the dom and responding to events. The answer lies in the way you see the problem, how you will represent the data, how you will handle the dynamic data that comes to you.
Images are html elements, so they can be manipulated with CSS3 like Jose Faeti said. Now for the dynamic part I would suggest you take a look at backbone.js (http://documentcloud.github.com/backbone/).
In a few words, backbone.js will help you defined albums and pictures as standalone entities, hook views to those data models - views that will automatically adapt when new data comes via ajax from the server - and to top it all of, it uses jQuery for dom selection, so:
1) You get a nice OOP-ish approach to defining your images data
2) You get a nice Model-View View-Model relationship that updates itself easily
3) You get jQuery as a dom selection and manipulation tool