D3 treemap for very large dataset - javascript

I am not sure if there is a way to implement this feature. I am looking in for something like zoomable treemaps but to load a few child levels on first go, then no node click add more child nodes and append them to the tree.
Say in http://bost.ocks.org/mike/treemap/ after i reach the leaf node, I make an ajax call if child exists, and if it does, I add them as a child to the graph. I dont want to redraw the graph from scratch, but rather make it more of a visualication on click. This is challenging to me, as i am not aware of how will the accumulate function will work.
This would ensure also, that if i click on grandparent it will help to go back to the previous parent.
This I am planning to achive:
1. Load on click
2. Make it more dynamic
3. Implement it for a very large dataset within browsers cache-able range though
Could someone please suggest something on this front?

I would move the algorithm of calculating the dx, dy, x and y on the server side by accepting the size of the div where you would want to place the treemap on and on a single call I'd return objects upto depth 3 or 4. The challenge could be with the animation transition.

Related

Chart.js / react-chart-js-2 add aura to bubble

I'm currently building a bubble chart that renders correctly with the data points - https://react-chartjs-2.js.org/examples/bubble-chart/
My next step is to conditionally render an "aura" around some of those bubbles (there's no interaction but the aura has a meaning). The "aura" has a single color and is always of the same size.
The only solution I could think of was passing another option to the "dataset" that renders duplicate bubble that's just bigger and behind the original one.
I'm struggling to derive based on documentation if there's a better way of adding it to the graph. Any pointers would be very helpful.

A scatterplot with links between points using d3?

I am trying to make a visualization using d3 which is basically a scatter plot with links between the points. (I have attached a .gif of the existing java based visualization)
The points can be added by double clicking other points. On hovering over a point, I wish to have links drawn between the point and all its partners on screen.
I have the part where on double clicking a node, its partners are added. What I need help with is drawing the links (primarily I am not able to understand how can I get the x1,y1,x2,y2 values required to draw the links).
This is what my DOM looks like:
I have seen a lot of examples online but somehow not able to figure the solution - if anyone could link me to a similar visualization or share a fiddle/ give some pointers on how this can be achieved I would be really grateful.
First the simple stuff: here are 2 mechanisms for drawing the lines.
Next, in terms of the data representation of the lines, check out how links are typically drawn when working with the force directed layout.
Important: Do not get distracted by the existence of the force layout in this example and by the fact that the force layout works with these links (which are passed into it by calling force.links(links)). That aspect of the example probably doesn't have an equivalent in what you're trying to achieve.
However, do notice how the links array is constructed —— with each element of the array being an object with pointers to source and target datums. In your case, you'll want to work with a similar links array, where source is the node under the mouse and target is a node that's connected to it. So you'll end up with an array of links who all have the same source datum but unique target datums.
You can then bind the links array (via the usual .data() method) to a d3 selection of line or path elements. Once you bind, you can use the usual enter, update, exit pattern to append, update and remove (on mouse out) the drawn lines.
Given a source and target datums, you can calculate the x and y of the endpoints in the same way you currently calculate the translation of each <g> element, presumably using a d3 scale.

Updating node labels to avoid clutter in JavaScript InfoVis Toolkit (JIT)

I am doing visualization with the JavaScript InfoVis Toolkit, in particular the hypertree. I am loading data dynamically and sometimes the labels around the nodes overlap and clutter. I would like to avoid this clutter by altering the label positions.
Here is an example of cluttering (the top and bottom nodes):
I imagine that I would loop through each x,y coordinate, give it some bounding box and do basic collision detection, and update positions accordingly.
For this library, I see the demo shows a onPlaceLabel() function, but (if I understand correctly) at that moment I wouldn't know the position of every other node's label. So, I am looking at onComplete(), where I see I can access each node as follows:
onComplete: function(){
ht.graph.eachNode(function(n) {
console.log(n);
}
}
But the node information does not include its label positions, only their positions relative to the center node. Is there a way to access the labels in this way and be able to update their positions?

Understanding "call" in D3.js with force-directed layouts

I am new to D3.js, and I want to work with graph layouts. I have this demo set up with a very simple graph obeying the force-directed layout built into D3.
http://jsfiddle.net/ewG95/
What I want to do is be able to turn off the graph layout algorithm (say, when the user presses space) and then still be able to drag nodes around, and turn the force-directed layout back on later.
Right now I have it set up to stop the force-directed layout upon hitting space:
d3.select("body")
.on("keydown", function() {
if (d3.event.keyCode == 32) {
if (forceActive) {force.stop();} else {force.resume();}
}
});
The problem is that every time you drag a node it restarts the force-layout. I've narrowed it down to (essentially) that the call method on a node is being bound to the force layout's drag method.
i.e. this piece of the linked code:
var node = svg.selectAll(".node")
.data(graph.nodes)
.enter().append("circle")
...
.call(force.drag);
I imagine I may have to do two things:
Write a custom "drag" method that moves a node and the edges associated to a single node.
Rebind the node's call method to it as needed (does this even make sense? Would that replace the bound method? And what does force.drag really do?).
I want to know if this has been done before, and how to do it (at all, possibly not using my guess as to how to do it).
First, on your explicit question: what does the call() method do?
In d3, call is just a convenience function to turn other functions inside out. Doing
node.call( force.drag );
Is actually just the same as doing
force.drag( node );
The only difference is that the call method on a selection always returns the selection so you can chain other methods to it.
So now your question is, what does the force.drag( selection ) do? It creates the event listeners that handle the mouse and touch events for the drag behaviour. Those event listeners update the position of the node data object, but they also restart the force layout.
If you don't want the default force-layout drag behaviour, just don't call the force.drag method on your selection.
As far as being able to customize the drag behaviour so that it doesn't restart the force layout, it doesn't look like you can do it with force.drag (not without changing the source code, anyway). However, you can access most of the drag-related functionality by creating your own drag behaviour object and binding it to the nodes.
Then, in your drag event handler you would update the x and y positions of the node data object, and redraw the node and any links attached to it. If your graph isn't too big, you can do this by re-calling your tick function to redraw all the elements to match their data; if your graph is big, you might want to store references to the actual elements in the data objects so you can quickly find the correct links.
Some examples on using drag behaviours (without force layout) to get you started:
http://bl.ocks.org/mbostock/1557377
http://bl.ocks.org/mccannf/1629464
http://bl.ocks.org/mbostock/6123708

How can one draw thumbnails as children in D3 Zoomable Icicle Layout?

I need to use the D3 Zoomable Icicle example (http://bl.ocks.org/mbostock/1005873) to view a file hierarchy.
I would like to have thumbnails to visualize the "leaf nodes" or "files".
I am not sure if this is possible using the example, and then if it is, how to go about having a different visualization of the folders and files within this layout? I have no idea how to attempt this.
Thanks.
If you implement your nodes as <g> elements, then you can use an .each() call to add either a rectangle or an <image> element and set it's size based on the data.
However, if you have lots of leaf nodes in a partition layout, the partitions tend to end up quite narrow, so the size of your image might be uselessly small. I see from your mock-up that you're hoping to tile the thumbnails in a multi-line grid. You're going to need to create some custom layout code, that identifies all the files (leaf nodes) within a given parent folder and calculates the amount of horizontal space which they collectively take up, then assigns the thumbnail positions into a grid no wider than that space.
You'll also need to make sure that your partition layout is sorting the partitions so that all the leaves are together, separate from any subfolders. I think the default sort should work this way, but it's something to keep in mind.
To make your updating and layout code straightforward, once you calculate the new positions for these leaves, make sure you save the x,y, dx (width) and dy (height) values in their respective data objects, over-writing the position and size created by the partition layout.

Categories

Resources