Increasing width and spacing of major groups in a d3 nested group graph - d3.js

I was able to create a chart using sub groups in the manner described here. The results look like this:
I'd like to be able to control width of the colored bars as the number of categories within them increases, rather than just have the category width decrease in width to fit a constant major group width. As a result of this, as the data increases, I'd like to have the "excess" graph just go off the div, like so:
and the excess would be access by means of scrolling, I guess with .css .scroll property.
How does one achieve this kind of look?

Related

handling dynamic data of large or small size in div of fixed width

I have a dynamic data (number of views(count) v/s months) as my input to my multibar graph of apexchart library.
It works nice with small data. However, when I increase the size of data, the graph looks very bad(shown in below figure). I know the reason for this. It is due to the fixed width of graph. The width of bar is calculated based on width of graph and number of data items. But then how to fix this? How to handle large and small data in a fixed sized div?
Step1 : Add a slider to the parent div of graph (overflow-x:auto).
Step2 : Increase graph width based on your data. Do not keep it fixed. Create a logic that changes width of graph (not width of div that contains graph) based on data. Even if it goes beyond the parent div, that is fine as we have added slider only to deal with this.
Step3 : Add a logic for width of bars. In apexcharts, bar width is set in percentages. So,for example : width of bar for less data = 10 (10% of graph width). width of bar for more data = 30 (30% of graph width)
So this way, even if the width of our div containing the graph is fixed, it will be able to handle dynamic data of large and small sizes.
Solution example : https://drive.google.com/file/d/1LzSNaYfzZNKQzOs8r9NVDqmQiFil-Xho/view?usp=sharing

Fast layout algorithms for UI

I have a number of UI elements like panels, edit fields, buttons, labels etc. so panels contain other panels which contain input fields, editors and so on. Most of the elements are editable and/or resizable which means whenever I change anything, a lot of adjacent UI elements should change their width, height and x/y position on the pane. It works fine with a small number of elements but incredibly slow when the number of elements is thousands.
Is there a fast layout algorithm which can be used in this case? Note that I cannot use any existing layout managers and should come up with my own implementation.
I'd suggest taking a leaf out of the Android playbook and have a larger 'grid' and keep everything sized in modular multiples - this avoids you needing to solve the knapsack problem everytime!
For example, instead of having a button with an width of 80 and a height of 40 you store this as metadata as {2:1} (assuming your layout grid is 40^40 squares).
This way if you have a work panel with space of, say, {2:12} this could be filled with two objects of size {2:6} or maybe 3 of size {2:4}.
It's pretty simple to fit-to-max too as any available space can just be scaled up (say you delete a {1:1} item you can just expand the one next to it to take the space etc - you can of course create your own rules around whether objects can scale in single directions etc.
The other advantage of this approach is that you can easily manage different screen sizes and resolutions too while still keeping the same framework and look and feel.

how to control size of bubble in circle packing layout in d3

in an animated circle packing d3 chart like this https://bl.ocks.org/HarryStevens/54d01f118bc8d1f2c4ccd98235f33848
The bubble will always size to fill the rectangle drawing canvas. Is there a way to fix the size to be consistent such that I can make the bubble growing smaller?
meanwhile because it'll scale up, even if passing in smaller value, the radius doesn't really get smaller.
for example: if data switched from [{"a",40}, {"b",50},{"c",60}] to
[{"a",4}, {"b",8},{"c",10}], ideally the circle get proportionally smaller.
how to control the scale? thanks.
d3.pack() has a method called size. According to the API:
If size is specified, sets this pack layout’s size to the specified two-element array of numbers [width, height] and returns this pack layout.
So, for instance, in the bl.ocks you shared we can do...
.size([width/2, height/2])
... to reduce the packing area.
Have a look at this updated bl.ocks, I put a rectangle to show the reduced area and a lavender background in the SVG: https://bl.ocks.org/GerardoFurtado/de5ad7b9028289d290a62bc41f97f08b/880ec47cbfa236bb05e96b8e22dbe05e9bdf140d
EDIT
This is an edit addressing your edit, which is normally not a good practice in a S.O. answer, but I believe that this point is worth a clarification: changing the data doesn't matter!
In your edit you said that...
if data switched from [{"a",40}, {"b",50},{"c",60}] to [{"a",4}, {"b",8},{"c",10}], ideally the circles get proportionally smaller.
No, they won't! The layout gets the data and takes the maximum amount of the available space. For instance, even if you have an object like this:
[{name:"foo", size:1}]
This is what you'll have: https://bl.ocks.org/GerardoFurtado/0872af463ee0d786dc90f2d1361f241f/bd5357164708f09e2f130f510aea424809d9d1f1

