two graph of d3 in same page are getting effected when events happening in other graph - d3.js

in a html page we have two divs.
one div consist of tree layout and second div consist of other graph .both are written in d3.
d3.select("g").transition().duration(duration).attr("transform",
"translate(" + x + "," + y + ")scale(" + scale + ")");
the above statement d3.select('g') is causing issue,it is trying to select the other div as well and it is effecting it.
tried adding id to each container but didnt worked.
thanks in advance

There are a few things you can do to differentiate between elements.
Give IDs to the divs and use them in the selector. d3.select("#divone > svg > g")
Assign different classes to the g elements. d3.select("g.classone")
Keep references to the SVGs when creating them and select from those.
Here's some example code for this way:
var svg1 = d3.select("#divone").append("svg"),
svg2 = d3.select("#divtwo").append("svg");
// more code
svg1.select("g");
Which way is the best depends entirely on your application, but in general the last solution is the safest one as you're keeping explicit references to your subselections.

Use something like this
function animateFirstStep() {
d3.select(this).transition().delay(0).duration(
100)
.attr("r", function(d) {
return d.r + 4;
});
or pass selector in place of this.
say the name if your function is generateChart(selector)
call the function like this generateChart("#NameofDiv")
it should work

Use something like this
.......
var g = d3.select(this)
redraw(g);
.....
function redraw(g) {
g.selectAll(".resize").attr("transform", function (d) {
"translate(" + x + "," + y + ")scale(" + scale + ")");
});
}

Related

Moving a node in a tree with its link and subtree but without dragging

I am trying to move a node in a d3.js tree based on this example.
I would like to move the node called "Level 2: A. So I use the following code:
var nodeToMove = node.filter(function(d) { return d.name === "Level 2: A" })
nodeToMove.attr("transform", function(d) { return "translate(" + (d.x + 100) + "," + (d.y + 100) + ")"; });
But if I do so, only the node is moving but not the link or the subtree.
The result can be seen on jsfiddle
A similar question has been asked, but one solution is not moving the link and the other is probably based on a force layout which is not my case.

How to make d3 milestone Shape

I'm trying to align a down triangle with a rectangle to make a group that can be used to represent a milestone. Any ideas why this code only shows 2 triangles and how to move them to centre bottom of rectangle or any other methods to achieve the same goal?
http://jsfiddle.net/sjp700/Pej4M/
tri.enter().append("path")
.attr("d", d3.svg.symbol().type("triangle-down"))
.style("fill", "black")
.attr("transform", function (d) { return "translate(" + xRange(d.start) + "," + yRange(d.Duration) + ")"; });
As pointed out in the comments, the reason you're seeing only two rectangles is that some of the data is bound to existing paths. To fix, assign a special class to the symbols that you can select by:
var tri = vis.selectAll("path.tri").data(datar);
For the positioning of the symbols, you need to use the same values you use for the rectangles. The y position needs to be offset by a constant so that the symbols appear at the bottom and the x position by half the duration -- I'm guessing that this is what you really want to show as you're currrently hardcoding everything to length 50.
.attr("transform", function (d) { return "translate(" + (xRange(d.start) + 25) + "," + (yRange(d.start) + 15) + ")"; });
Complete demo here.

Smooth transitioning between tree, cluster, radial tree, and radial cluster layouts

For a project, I need to interactively change hierarchical data layout of a visualization - without any change of the underlying data whatsoever. The layouts capable of switching between themselves should be tree, cluster, radial tree, and radial cluster. And transitioning should be preferably an animation.
I thought that would be relatively easy task with D3. I started, but I got lost in translations and rotations, data bindings, and similar, so I am asking you for help. Also, probably I am doing something not in the spirit of D3, which is bad since I am seeking a clean solution.
I put together a jsfidle, but it is just a starting point, with added radio buttons, convenient small data set, and initial cluster layout - just to help anybody who wants to take a look at this. Thanks in advance!
UPDATE:
I wanted to focus on links only, so I temporary disabled other elements. Building on #AmeliaBR method, following animations are obtained:
Here is updated jsfiddle.
UPDATE 2:
Now with circles: (excuse my choice of colors)
{doom-duba-doom}
Here is one more updated jsfiddle.
I don't see why it would be that hard so long as all your layouts have the same overall structure of link-paths, circle nodes and text labels.
Just make sure all your objects, including your link paths, have a good data-key that is independent of the data attributes created by the layout functions. Then for each transition, update the data with the results of the appropriate layout function and draw that layout.
I've got the transition to radial tree implemented here: http://jsfiddle.net/YV2XX/5/
Key code:
//Radial Tree layout//
var diameter = 500;
var radialTree = d3.layout.tree()
.size([360, diameter / 2 ])
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });
var radialDiagonal = d3.svg.diagonal.radial()
.projection(function(d) { return [d.y, d.x / 180 * Math.PI]; });
function transitionToRadialTree() {
var nodes = radialTree.nodes(root), //recalculate layout
links = radialTree.links(nodes);
svg.transition().duration(1500)
.attr("transform", "translate(" + (diameter/2)
+ "," + (diameter/2) + ")");
//set appropriate translation (origin in middle of svg)
link.data(links, function(d){
return d.source.name + d.target.name;})
.transition().duration(1500)
.attr("d", radialDiagonal); //get the new radial path
node.data(nodes, function(d){
return d.name ;})
.transition().duration(1500)
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
node.select("circle")
.transition().duration(1500)
.attr("r", 4.5);
node.select("text")
.transition().duration(1500)
.attr("dy", ".31em")
.attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.attr("transform", function(d) { return d.x < 180 ? "translate(8)" : "rotate(180)translate(-8)"; });
};
The layout code is all from http://bl.ocks.org/mbostock/4063550, I've just changed it to be an update instead of an initialization.
Also note that I have moved the variable declaration for root outside of the data-reading method, so it can be re-accessed by the transition functions.
Layout still needs some finessing, but you get the idea.
Now, if you wanted one of the transitions to be a partition, treemap or other layout that doesn't use the node-link structure, they it gets more complicated...
I don't have enough reputation to make a comment...so, I am just giving this tiny contribution as a pseudo-answer. After looking at this post, and based on #VividD's perfect comment on how simple the transitions turned out to be, I simply added the Tree Vertical option to the transformations in this fiddle.
The addition is simply this:
var diagonalVertical = d3.svg.diagonal()
.projection(function (d) {
return [d.x, d.y];
});
Anyways, I have bookmarked this highly instructional interaction.

