Here i'm working on Decision tree using d3 tree example: Search collapse tree. In this example, user can search the node and the path from root to selected node will be highlighted. But in my case, when user enters, the nodes that connects to the output node, the path from the root node to the output node should be highlighted. Just like shown in the image:
I need to work the tree just like shown in the image but my logic seems not working. Please check out my FIDDLE. To get the outputh path, i added a method named as "searchPath" that works on click function of "Find output path" button. (In fiddle, the click function is not working, dont know why. In normal html page it works):
function searchPath(){
var searchText = $("#newpath").val();
//alert(searchText)
var textspl = searchText.split(",");
var path="";
for(var i=0;i<textspl.length;i++){
var paths= searchTree(treejson2,textspl[i],[]);
fullpath.push(paths[Object.keys(paths).length-1]);
}
console.log("finally : ");
console.log(fullpath);
d3.selectAll("circle").filter(function(d) {
console.log("circle name "+d.name);
});
//return fullpath;
}
To select the circle and link element based on the path, i added "id" attributes to those element. For circle, i give id as d.name and for link i give id as d.source.name+":"+d.target.name", so as to easily identify the source node and target node of a particular link.
But now i'm stuck with the code, i'm not getting any idea or logic to go forward.
Related
I'm currently learning Godot and my textbook seems to be a bit out of date as it still uses the deprecated AnimationTreePlayer. So I've had to figure out AnimationTree on my own. The exercise for this lesson talks about changing the XFade for the transition node to a random value when the player presses the "up" key but I cannot for the life of me figure out how to do it. I see in the documentation that AnimationNodeTransition has a set_cross_fade_time(value) method but how do I get to it? How do I even access the tranisition node in the script? I've tried things like $AnimationTree/Transition and $AnimationTree["parameters/Transition"] but nothing I've tried works.
My script is currently on the root node and the node tree looks like this:
Sprite [script is here]
AnimationPlayer
AnimationTree
Let us say you have your AnimationTree with the AnimationPlayer set on the anim_player property. And the tree_root of the AnimationTree is an AnimationNodeBlendTree, where - among other nodes - you have an AnimationNodeTransition.
As you are aware, we can get some "paramters" of the AnimationTree, they should appear in the Inspector Panel. And there you should find this one:
$AnimationTree.get("parameters/Transition/current")
Where "Transition" is the name of the node in the AnimationNodeBlendTree. But there isn't a parameter for the xfade_time.
Instead we will get the root of the AnimationTree (in other words, the AnimationNodeBlendTree) like this:
var blend_tree := $AnimationTree.tree_root as AnimationNodeBlendTree
Then we can get the nodes like this:
var blend_tree := $AnimationTree.tree_root as AnimationNodeBlendTree
var node := blend_tree.get("nodes/NodeName/node")
By the way, if you change "/node" to "/position" you get a Vector2 with the position of the node on the editor.
So, let us say we want a node called "Transition", which is our AnimationNodeTransition. We do this:
var blend_tree := $AnimationTree.tree_root as AnimationNodeBlendTree
var transition := blend_tree.get("nodes/Transition/node") as AnimationNodeTransition
And finally we can access xfade_time. Set a random value you said? This should do:
var blend_tree := $AnimationTree.tree_root as AnimationNodeBlendTree
var transition := blend_tree.get("nodes/Transition/node") as AnimationNodeTransition
transition.xfade_time = rand_range(0.0, 120.0)
Or as a one line:
$AnimationTree.tree_root.get("nodes/Transition/node").xfade_time = rand_range(0.0, 120.0)
Be aware that the value of xfade_time is the number of seconds for the transition. So setting 120 give you a two minutes transition.
Was able to get a click event working on a pie/bar chart working per this question, which returned the key/value of the path selected. I am simply wondering if there is a way to get at all the selected path/rect of a given chart within say a click like this?
I have basically tried:
d3.selectAll('g').forEach(function(d) {
for (var prop in d) {
if (d[prop].classList !=== undefined && d[prop].classList.contains('selected')) {
var ( elem in d[prop].children ) {
// I can see the path element there but have been unable to get at it
console.log(d[prop].children[elem]);
}
}
}
});
what I am trying to do is get at the path in order to get the d.data.key for all selected chart paths on the page.
You should probably look at the data rather than trying to reverse-engineer it from the svg elements.
It sounds like chart.filters() will give you what you want.
http://dc-js.github.io/dc.js/docs/html/dc.baseMixin.html#filters__anchor
i am missing something basic about d3 selection. using the basic d3 force layout example, i want to select a particular node, say Myriel and make it fixed. following previous hints like this and this, it seems myrielNode = d3.select(["name=Myriel"]) should do it but does not? i've also tried filter() based strategies, ... what am i doing wrong, please?
var myrielDomNode = d3.select('[name="Myriel"]');
var myrielDatum = myrielDomNode.datum();
myrielDatum.fixed = true;
This of course assumes a DOM node exists that has an attribute name="Myriel" and is bound to data such that datum() is an object controlled by the force layout.
Update
Turns out that name was not an attribute of the DOM node, but rather an attribute of the data. In this case, finding the Myriel node becomes a find operation (via filter) on the data array:
myrielNode = nodes.filter(function(d) { return d.name == 'Myriel'; })[0]
You probably want
d3.select('[name="Myriell"]');
I have the following code:
var cnt = 0;
$(document).ready(function () {
var data = [
{
"id": cnt++,
"text":"node_" + cnt
}
];
var tree = $("#treeview").kendoTreeView({
dataSource:kendo.observableHierarchy(data)
}).data("kendoTreeView");
$("#push").click(function () {
var pos = tree.dataItem(tree.select());
pos.items.push({id:cnt++, text:"node_" + cnt});
});
$("#append").click(function () {
var pos = tree.select();
tree.append({id:cnt++, text:"node_" + cnt}, pos);
});
$("#show").click(function () {
var data = tree.dataItem(".k-item:first");
$("#content").html(JSON.stringify(data, null, 2));
});
});
And there are two functions:
1. push: once selected a node in the tree, it uses dataItem to get current data item and pushes one additional node into it (child node). This should be valid since dataSource is an ObservableHierarchy object.
2. append: once selected a node in the tree, it uses append to introduce one additional node into it (child node). This was valid on previous release of KendoUI and modify the tree but should not reflect changes in the DataSource.
The question / problem is:
1. If I use append the tree is update (visually) but the dataItem is not updated.
2. If I use push then dataItem is update but not the tree.
3. If I select a node, use append and then push, the tree is visually updated and the model too.
It seems that the first time that I introduce a child append updates some internal structure and from there the tree 'observes' the observable hierarchy put if I directly push it then the tree does not observe the observable hierarchy.
How should I insert nodes dynamically being able to check the DataSource and get the current state of the tree?
NOTE This is with the latest version of KendoUI Q2.1024.
Ok so,I just got an answer on a ticket about this matter after 2 days.
It is indeed a BUG which is already fixed in the latest builds,but the builds are only available for customers with an active subscription...
It will be available for the rest of the community in the next official release (around March 2013).So currently the only solution is to purchase a commercial subscription and you will get immediate access to the new builds...
Kinda disappointed with all this commercial stuff since it is a bug..But anyway,nothing we can do about it..
At least we know we are not crazy,and in a few months we can replace our code with the fixed build. :P
Kinda my problem too at the moment since append doesn't update the dataSource at all and while push updates the dataSource,it does so only the first time I add a node,I can't even select that node afterwards until I save the dataSource and refresh the page.(or I get an pos.items is undifined error)
What I've though so far is that maybe we can use the push method that adds the child-node to the dataSource and try to force load the selected node's children in the dataSource everytime through treeview.dataSource.get(treeview.select()).load()
According to documentation here http://docs.kendoui.com/documentation/api/framework/node
If we can get the selected Node we can load it's children forcibly.But I haven't been able to have datasource.get() or dataSource.view()[] read the selected node so far..
PS I know this is not a complete answer but maybe it helps..
How can I get information about the states of styles present on the toolbar, at the current cursor position.
The documentation is completely silent on this issue. As far as I can tell from digging into the source code, CKEditor doesn't keep an internal log of what the styles are at the current position. It simply recalculates them on an as-needed basis, namely whenever it needs to add new styles to a selection.
Please keep in mind that CKEditor is actually building and modifying an entire DOM tree, and so the styles it applies cascade down the nodes. It appears that the only way you can pull the style information is to traverse up the DOM tree from your current cursor position, recording the style information from each ancestor until you reach the body node of the editor.
The following code should get you started traversing up the ancestor nodes:
//Or however you get your current editor
var editor = CKEDITOR.currentInstance;
//This will pull the minimum ancestor that encompasses the entire selection,
//so if you just want to use the cursor it will give you the direct parent
//node that the cursor is inside
var node = editor.getSelection().getCommonAncestor();
//This is all the ancestors, up to the document root
var ancestors = node.getParents();
//This is the editors body node; you don't want to go past this
var editor_body = editor.getBody();
var body_ancestors = editor_body.getParents();
//The ancestors list descends from the root node, whereas we want
//to ascend towards the root
for (var i = ancestors.length - 1; i >= 0; i--;) {
//Pull the node
var a = ancestors[i];
//You've hit the body node, break out of the loop
if (a.getText() == editor_body.getText()) break;
//This is a node between the cursor's node and the editor body,
//pull your styling information from the node here
}
Thanks to the customizability of CKEditors style interface, there isn't a single set of styles that can be checked for, nor do they follow the same form (for instance, some will be CSS styles, while others will be span elements with a particular class).
My suggestion is to check for just those styles which you actually care about, and ignore the rest. It'll make the code much simpler.
Here is another way (based on a few attached links).
You can get the current element position by editor.getSelection().getStartElement() - (editor is CKEDITOR.instances.%the editor instance%.
Now, you can then wrap the actual element for jquery (or use the jquery adapter..):
$(editor.getSelection().getStartElement().$)
This will give you an access to use the following plugin which resolves all the styles of a given element (both inline and inherited):
/*
* getStyleObject Plugin for jQuery JavaScript Library
* From: http://upshots.org/?p=112
*
* Copyright: Unknown, see source link
* Plugin version by Dakota Schneider (http://hackthetruth.org)
*/
(function($){
$.fn.getStyleObject = function(){
var dom = this.get(0);
var style;
var returns = {};
if(window.getComputedStyle){
var camelize = function(a,b){
return b.toUpperCase();
}
style = window.getComputedStyle(dom, null);
for(var i=0;i<style.length;i++){
var prop = style[i];
var camel = prop.replace(/\-([a-z])/g, camelize);
var val = style.getPropertyValue(prop);
returns[camel] = val;
}
return returns;
}
if(dom.currentStyle){
style = dom.currentStyle;
for(var prop in style){
returns[prop] = style[prop];
}
return returns;
}
return this.css();
}
})(jQuery);
(Taken from: jQuery CSS plugin that returns computed style of element to pseudo clone that element?)
All that is left to do is:
$(editor.getSelection().getStartElement().$).getStyleObject()
Now you can check for any style asigned to the element.
Another small tip will be - what are the styles for the current cursor position, every time the position or styles are changed:
In which case you can use attachStyleStateChange callback (which is pretty atrophied by itself since is can only return boolean indication for weather or not a certain style is applied to current position).
The good thing about it is - callback is being recieved when ever the style state is changed - that is - whenever the cursor position is moved to a position with different style attributes - Any different attribute and not just the attribute the listener was ment to verify (Taken from the API http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#attachStyleStateChange)
Combining everything together to figure out what is the current applied styles on the current cursor position Every time something is changed:
editor.on('instanceReady', function () {
//editor.setReadOnly(true);
var styleBold = new CKEDITOR.style(CKEDITOR.config.coreStyles_bold);
editor.attachStyleStateChange(styleBold, function (state) {
var currentCursorStyles = $(editor.getSelection().getStartElement().$).getStyleObject();
// For instance, the font-family is:
var fontFamily = currentCursorStyles.fontFamily;
});
});