dc.js not respecting xUnits

I'm trying to reduce the number of points in a DC.js line chart to improve performance. The docs lead me to believe xUnits() is the way to do this:
The coordinate grid chart uses the xUnits function to calculate the number of data projections on x axis such as the number of bars for a bar chart or the number of dots for a line chart.
but xUnits does not even seem to be used:
http://jsfiddle.net/m5tguakf/2/
What am I doing wrong?
The number of points is actually determined by crossfilter - dc.js doesn't do any aggregation on its own, so it has no way to add or reduce the number of points.
That documentation may be misleading - it doesn't alter the shape of the data. xUnits is really just needed for dc.js to know the number of elements it is going to draw. It's used for two purposes:
to determine the width of bars or box-plots
to know whether the x scale is ordinal or quantitative
Could dc.js just count the number of points in the crossfilter group? Perhaps.
Anyway, to get back to your original question: if you want to reduce the number of points drawn, aggregate your data differently in your group. Usually this means creating larger bins which either sum or average the data which fall into that interval.
As a simple example, you can combine every other point in your fiddle by binning by even numbers, like so:
var BINSIZE = 2;
// ...
speedSumGroup = runDimension
.group(function(r) { return Math.floor(r/BINSIZE) * BINSIZE; })
// ...
http://jsfiddle.net/gordonwoodhull/djrhodkj/2/
This causes e.g. both Run 6 and Run 7 to fall in the same bin, because they have the same group key. In a real example, you'd probably want to average them, as shown in the annotated stock example.

JavaFX's version of WPF's UniformGrid?

I'm starting with JavaFX on a new application and I want to get a layout on screen identical to WPF's UniformGrid. There's TilePane but it's different (similar to WrapPanel I guess).
My approach so far would be (for a collection [size = N] I want to display as "tiles"):
Use a TilePane t.
t.setPrefRows( ROUNDUP( sqrt(N)))
That's probably not the best approach.
Do you know a better solution? Maybe a resizable one?
It sounds like you want a layout which:
Has a fixed number of cell nodes in each row.
Each cell node has the same height and width.
I'm not familiar with WPF or UniformGrid, but I think the above is what you want.
TilePane likely isn't a Good Fit
It seems like TilePane would be a good fit for this, but, as you found out, it doesn't really exhibit this behaviour out of the box. With a TilePane, you set a preferred number of rows, but as you resize the TilePane the number of rows and the number of columns can change as the tiles are rearranged to fit the available area.
Use a GridPane with Binding and Preference Settings or Constraints
To get a fixed number of cells per row, use a GridPane. A GridPane will keep a fixed number of rows and columns as it resizes. To ensure that each cell node has the same height and width, you can listen to the height and width properties of the GridPane and, on change, set the min/max/preferred sizes of the child elements so that they all have the same size. Or set some constraints on the GridPane rows and columns such as setPercentWidth and setPercentHeight.
To demonstrate this approach, the ColorChooser sample provides some code for a re-sizable ColorChooser with a fixed number of color swatches per grid row and as the overall containing grid grows or shrinks, the color swatches are grown and shrunk to fit the available area as appropriate. The color swatches themselves don't necessarily maintain the same height/width ratio, but you could easily achieve that by setting appropriate min/max/preferred sizes on the child elements.
Create Your Own Layout
As an alternative to using change listeners and setting min/max/preferred sizes on children, you could implement your own layout manager by subclassing Pane to create a UniformGrid class and implementing the layoutChildren method. In layoutChildren, arrange the size and position of UniformGrid children as needed. You can refer to the source code of an existing Pane to find an example of how to create your own layouts.
Investigate 3rd party Layouts
The ControlsFX project has a GridView or MigLayout which might provide the functionality of a UniformGrid.

Resources