What does D3's "empty" selection do? - javascript

I'm fairly new at D3 and recently saw this piece of code while someone was creating a transition: d3.select({}) in d3.select({}).transition() etc. This seems to be doing the same thing as d3.select([]). In the console, it showed up as an array, but I'm still unsure what it does. Any help would be appreciated, thank you!

The only place I've seen this is here. Now usually you would d3.select the object you want to run the transition on. But in the linked example, Bostock is not operating on svg composed of different DOM objects to manipulate but instead on a canvas that has to be wiped and redrawn for each step in the transition. So, d3.select({}).transition(), simply becomes an easy way to fire up a generic transition he can work with. You should note that something has to be selected to create a transition, just doing d3.select().transition() won't work and an empty object (or an empty array) allows it to work.

Related

Animated buffergeometry with morphattributes not updating shadow

I have converted the MD2 code from the library to use THREE.BufferGeometry instead of THREE.Geometry to vastly improve memory footprint. To do this I just convert the model to THREE.BufferGeometry after it is done loading. I also had to modify the MorphBlendMesh code to use attributes for the morphTargetInfluences.
This is working great except for issue: the shadows don't update during animation, it always uses the shadow from the first frame of the animation.
I haven't seen any documentation on morphTargetInfluences attributes, so I don't have much to go on.
I can't really post the code since it is too much spread out across the code base.
I am just hoping that someone out there might have some insight as to how shadows get updated during morph animation, and maybe point me in the right direction on how to research this issue.
I have found the problem, and a workaround!
The code in the shader renderer is checking to see if geometry.morphTargets has a non-zero length before it decides to set the 'usemorphing' flag. The converted buffergeometry does not have a .morphTargets field since this information appears to have moved to .morphAttributes for buffergeometries.
My hack workaround is to add a fake .morphTarget list like so:
Buffergeometry.morphTargets = [];
Buffergeometry.morphTargets.push(0);

three.js and depthFunc

From looking at the code, it seems that three does not give much control over the depthFunc. I would like to confirm that it's only set once as the default GL state, and not available say, in the material?
I'm not familiar with all examples, and was wondering if this is happening somewhere?
If not, what would be the best approach to set the depthFunc to gl.EQUAL for example, when a specific draw call is being made i.e. a mesh with a material?
Is something like toggling between scenes i.e. use one to render stuff, then use another one to render stuff on top of the first one a good solution for this? That's the only example that i've seen of tweaking the otherwise sorted objects.
It's currently in the dev branch of three.js: the pull request.

Updating overflow without removing elements from the div?

If I used:
parentNode.removeChild( divHere );
It does work and the scroll bar for the overflow updates accordingly. If I use JS to 'divHere.style.visibily = "hidden";' well that doesn't work anymore. What I've done pretty much is create 115 divs that are in a container div and the user can select filters to show only the images they want, all the divs have a background image and are essentially just an image with a name under it.
So I have 2 questions:
1) Is there a way to update the overflow and make it not take hidden elements into consideration?
2) If 1) isn't possible than when I use removeChild to remove a div from the container, it does indeed disappear but what exactly happens to it? Does it disappear off the page because it's not added to any element on the page? So it essentially works like it's hidden? I don't have to worry about people seeing the images in some completely weird spot in some lesser used browser?
and well 3) If you have a better method of doing this it would be greatly appreciated
Thanks in advance for any help
The removeChild() method removes a specified child node of the specified element and returns the removed node as a Node object, or null if the node does not exist.
That null means that the element is now removed from your mark-up.
You should use it to not let the browser take that into consideration, as the browser will not find that element in the mark-up.
You can do it in this way as well:
$(document).remove(object_to_remove);
FInd more about it: http://api.jquery.com/remove/
I believe I may have a response for the third part of your question. That large number of divs in your containing div and the usage of filtering make me think you might want to look into using the DataTables plugin for jQuery (http://www.datatables.net/). It has some very nice features for sorting/filtering/etc. a large number of data elements and supports a variety of data sources. There are also some plugins for the plugin if the basic functionality isn't enough for you.
There is a bit of a learning curve if you want to do more complex stuff with it, and it might be tricky to get used to if you haven't worked with jQuery much (though being someone who hasn't worked with jQuery all that much due to not doing much web development, I can say that I quite like using it whenever I get the chance, although that may just be due to me enjoying learning how to do new things in programming), but I feel that if you're willing to spend the time on it you will have something much more maintainable than what you currently have.

