How to generate a treemap using only squares - javascript

I am currently experimenting with the gallery treemap of d3.js.
http://bl.ocks.org/4063582
Now I am wondering if I can make the treemap render all items in squares. I can only get it to render rectangles. I tried to use .mode("squarify"); but that doesn't result in the required layout. It doesn't matter that it won't use all the available space. I just want it to render squares.

Squarified Treemaps: http://www.win.tue.nl/~vanwijk/stm.pdf. It looks like a thorough look at the problem and includes solution pseudocode.
Abstract. An extension to the treemap method for the visualization of hierarchical information, such as directory structures and
organization structures, is presented. The standard treemap method
often gives thin, elongated rectangles. As a result, rectangles are
difficult to compare and to select. A new method is presented to
generate lay-outs in which the rectangles approximate squares. To
strenghten the visualization of the structure, shaded frames are used
around groups of related nodes
Additional Resources
Alternatively, you could create your own output based on the data as suggested here: How to use jQuery to render a JSON tree as nested HTML using divs?
Some improvements on the squarified algorithm: http://incise.org/d3-binary-tree-treemap.html
Treemaps for space-constrained visualization of hierarchies shows a history of various treemap algorithms most with the goal of reducing the rectangle ratio to 1. You might find some of the papers helpful.
This page also provides a nice break down of the various treemap algorithms.
Depending on the data, the rectangles can have very different aspect
ratios, making them hard to compare: a thin long rectangle of the same
area as an almost square one looks very different. Bruls, Huizing, and
van Wijk therefore developed Squarified Treemaps, which optimize the
placement of nodes within a level to make them as square as possible.
While that is a great idea to make static treemaps more readable, it
causes problems when treemaps are used to show developments over time.
Ordered Treemap Layouts, developed by Shneiderman and Wattenberg,
solve this problem by conserving the ordering of elements while
seeking to keep nodes as square as possible, and thus produce very
stable layouts.
Conclusion
The brief read at the wikipedia entry provides a good explanation on why a strictly square treemap remains difficult to achieve. Emphasis added.
To create a treemap, one must define a tiling algorithm, that is, a
way to divide a rectangle into sub-rectangles of specified areas.
Ideally, a treemap algorithm would create rectangles of aspect ratio
close to one, furthermore preserve some sense of the ordering in the
input data, and change to reflect changes in the underlying data.
Unfortunately, these properties have an inverse relationship. As the
aspect ratio is optimized, the order of placement becomes less
predictable. As the order becomes more stable, the aspect ratio is
degraded.
After researching this topic further, I agree with Lars Kotthoff that obtaining a treemap strictly with squares does not appear trivial. At least not based on existing implemented treemap algorithms. The easiest way around this might be to create your own code (JS and CSS) to generate nested divs or lis to achieve the desired final treemap look.
Addendum
http://www.koalastothemax.com/ - this demo renders nested circles but it's obvious they all sit within squares. It might take some work but you probably could achieve the desired results using the Koalas to the Max code.

Unfortunately it is not possible to have the treemap render all items in squares, for mathematical reasons.
Here i just give you a counter-example.
Suppose that, at the end of your processing, you end up with 4 categories (A, B, C, D) with the folowing surface area.
A=2
B=2
C=2
D=1
Independently of the position you give to them, it is impossible to have the final treemap with a square or even rectangle shape.
Think: in each of the following patterns you always have a missing corner
AB AC AD BA BC BD CA CB CD DA DB DC
CD BD BC CD AD AC BD AD AB CB AC AB ..there are more
because one of the square has surface area = 1.
So this is not possible to have all squares
From that paper , as mentioned by JSuar we learn that there is an optimized almost-squared representation you can have, implementing the algorithm described in the paper.
But this is an approximation.
I think that all you can do, if you really need ONLY squares, is:
change visualization, using for instance http://bl.ocks.org/4063530
hack the treemap.js code modifying line 12 as follows
ratio = 1;
But in this latter case you could have some empty white spaces or other malfunctioning.

Related

