d3.js change path target or increase lines - d3.js

using the bl.ocks collapsable tree example: how do I increase the length of the lines between the circles (or move the circles further out, to the right)? I know I can style the lines easily using CSS and I can update the circle sizes easily in the script... but my text is longer and it is overlaid when the children are exposed. Better still would be either:
* calculate the max length of text in that set of children and set the new children out past the current set of children.
or
* when exposing children, move the current set of children apart so the child that is now also a parent, has room at top/bottom to accommodate it's children.

You can use the tree.nodeSize() function to set the height and width of the spacing. The thing to note is that if you are following the code posted above, it is using the tree.size() function and the both of these can't be used at the same time. Here is the documentation for the tree.nodeSize() function: https://github.com/d3/d3-3.x-api-reference/blob/master/Tree-Layout.md#nodeSize.

Related

How to size circles in pack layout correctly

I'm building a 'cluster visualization' leveraging pack layout recently to help explore some of our data. Please see the screenshot. (Looks like I can not attach a image, so I posted a dropbox link)
https://www.dropbox.com/s/pfcq6ytetv19bng/Screenshot%202015-05-27%2013.42.14.png?dl=0
This is how I did it: first, I rendered the clusters' circles using one pack layout(the light blue ones), and then I grabbed the positions of all the clusters and created all the G elements. Finally, within each G element, I rendered the children elements using a different pack layout(the colorful circles).
The reason I did it this way is: I want to separate clusters far away from each other and keep children elements of one cluster close to each other.
But, it seems the sizes of children circles in different clusters are not consistent. (all the red circles should actually have the same size, cause their values are the same). Right now, I simply sum up all the children' values to get the clusters' values.
My question is, how can I get the sizes of circles within different clusters correctly? Thank you in advance :)
Best,
I would recommend using the layout to calculate all the circles sizes, so they're all the size. Then you can offset all of the children of the root's children to be relative to the root's children. For each root child, you can then add a <g> and scale it however you like. Here's a live demo of what I mean: http://bl.ocks.org/vicapow/3d24f96c240eeb8d14e3

D3.js - how can I position a force chart upwards and to the left of a page?

I have a force network graph (in a Drupal site) which does what I want it to (thanks to many members of stackoverflow) but it ends up about 400px from the top and left margins of the content area.(see http://trsg.tcan.ca/stronger-together-network)
Which parameters control this?
The force layout is designed to distribute items in the available space. When you create a force layout, you set the size of the available area, and the nodes are attracted to the center of the area.
You can either set a smaller area for the network chart or lower the attraction between the nodes and the center, by setting the charge attribute of the force to a greater value. The default value is -30, try with -10 or -5.
Assigning the layout to Body instead of a DIV solved the problem. (In most other scripts I had to use a DIV and using Body caused problems.)

Key function for D3 datum

I was wondering how would it be possible to associate a certain key function with a datum data binding in D3. This seems to be possible with .data([values[, key]]), but the key is not available as parameter in the .datum([value]) binding.
This becomes particularly relevant when drawing SVG paths in which the updated values are not appended to the end of the data array, but contribute to changes in granularity in the middle.
This example illustrates this case:
http://jsfiddle.net/vastur/LtHyZ/1/
Each data point is an [(x),(y)] tuple. The red dots are moving properly according to the key function on the x axis:
.data(lineData, function(d) {return d[0]})
But the line is created using datum() and therefore no key function is associated. Consequently, its line segments move illogically when new data points are added in between.
So, in this example, how to make line vertices move according to the motion of the red dots?
The short answer is that this is not possible for the case that you're dealing with. The problem is that there is only a single element (the line), so matching and computing joins doesn't make sense. To achieve the behaviour you want, you would need to specify the same number of support points for both lines.
A slightly more elaborate explanation. The D3 data model relies on binding data points to DOM elements. That is, each data point is matched to exactly one DOM element. The path you're drawing is a single DOM element and therefore has only one data "point" matched to it, the point being an array in this case. You can't use D3's data model for what you want precisely of this -- there's only a single DOM element for the path. Furthermore, SVG paths are entities that cannot be broken easily -- you need an M command to start with and then L commands in your case. You can sort of do it by breaking the line into different segments, but then the animation doesn't work (see here).
The way to achieve what you want would be to preprocess the data to compute any intermediate points.

variable stroke width in NVD3 lineChart

i am trying to figure out if there is a reasonably easy way to extend NVD3's lineChart model to allow variable stroke widths along each line path in a chart.
specifically, i am dealing with a simple line chart where i need to show the year-on-year growth of employment in different sectors (for which NVD3's lineChart works perfectly), while also giving an idea of the relative weight of these sectors (i.e. agricolture might be growing while employing only a few hundred people overall, while retail might be struggling but still be employing a large percentage of the population) - this won't be a linear scale of course, but assuming that relative weight of each sector varies across time, a thicker line could represent a sector with more employees than one with a thin line.
obviously i could very easily change the stroke width for the whole line using i.e. an average weight of each sector across the whole timespan, but as far as i understand there is no way in SVG to specify a varying width of a single path element: would it make sense to create an NVD3 model that builds on top of lineChart but splits each line into discrete polygons (triangles?) for each year-on-year period?
Looking for an answer to this myself. It seems there is no easy way, but one possibility is to use the stroke-dasharray attribute.
http://owl3d.com/svg/vsw/articles/vsw_article.html
Essentially, you can create a series of cloned paths, covering a range of stroke widths. If you turn them into dash arrays, you can play with the spacing between dashes to control which paths are visible at each point.
Depending on the shape and width you are looking for, you may also be able to fudge it by adding a second path element with a varying offset from the first.
Perhaps generate a closed path and apply a pattern fill or regular fill on that path. The closed path is effectively a triangle shape, to mimic a line of varied width.

d3.js forced directed graph effects on enter

I use d3.js exactly as shown here but with different data value.
When the graph is first shown all elements are scattered and for around a second rapidly move towards their position. This looks nice in the sample, but for my data it does not look so nice. Any way to turn it off so that nodes start in their designated place? Any way to customize this entry visualization?
You can loop through the nodes array and set the .x/.y and .px/.py values to an initial position that you want the nodes in, and by doing so will limit the amount they need to move in their initial layout. If you turn off the force-directed algorithm (the tick() function) then you can apply standard .transtion().duration(500).attr("transform", xx) behavior to the nodes and links to make them animate in a manner you prefer before or after running the force-directed algorithm, but make sure you set the .x/.y and .px/.py attributes to their final position, otherwise they will be reset as soon as you .tick()

Resources