Highlighting Highcharts series from a remote element

I'm trying to figure out how to highlight a line (series) in Highcharts from an element that's not related to the Chart object in any way.
I went through the documentation, and don't really see a way of achieving this. I can get into the series elements using the series.get(id).
Seems like there are no methods that can be helpful - http://www.highcharts.com/ref/#series-object
Any ideas if that's even possible?
After a lot of digging and testing, I've managed to get this working - still not sure if this is the best way (probably not).
Chart.series.get(someId).graph.attr('stroke-width', '5')
Unfortunately, this is just getting into the actual DOM element and changing the value of the property of a single element, so if you need to change the stroke width, and the styles of the markers on this line, you'd have to loop through all elements, and apply changes manually.
UPDATE: Ok, there's a better way
But this is using the private API, so if the library changes thins, your code will not work:
Chart.series.get(someId).onMouseOver() and Chart.series.get(someId).onMouseOut().
This actually fires the defined hover-state.

Can someone clarify Raphael's documentation? (or know a place in which someone already has done it)

I´m working with Raphael, and I think that I´m using it in a way that does not take advantage of some features that seems to be useful.
For example, I´m trying to add a listener on a Set (a group of elements), in a way that on mouse over on any of those elements, the script triggers an animation on the whole set.
When you add a listener to a set, Raphael adds the listener to each of the elements and animates them separately.
Like you see in this example http://jsfiddle.net/4VYHe/3/ in wich I want that all the rectangles in the same set (set = horizontal groups of 10 rectangles), change the color attribute on mouse over on any of them.
I have found a few methods in the raphael documentation that i think must help to achive this. But I´m having a hard time understanding how these methods work.
For example:
the eve object(http://raphaeljs.com/reference.html#eve)
the Element.animateWith() method (http://raphaeljs.com/reference.html#Element.animateWith)
the Raphael.animation() method (http://raphaeljs.com/reference.html#Raphael.animation)
The Raphael Library seems to be really powerful and I really want to get it work properly, I don´t want to write all kinds of diferent javascript hacks, because I think that these tools have to get the work done in a more elegant way.
If you think that I´m using the wrong library I´m still open to all kinds of advices.
Thank you in advance.
---EDIT---
This is a working example (http://jsfiddle.net/4VYHe/6/). But this is a hack with lack of efficiency and elegancy. I want something that uses the correct tools on the correct way.
There is some information on this page. http://www.irunmywebsite.com/raphael/additionalhelp.php?v=2#PAGETOP . A couple of examples, but nothing that explain how things work in Raphael.
Take a look at this fiddle, I think it is doing what you are looking for. The fundamental difference is that you want to call animate on the set, rather than this. It appears that when you add a handler to a set, this refers to the individual elements in the set (which are iterated over to assign the handler), and not the set itself.
Note that I pulled the handler functions out into the getHoverHandler function:
function getHoverHandler(fillColor) {
var cSet = set;
return function(){
cSet.animate({fill: fillColor}, 300);
};
}
set.hover(getHoverHandler('#000'),
getHoverHandler('#FFF'));
in order to break the closure. If you try to do it like this:
set.hover(function(){
set.animate({fill: '#000'}, 300)
}, function(){
set.animate({fill: '#FFF'}, 300)
});
as you loop through, set will keep changing, and the closures will maintain awareness of this. As a result, all handlers will be acting on the last row of boxes.
If you don't understand javascript closures, you might want to look at this article. It is old, but in pretty simple language, and it helped me as I have tried to get my head around them.
Kreek is absolutely correct in this comment above. Sets are a workaround for the inconsistencies between SVG and VML.
In your example above, you're running into the same issue that you were facing in your previous question. Using this in an anonymous function will almost always not work in the way you expect, as this won't be referring to what you think it is. Have a look at this discussion, particularly the first two comments in the comments section. (As an aside, the commenter uses "self" as the reference to "this", which is much better than my "that", which goes to show there's always someone doing it better than yourself)
Anyway, with that in mind, I've cloned your fiddle, wrapped your set in an object, and put the events into the object constructor. By doing this, the event can then refer to that.set and animate all objects in the set at the same time.
It's a small but fundamental concept that will aid you throughout any Raphael (or javascript) development you do.
This doesn't answer your question directly, but hopefully clarifies some of the issues you seem to be discovering. I can't really comment on the animation calls you've mentioned, but I do think that Raphael as a library is definitely worth persevering with.
N.

Categories