d3.select.reverse() has no effect - javascript

I'm confused why reverse() works for regular arrays but not d3.select objects, which are based on the array as well. I'm basically trying to traverse the elements I selected from the DOM in reverse order via each but the following seem to traverse them in the same order:
d3.selectAll('.someclass').each(function(){console.log(this);})
d3.selectAll('.someclass').reverse().each(function(){console.log(this);})

I figured it out. d3.select IS an array, it's in their documentation (https://github.com/mbostock/d3/wiki/Selections), but it's a container array of size 1, the actual array of DOM elements is contained within that first element. The following, while a bit uglier, works as expected:
selection = d3.selectAll('.someclass')
selection[0].reverse()
selection.each(function(){console.log(this);})
I'm not a big fan of using the sort solution (the elements are technically already sorted, and I'd also need to figure out the current order in the DOM tree to compare by).

There is no .reverse() method in D3. Note that selections are not arrays and come with their own implementation of methods to manipulate them. To sort the elements in a particular way, use .sort().

Related

What data Structure to use for storing and searching within huge JSON / Dict type object in Browser

I am creating a ReactJS app. The app has over 100,000 entities on screen which I am plotting using WebGL. The properties of these entirties are stored in a JSON/Dict type object. Whenever a user applies a filter, I need to go through the values, compare the properties, and select the ID (type UUID4) of those not matching the filter, so that I can turn their Visibility to False in the WebGL container.
I am presently using an Array of the following type :-
spriteProps = [ {id: xxxx-...-xxxx, color: Blue, Length: 10, points:50},
{id: yyyy-...-yyyy, color:Red, Length:25, points:112},
.....
]
The user may want to see all entities which are Blue in color and have a length less than 100. So I have to iterate through each value and check which values match the filter.
However, this is very slow.
What is the best data structure to use in this situation to get the best performance? Is there any JS library I can use to improve performance?
Thanks.
https://www.ag-grid.com/react-getting-started/
Ag-grid is a good library that will help you implement what you are looking for.
I have used it with data that was an array of objects and the dataset was very large. It should fit your needs perfectly.
Sorting and searching works seamlessly. Your properties will be the column headings and you can sort and filter based on columns. Selecting rows and pinning specific rows is also possible.
Basically in this use case you need to filter from large set of data.
Cross filter is very good option. Crossfilter is a JavaScript library for exploring large multivariate datasets in the browser.
https://github.com/crossfilter/crossfilter
You can try the following binary search approach.
Choose any property likely to be used in the filtering criteria. I'm choosinglength here. When user applies filters and if length isn't used as a filter, then fallback to simply iterating the array in sequence.
When data is available, sort the array in ascending or descending order based on length property.
When user applies filters, perform a binary search to find the index above or below which all elements are within the given length.
Iterate on the section of the array containing elements within given length and turn visibility off for elements with different color property.
Then iterate on other section of the array containing elements greater than given length and turn visibility off for all these elements.
We can see that we are visiting every element in the array. So, this approach isn't any better than visiting each element in the array sequentially.
If all the elements have visibility off at the beginning and if we have to turn visibility on for selected elements, then we can avoid visiting the second section of the array (point 4), and this binary search approach will be useful in such case.
But since it isn't the case, we have to visit every element in the array and therefore time complexity couldn't get better than linear time O(n).

why is d3 each() function only iterating through first item in list?

For some reason, when I implement the d3 each() function it only acts upon the first item in an array. For example, in the following function, only the user ID of the first user in the array is alerted:
https://jsbin.com/hayedeh/edit?html,js
What am I missing here?
Using selectAll instead of select will iterate the entire array. That said, you need to read up on selections. This is an odd use case (selecting an array). It's meant to be used with selectors or node elements to traverse collections of DOM elements. I see little need to use it to traverse regular arrays. Just use good old fashioned array methods.
U can do forEach like this:
users.forEach(function(user)
{
alert(user.userID);
});

why does .add() method in jquery sort the set?

