Say I have the following DOM structure:
div
> svg
> defs
> g
> rect
> g
> g
<-- I want to insert an element here
> g
> g
None of the parent g's child g elements have a class, id, or anything else I can use as a selector, and I cannot modify them because they are coming from a 3rd party widget loaded into the page.
The best I can do so far is insert into the 3rd g element, but that's not acceptable. I want to add a 6th element to the parent g's children, between the current indices 2 and 3 (or indices 1 and 2 if you don't count the rect).
Here's what I have done so far:
var test = d3.selectAll('#continer svg > g > g');
test = d3.select(test[0][2]);
test.append('foreignObject').
attr('width', 690).attr('height', 500)
.append('xhtml:body').style('font', '14px "Helvetica Neue"')
.html('<h1>An HTML Foreign Object in SVG</h1>');
With that I end up with the following structure:
div
> svg
> defs
> g
> rect
> g
> g
> g
> foreignobject & its children inserted here
> g
... and I understand why. I have tried D3's insert method using a function as the second argument to specify before, but the browser keeps telling me:
An attempt was made to reference a Node in a context where it does not
exist.
Ok so this works but it's a bit of a hack. I use jQuery to rearrange elements after appending using D3. Would still like to see a pure D3 solution to this if one is possible:
// select the parent g element
var parentG = d3.select('#continer svg > g');
// append a new G element with a nested foreign object
parentG.append('g').attr('id', '__my_custom_id')
.append('foreignObject').attr('width', 690).attr('height', 500)
.append('xhtml:body').style('font', '14px "Helvetica Neue"')
.html('<h1>An HTML Foreign Object in SVG</h1>')
;
// now use jQuery to rearrange the order of the elements
$('#__my_custom_id')
.insertAfter('#container svg > g > g:nth-child(3)')
.removeAttr('id')
;
Related
I have a complex nested list (depth can be >2 also):
p:((`g;`d1`d2);(`r;enlist `e1);(`r;enlist `p1))
How to add an element to each element of the nested list but retaining the original structure; e.g. adding `h to each element of p to get the following :
((`g`h;(`d1`h;`d2`h));(`r`h;enlist `e1`h);(`r`h;enlist `p1`h))
I tried this but doesn't give what I want :
q)p,\:`h
((`g;`d1`d2;`h);(`r;enlist `e1;`h);(`r;enlist `p1;`h))
q)raze[p],\:`h
(`g`h;`d1`d2`h;`r`h;`e1`h;`r`h;`p1`h)
You can use .z.s to recursively go through the nested list and only append `h to lists of symbols:
q){$[0=type x;.z.s'[x];x,\:`h]}p
g h d1 h d2 h
`r`h ,`e1`h
`r`h ,`p1`h
For this function I have made the assumption that your nested lists will only contain symbols. It checks the type of the list, if it is not a mixed list then it appends `h to each element. If it is a mixed list then it passes each element of that list back into the function separately to check again.
Although not recursive (and so requires some knowledge about the shape of your nested list), a more conventional approach would be
q).[p;2#(::);,';`h]
g h d1 h d2 h
`r`h ,`e1`h
`r`h ,`p1`h
Though Thomas has already answered the question; In case you want to specify any other operation apart from append, you can use the following :
q)f:{`$ "_" sv string x,y}
q){[o;a;e] $[-11<>type e; .z.s [o;a] each e; o[e;a]] }[f;`h] each p
`g_h `d1_h`d2_h
`r_h ,`e1_h
`r_h ,`p1_h
or when f is assigned as append operation
q)f:{x,y}
q){[o;a;e] $[-11<>type e; .z.s [o;a] each e; o[e;a]] }[f;`h] each p
g h d1 h d2 h
`r`h ,`e1`h
`r`h ,`p1`h
I am trying to manipulate a tree in Julia. The tree is created as an object. All I want is substituting the one of the branches with another one. I can do it manually but can not do it by using a recursion function.
mutable struct ILeaf
majority::Any # +1 when prediction is correct
values::Vector # num_of_samples
indicies::Any # holds the index of training samples
end
mutable struct INode
featid::Integer
featval::Any
left::Union{ILeaf,INode}
right::Union{ILeaf,INode}
end
ILeafOrNode = Union{ILeaf,INode}
And my function for chaning the tree is (tree is original one where, by using LR_STACK, I am willing to change one of the branches and substitute it with the subtree. ) :
function traverse_and_assign(tree, subtree, lr_stack) # by using Global LR_stack
if top(lr_stack) == 0
tree = subtree
elseif top(lr_stack) == :LEFT
pop!(lr_stack)
return traverse_and_assign(tree.left, subtree, lr_stack)
else # right otherwise
pop!(lr_stack)
return traverse_and_assign(tree.right, lr_stack)
end
end
What happens is that I cannot change the original tree.
On the other hand :
tree.left.left = subtree
works perfectly fine.
What is wrong with my code ? Do I have to write a macro for this ?
B.R.
edit#1
In order to generate data :
n, m = 10^3, 5 ;
features = randn(n, m);
lables = rand(1:2, n);
edit#2
use 100 samples for training the decision tree :
base_learner = build_iterative_tree(labels, features, [1:20;])
then give other samples one by one :
i = 21
feature = features[21, :], label = labels[21]
gtree_stack, lr_stack = enter_iterate_on_tree(base_learner, feature[:], i, label[1])
get the indices of incorrect samples
ids = subtree_ids(gtree_stack)
build the subtree:
subtree = build_iterative_tree(l, f, ids)
update the original tree(base_learner):
traverse_and_assign(base_learner, subtree, lr_stack)
I still miss MWE but maybe I could help with one problem without it.
In Julia value is bind to variable. Parameters in functions are new variables. Let's do test what does it mean:
function test_assign!(tree, subtree)
tree = subtree
return tree
end
a = 4;
b = 5;
test_assign!(a, b) # return 5
show(a) # 4 ! a is not changed!
What happend? value 4 was bind to tree and value 5 was bind to subtree.
subtree's value (5) was bind to tree.
And nothing else! Means a is stil bound to 4.
How to could we change a? This will work:
mutable struct SimplifiedNode
featid::Integer
end
function test_assign!(tree, subtree)
tree.featid = subtree.featid
end
a = SimplifiedNode(4)
b = SimplifiedNode(5)
test_assign!(a, b)
show(a) # SimplifiedNode(5)
Why? What happend?
Value of a (which is something like pointer to mutable struct) is bind to tree and value of b is bound to subtree.
So a and tree are bound to same structure! Means that if we change that structure a is bind to changed structure.
I saw some pseudocode in some old exam and I can't really figure out what it's doing.
Can anyone explain it to me?
A and B are BST's.
Foo(A,B)
if A= NULL
return B
if B != NULL
if value[A] > value[B]
return Foo(B,A)
left[B] <- Foo(right[A],left[B])
right[A] <- B
return A
This is a binary search tree merge routine. If either A or B is null (representing an empty tree), it returns the other. Otherwise, it makes sure that the root of A is less than the root of B; if the roots are in the wrong order, it recurses with the arguments swapped. Then, it recursively merges the right subtree of A and the left subtree of B, and attaches the result as the left subtree of B. Finally, it attaches B as the new right subtree of A and returns A.
After some complicated integration maple gives a list of solutions defined on different domains of variables. I need to select just one of them. Domains are so complicated that assuming is not helpful: maple runs out of memory trying to figure out how these assumptions correspond to domains he found. However, it is pretty obvious, which solution I need.
Is it possible in maple to extract somehow solution by its number or just drop undefined solutions making maple to forget about domain where it is defined?
P.S. It is hard to copy-paste this solution as it is pretty long.
UPD Minimal working example:
> sln := int(1/x, x=a..b,AllSolutions):
> value(sln) assuming a>0, b>0;
{ -ln(a) + ln(b) a < b
{
{ 0 b = a
{
{ -ln(a) + ln(b) b < a
In this patricular example adding assuming a<b would help, but I would like to get ln(b)-ln(a) directly.
Have a look at convert. It can take your piecewise system and transform it to an array.
> sln := int(1/x, x=a..b,AllSolutions):
> s:=value(sln) assuming a>0, b>0;
{ -ln(a) + ln(b) a < b
{
s := { 0 b = a
{
{ -ln(a) + ln(b) b < a
> conv:=convert(s,list);
conv := [a < b, -ln(a) + ln(b), b = a, 0, b < a, -ln(a) + ln(b)]
> conv[2];
-ln(a) + ln(b)
You can select your favorite part by giving the right (even) index into the array or by matching the odd ones for the part you want (and then select the corresponding even one).
I'm using prototype and have some divs with id p1 p2 p3...
In these divs I have some divs with id d1 d2 d3...
I would like to use $ to get the specified d element, in the specified p element.
If I'm given the values 3 and 4 I should be able to go $('p3').$('d4')
This syntax doesn't work of course.
There's an easy way to do this with jQuery so I'm assuming this exists in prototype
Unfortunately, prototype's $ function doesn't chain, as it returns an extended HTMLElement object and $ is a window method. However, you could use the $$ function along with a CSS selector to achieve this:
$$('#p3 #d4').first(); // Element with id 'd4' that's a descendant of an element with id 'p3'
While the $$ function returns an extended HTMLElement object just like $, it actually returns an array of them, as a CSS selector could potentially match multiple elements.
You can read about CSS selectors here.
Considering an id ("identifier") is (should be) unique, why not just use the most specific identifier you have -- the second one :
$('d4')
If your identifiers are not unique, they are not identifiers... And they shouldn't be used as the "id" attribute of your divs...
Actually, if you have something like this :
p1
d1
d2
p2
d1
d2
d3
p3
d1
Your "pX" can be id (they are unique), but your "dX" shouldn't be ids ; a solution might be to use the class to store the "dX" information.
A bit like this, I suppose :
id=p1
class=d1
class=d2
id=p2
class=d1
class=d2
class=d3
id=p3
class=d1
Then, you'll use the $$ function with a CSS-selector : if you want the element with a class="d2" inside the elemnt of id="p1", something like this might work :
$$('#p1 .d2');
ie :
p1 = element with id=p1
.d2 = element which has a class containing d2
Hope this is clear and helps...
This ought to work:
$('p3').select('#d4').first()
Then again, if all of your ids are unique, as they should be, why not just do this:
$('d4');
$('p3').select(new Selector('#d4'));