Unique symbols for each data set in d3 Scatterplot

I am having trouble using d3's symbol mechanism to specify a unique symbol for each set of data. The data's like this:
[[{x: 1, y:1},{x: 2, y:2},{x: 3, y:3}], [{x: 1, y:1},{x: 2, y:4},{x: 3, y:9}], etc.]
The part of the code that writes out the symbols looks like this:
I create a series group for each vector of points. Then:
series.selectAll("g.points")
//this selects all <g> elements with class points (there aren't any yet)
.data(Object) //drill down into the nested Data
.enter()
.append("g") //create groups then move them to the data location
.attr("transform", function(d, i) {
return "translate(" + xScale(d.x) + "," + yScale(d.y) + ")";
})
.append("path")
.attr("d", function(d,i,j){
return (d3.svg.symbol().type(d3.svg.symbolTypes[j]));
}
);
Or at least that's how I'd like it to work. The trouble is that I can't return the function d3.svg.symbol() from the other function. If I try to just put the function in the "type" argument, then data is no longer scoped correctly to know what j is (the index of the series).
right, but I don't want a unique symbol for each datapoint, I want a unique symbol for each series. The data consists of multiple arrays (series), each of which can have an arbitrary number of points (x,y). I'd like a different symbol for each array, and that's what j should give me. I associate the data (in the example, two arrays shown, so i is 0 then 1 for that) with the series selection. Then I associate the data Object with the points selection, so i becomes the index for the points in each array, and j becomes the index of the original arrays/series of data. I actually copied this syntax from somewhere else, and it works ok for other instances (coloring series of bars in a grouped bar chart for example), but I couldn't tell you exactly why it works...
Any guidance would be appreciated.
Thanks!
What is the question exactly? The code that you give answers your question. My bad, j does return a reference to the series. Simpler example.
var data = [
{id: 1, pts: [{x:50, y:10},{x:50, y:30},{x:50, y:20},{x:50, y:30},{x:50, y:40}]},
{id: 2, pts: [{x:10, y:10},{x:10, y:30},{x:40, y:20},{x:30, y:30},{x:10, y:30}]}
];
var vis = d3.select("svg");
var series = vis.selectAll("g.series")
.data(data, function(d, i) { return d.id; })
.enter()
.append("svg:g")
.classed("series", true);
series.selectAll("g.point")
.data(function(d, i) { return d.pts })
.enter()
.append("svg:path")
.attr("transform", function(d, i) { return "translate(" + d.x + "," + d.y + ")"; })
.attr("d", function(d,i, j) { return d3.svg.symbol().type(d3.svg.symbolTypes[j])(); })
The only difference is that I added parenthesis after d3.svg.symbol().type(currentType)() to return the value rather than the function. D3js uses chaining, jquery style. This let you use symbol().type('circle') to set a value and symbol().type() to get it. Whenever accessors are used, what is returned is a reference to a function that has methods and attributes. Keep in mind that, in Javascript functions are first class objects - What is meant by 'first class object'?. In libraries that use that approach, often, there is an obvious getter for retrieving meaningful data. With symbol, you have to use symbol()().
The code beyond the symbol functionality can be seen at: https://github.com/mbostock/d3/blob/master/src/svg/symbol.js
d3.svg.symbol = function() {
var type = d3_svg_symbolType,
size = d3_svg_symbolSize;
function symbol(d, i) {
return (d3_svg_symbols.get(type.call(this, d, i))
|| d3_svg_symbolCircle)
(size.call(this, d, i));
}
...
symbol.type = function(x) {
if (!arguments.length) return type;
type = d3_functor(x);
return symbol;
};
return symbol;
};
Just in case you haven't. Have you tried?
.append("svg:path")
.attr("d", d3.svg.symbol())
as per https://github.com/mbostock/d3/wiki/SVG-Shapes.

d3js How to gather nodes by cluster un force layout?

I have network and each node has a property group obtained by a clustering method. I would like to know what is the best method to render a network with the force layout where nodes belonging to the same group are gathered in space?
One way, but i don't know how to implement it, would be to add a attractive force between nodes of the same group (little compared to the repulsive force applied to all nodes).
one possibility is to devide space in nb_group directions and push nodes in the direction allocated to their group:
var angle = 2*Math.PI/nb_group;
var intensity = 500;
var updateNode = function() {
this.attr("transform", function(d) {
var xm = d.x + intensity*Math.cos(angle*d.group);
var ym = d.y + intensity*Math.sin(angle*d.group);
return "translate(" + xm + "," + ym + ")";
});
}
my intensity is hugh because I have charge of 1000

Resources