i was adding many dom objects (svgg elements) around 3000 to an empty jquery set using .add() jquery method but it takes a lot of time and the ui freezes when the javascript is running.And i found out that add every time sorts the set which is taking a lot of time but why is there a need of sorting.
here is the javascript code.
var list= $jquery();
for(x=0;x<no_of_objects(around 3k+ in my case);x++){
list.add(items[x]);
}
Let's see what jQuery docs say about .add() method:
When all elements are members of the same document, the resulting collection from .add() will be sorted in document order; that is, in order of each element's appearance in the document. If the collection consists of elements from different documents or ones not in any document, the sort order is undefined. To create a jQuery object with elements in a well-defined order and without sorting overhead, use the $(array_of_DOM_elements) signature.
https://api.jquery.com/add/
So if you want to preserve the order, try $(items) as they suggest..?
Because jQuerys add() does not only append a value to a set, it actually creates a new sorted collection and then adds the value to it..
For more info, take a look at the docs: https://api.jquery.com/add/
You can add this elements in loop to element not attached to DOM, and then attach them in one move. Each time you modify DOM, browser must recalculate view.
var list = new Array();
for(x=0;x<no_of_objects(around 3k+ in my case);x++){
list.add(items[x]);
}
$('#list').append(list.join(""));

Remove all the DOM elements with a specific tag name in Javascript

How can I remove all the elements with a specific tag name using Javascript. For example, I did the following:
var els = document.getElementsByTagName("center");
and it returned an array of all the center elements. How may I remove all these elements?
Coming from Remove all child elements of a DOM node in JavaScript and JavaScript DOM remove element I know that I can loop through els, find the parent of each element and then remove that specific node. But is there anyother way provided by javascript. Like we can do $('center').remove() in jquery and it removes all the elements with center tag. Anything similar to that in Javascript?
With the mention that you still loop over the elements (there is no way to avoid that), you can do this:
Array.prototype.slice.call(document.getElementsByTagName('center')).forEach(
function(item) {
item.remove();
// or item.parentNode.removeChild(item); for older browsers (Edge-)
});
DEMO: http://jsbin.com/OtOyUVE/1/edit
Some notes on slice:
document.getElementsByTagName doesn't return an array, it returns a live list with a length
property. That is why it is needed to first convert it into an array (Array.prototype.slice does that for any object with the length property). By doing that you eliminate the problem of the list being live (gets updated when you change the DOM) and you also get the other array functions to work (like forEach) which have a more functional syntax for looping.
"it returned an array of all the center elements."
Well, it returned an array-like object (a live NodeList or an HTMLCollection depending on the browser).
"How may I remove all these elements?"
You have to loop through the list removing them one at a time as you mentioned later in your question. If you find yourself doing that a lot, encapsulate the looping inside a function so that you don't have to repeat it.
"we can do $('center').remove() in jquery and it removes all the elements with center tag. Anything similar to that in Javascript?"
jQuery is a collection of JavaScript functions, so it can't do anything JavaScript can't do. jQuery's .remove() method (like most other jQuery methods) will loop internally, it just saves you having to think about it. So that comes back to what I already mentioned above, encapsulate the loop/remove code in a function so that you can use it from any part of your code.

Convert jquery selectors to array

I need to be able to store the current selectors in the current viewport and then 10 seconds check if they are still in the users current viewport.
My solution for this was to store the selectors in an array and then in 10 seconds compare the old selectors against the new and see if any match. If they do... do something.
So i believe using .each and build the array, unless somebody has a more elegant solution to this?
$('.gridContainers:in-viewport')
This will return a standard selectors.
Calling $(selector) returns an array-like jQuery object, not an actual JavaScript array, though for the purposes of what they're trying to do converting it to an actual array may be unnecessary.
This is how one would turn a selector into an native Javascript array.
$(selector).toArray()
Jquery.toArray()
With ES6 :
Array.from($(selector)); // return JS array
Try Out FIND method as Below:
$('element').find('selection');
This will give all selected elements to Array. Hope this helps

Categories

Resources