How to get the same node positions in d3's force layout graph

I would like to create a force directed graph, but i need it to stay the same every time it is generated (with the same data).
Is there any way to do this using d3.js?
UPDATE:
I found working solution, which is based on using seeded random number generator
// set the random seed
Math.seedrandom('mySeed');
You could by modifying D3's force layout, or by creating your own layout based on it. There are at least 3 places where randomness (Math.Random) is used in the positioning of nodes (there may be more, given the force layout references other code). You would have to eliminate all randomness in order to get the graph to display in the same way each time:
https://github.com/mbostock/d3/blob/master/src/layout/force.js
However, this would hamper how the layout works – it's using randomness to sort itself out into a legible diagram quickly. If your number of nodes is small, then it probably wouldn't be an issue, but a large number of nodes could just end up a tangle.

D3.js scattergraph with large (>500,000) points? Clustering?

I'm looking at plotting a scatterplot with a large number of points (500,000 and upwards).
Currently, we're doing this in Python with Matplotlib. It plots the points, and it provides controls to pan and zoom. I don't believe it provides any clustering or points, it just plots them all - doesn't make much sense at the zoomed out view, I suppose, but you can zoom in and they're all there.
I was looking at doing the chart in JavaScript, to make it a bit easier to distribute. I was looking at D3.js, to see if something similar is feasible there. I did find this example of a basic scatterplot:
http://bl.ocks.org/mbostock/3887118
Firstly, would you be able to plot that number of points? (500,000 and upwards) I was under the impression you couldn't due to the overhead of all the DOM objects? Are there ways around this?
Secondly, is there any kind of clustering available, either a library or even just an example of this being done in D3.js?
Thirdly, if anybody knows any good examples of pan/zoom functionality and clustering, or even just a packaged JS library that handles it, that would be awesome.
Fourth, it would be also nice to have click handlers for each point - and to display some text either in a overlay, or even just in a separate window. Any thoughts on this?
Can you draw half a million points with D3? Sure, but not with SVG. You'll have to use canvas (here's a simple example with 10,000 points that includes brush-based selection: http://bl.ocks.org/emeeks/306e64e0d687a4374bcd) and that means that you no longer have individual elements to assign click handlers to. You will not be able to render half a million points with SVG, because all those DOM elements will choke your interface, as you mentioned.
D3 does include quadtree support that can be leveraged for clustering. It's in use in the above example to speed up search but you could use it to nest elements in proximity at certain scales.
Ultimately, your choices are:
1) Some other library/custom implementation that renders in canvas and polls the mouse position to give you the data element rendered at that point.
2) A sophisticated custom D3 approach that nests elements in proximity and only renders SVG elements appropriate at the zoom level and canvas position (pan) you're at.
Yes, D3.js can be made to work with million scale data with two things:
pre-rendering on the server side. For more see here: https://mango-is.com/blog/engineering/pre-render-d3-js-charts-at-server-side/
By aggregating (or clustering) part of the data so that user can interact and expand the graph if need be. For this use collapsible nodes if you can (http://bl.ocks.org/mbostock/1062288).
Also avoid using force layout. It takes time to settle and converge to a stable positioning.
For clustering libraries, I would pick one up off the shelf. I would choose the scikits library from python, there are many in JavaScript but they are not very robust as they mostly cover k-means or hierarchical clustering. I would precalculate the coordinates using scikits by clustering and then render it using D3.
D3 handles Pan and zoom. Again click handlers and text display are available in D3. (http://bl.ocks.org/robschmuecker/7880033)

Comparison of two network graphs

I have two network graphs but placing both of them next to each other is the easiest way to compare if the graphs are small. But as the graph grows, it is making hard for the user to compare the views. I wanted to know the best way to merge two graphs and show the comparison.
In the above picture it can be seen that no of nodes are same but the way they are linked is different.
I would like to know how to present the compared data.
Any ideas about different views to present such comparison using d3.js.
I would suggest not trying to apply force layout or similar method for drawing graphs (that would draw the graph in a fashion similar to the on in the picture in your question). Instead, I wold like to suggest using circular layout for both graphs (similar to chord diagram):
This visual example is made for other purposes, but similar principles could be applied to your problem:
Layout all vertexes on a circle, in equidistant style (if there are some vertices belonging only to one of two graphs, they can be grouped and marked different color)
If there is a link between two vertices in both graphs, connect them in one color (lets say green)
If there is a link between two vertices in one graph only, connect them in appropriate color, dependant on a graph (lets say red and purple)
This method scales well with number of vertices.
Hope this helps.
Following methods for network comparison could be useful in the current scenario:
NetConfer, a web application
Nature Scientific Reports, an article guiding comparisons
CompNet, a GUI tool

spatial index for lines

I have lots of line segments (that represent various surfaces such as walls, ceilings and floors). I want to efficiently determine which lines are within the player's bounding box.
(Right now I'm cycling through all lines, and whilst correct, it is proving much too slow).
There are several kd-tree and other spatial indices in Javascript but they all store points rather than lines.
I actually only need to query by the x axis; it would suffice with a 1D range tree of some sort.
How can you efficiently store and retrieve shapes such as lines?
Once built, the index would not be added to.
In just 2 dimensions, where you have good control over the total spatial extend (i.e. know min and max, and these won't increase), grid based approaches such as plain grids or quadtrees work incredibly well. In particular, if you know your query radius (the players box size), a grid of exactly this size should work really well.
Many games also used what is called a BSP tree, a binary space partitioning tree. But for good performance, this tree is AFAIK usually precomputed when the level is built, and then just loaded with the map.

I'd like to know how WebKitCSSMatrix actually works

Apple's official documentation says:
WebKitCSSMatrix objects represent a 4x4 homogeneous matrix for 3D transforms or a vector for 2D transforms. You can use these objects to manipulate matrices in JavaScript. For example, you can multiply, translate, and scale matrices.
I'm a glorified designer, not an engineer, so I'm assuming that's the reason why I can't make any sense of that description. Please, can somebody point me in the right direction to understand how this matrix and/or vectors work?
Whew, this is the most difficult question I've attempted to answer. The short answer is that, as web designers, we don't have the vocabulary to express 3d transformations. In order to explain it to you in a comprehensible way I'd have to use math concepts which I don't understand myself.
If you'd like to investigate further you can take a look at:
http://www.eleqtriq.com/2010/05/css-3d-matrix-transformations/
But, I can explain it visually.
http://duopixel.com/stack/webkitmatrix/ (you'll have to view this under Safari 5 w/Snow Leopard, or an iPad, or course).
What you're seeing is just an interface to the 16 values webkitCSSMatrix, the sliders that seem to do nothing are related to the z axis, which I suspect would be visible if we had more objects in the 3d canvas.
Edit: after studying the link I placed before, I noticed the original author has done the same example before, doh! http://www.eleqtriq.com/wp-content/static/demos/2010/css3d/matrix3dexplorer.html
Even though it's for ActionScript, check out Understanding the Transformation Matrix in Flash 8. It's got pretty pictures, too :)
Before getting into how transformation matrices (matrices is plural of matrix) work, it is important to understand what a matrix is. A matrix is a rectangular array (or table) of numbers consisting of any number of rows and columns. A matrix consisting of m rows and n columns is known as an m x n matrix. This represents the matrix's dimensions. You'll commonly seen matrices with numbers in rows and columns surrounded by two large bracket symbols.
...
Affine transformations are transformations that preserve collinearity and relative distancing in a transformed coordinate space. This means points on a line will remain in a line after an affine transformation is applied to the coordinate space in which that line exists. It also means parallel lines remain parallel and that relative spacing or distancing, though it may scale, will always maintain at a consistent ratio. Affine transformations allow for repositioning, scaling, skewing and rotation. Things they cannot do include tapering or distorting with perspective. If you're ever worked with transforming symbols in Flash, you probably recognize these qualities.
(source: senocular.com)

Categories