score:2
i found solution in detecting collision function when generating random coordinates, here is the jsfiddle link and code:
(function () {
var angle, offset, data, x, y, r,
collision, circle1, circle2,
circles = [],
size = [8, 15],
width = 500,
color = d3.scale.category10(),
height = 600,
radius = 130,
dispersion = 10,
svgcontainer = d3.select('body').append("svg")
.attr("width", width)
.attr("height", height);
function detectcollision(c2, c1) {
var dx = c1.cx - c2.cx;
var dy = c1.cy - c2.cy;
var rsum = c1.r + c2.r;
return ((math.pow(dx, 2) + math.pow(dy, 2)) < math.pow(rsum, 2));
}
var sh = 2, elements = 55;
data = d3.range(elements).map(function (i) {
do {
// dispersion += i / 50;
angle = math.random() * math.pi * 2;
offset = math.max(size[0], size[1]) + radius + dispersion + (elements/sh);
x = offset + math.cos(angle) * radius + rand(- (dispersion + i / sh), dispersion + i / sh);
y = offset + math.sin(angle) * radius + rand(- (dispersion + i / sh), dispersion + i / sh);
r = rand(size[0], size[1]);
circle2 = {cx : x, cy : y, r : r};
collision = false;
if (circles.length > 1) {
circles.foreach(function (d) {
circle1 = {cx : d.cx, cy : d.cy, r : d.r};
if (detectcollision(circle1, circle2)) {
collision = true;
}
});
}
} while (collision);
circles.push(circle2);
return circles[circles.length - 1];
});
svgcontainer.selectall("circle")
.data(data)
.enter().append("circle")
.attr({
r : function (d) {
return d.r
},
cx : function (d) {
return d.cx
},
cy : function (d) {
return d.cy
},
fill : function (d, i) {
return color(i % 3)
}
});
function rand(min, max) {
return math.floor(math.random() * (max - min + 1)) + min;
}
})();
score:2
yes, you can achieve this by force layout. the idea is to keep all the links display none and center node display none none. something like this:
nodeenter.append("circle")
.style("display", function (d) {
return d.children ? "none" : ""; //ceneter node has children thus display will be none
})
in such a case it will just look like the visualization you want to have.
working code here
hope this helps!
score:7
i have made some updates to your fiddle and applied collision detection as in the demo i mentioned in the comment. hope this helps.
var angle, offset, data,
size = [8, 15],
width = 500,
color = d3.scale.category10(),
height = 600,
radius = 200,
dispersion = 10,
svgcontainer = d3.select('body').append("svg")
.attr("width", width)
.attr("height", height);
var force = d3.layout.force()
.gravity(0.05)
.charge(function(d, i) {
return i ? 0 : -2000;
})
.distance(500)
.size([width, height]);
data = d3.range(100).map(function() {
angle = math.random() * math.pi * 2;
offset = math.max(size[0], size[1]) + radius + dispersion;
return {
x: offset + math.cos(angle) * radius + rand(-dispersion, dispersion),
y: offset + math.sin(angle) * radius + rand(-dispersion, dispersion),
radius: rand(size[0], size[1])
};
});
force
.nodes(data)
.start();
root = data[0],
color = d3.scale.category10();
root.radius = 0;
root.fixed = true;
root.px = 250; //center x
root.py = 275; //center y
var nodes = svgcontainer.selectall("circle")
.data(data)
.enter().append("circle")
.attr({
r: function(d) {
return d.radius
},
cx: function(d) {
return d.x
},
cy: function(d) {
return d.y
},
fill: function(d, i) {
return color(i % 3)
}
});
force.on("tick", function(e) {
var q = d3.geom.quadtree(data),
i = 0,
n = data.length;
while (++i < n) q.visit(collide(data[i]));
svgcontainer.selectall("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
});
function rand(min, max) {
return math.floor(math.random() * (max - min + 1)) + min;
}
function collide(node) {
var r = node.radius + 16,
nx1 = node.x - r,
nx2 = node.x + r,
ny1 = node.y - r,
ny2 = node.y + r;
return function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== node)) {
var x = node.x - quad.point.x,
y = node.y - quad.point.y,
l = math.sqrt(x * x + y * y),
r = node.radius + quad.point.radius;
if (l < r) {
l = (l - r) / l * .5;
node.x -= x *= l;
node.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
edit:
do you mean something like this?
var angle, offset, data,
size = [8, 15],
width = 500,
color = d3.scale.category10(),
height = 600,
radius = 200,
dispersion = 10,
svgcontainer = d3.select('body').append("svg")
.attr("width", width)
.attr("height", height).append("g");
var force = d3.layout.force()
.gravity(0.05)
.charge(function(d, i) {
return i ? -20 : -2000;
})
.distance(500)
.size([width, height]);
data = d3.range(100).map(function() {
angle = math.random() * math.pi * 2;
offset = math.max(size[0], size[1]) + radius + dispersion;
return {
x: offset + math.cos(angle) * radius + rand(-dispersion, dispersion),
y: offset + math.sin(angle) * radius + rand(-dispersion, dispersion),
radius: rand(size[0], size[1])
};
});
force
.nodes(data)
.start();
root = data[0],
color = d3.scale.category10();
root.radius = 0;
root.fixed = true;
root.px = 250; //center x
root.py = 275; //center y
var nodes = svgcontainer.selectall("circle")
.data(data)
.enter().append("circle")
.attr({
r: function(d) {
return d.radius
},
cx: function(d) {
return d.x
},
cy: function(d) {
return d.y
},
fill: function(d, i) {
return color(i % 3)
}
});
var rotation = 0;
setinterval(function(){
if(force.alpha()==0){
if(!rotation)
rotation = math.random() * 50;
else
rotation = rotation+1;
svgcontainer.attr("transform","rotate("+rotation+", "+(width/2)+","+(height/2)+")");
}
//force.theta(0.5);
},250);
force.on("tick", function(e) {
var q = d3.geom.quadtree(data),
i = 0,
n = data.length;
while (++i < n) q.visit(collide(data[i]));
svgcontainer.selectall("circle")
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
});
function rand(min, max) {
return math.floor(math.random() * (max - min + 1)) + min;
}
function collide(node) {
var r = node.radius + 16,
nx1 = node.x - r,
nx2 = node.x + r,
ny1 = node.y - r,
ny2 = node.y + r;
return function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== node)) {
var x = node.x - quad.point.x,
y = node.y - quad.point.y,
l = math.sqrt(x * x + y * y),
r = node.radius + quad.point.radius;
if (l < r) {
l = (l - r) / l * .5;
node.x -= x *= l;
node.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
};
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Source: stackoverflow.com
Related Query
- How to draw circles around circular path with D3js
- How to draw circles with radii given in kilometers accurately on world map
- How to Draw rectangles at 0,45,90,135,180 degree so on around an SVG Circle with D3.js
- How to draw a diamond with the path "d" attribute?
- How to draw circles at different times with D3js?
- How can I draw rectangles with D3js which are placed like wall bricks structure?
- How to draw timeseries chart by month,year with d3js
- How to transition along a circular path with d3?
- D3 draw lines around a pie with a circular rotation
- d3js - How to update an existing svg path in a simple d3 line chart with new data flowing through?
- How to Stack circles using d3js with lable and values
- How to draw path with d3.js correctly?
- How to draw line with arrow using d3.js
- How to select a d3 svg path with a particular ID
- How to update an svg path with d3.js
- How to draw a path smoothly from start point to end point in D3.js
- How to draw a *simple* line segment with d3.js?
- D3: How to create a circular flow / Sankey diagram with 2 arcs
- How to draw logarithmic line charts with nvd3
- Path transition with gap - how do to that?
- how do you draw linear line in scatter plot with d3.js
- How to draw arc with d3.js with only outer radius, or sector of circle?
- How to replace a d3js nest function with group and rollup
- With D3, how can I set attribute ("fill", "none") of axis path and line, but not text (without editing stylesheet)
- How to Integrate a data-driven d3JS graph with Shiny?
- In R plotly d3js how to format a number with space instead of comma?
- How can I programmatically draw a nonlinear writing system with automatic graph relaxation (e.g. in d3.js)?
- Draw a map with D3.js: How to get the right scale() and translate()?
- How to get started with d3js examples using xampp?
- How can I choose a legible color to draw text on a bar in a d3js chart?
More Query from same tag
- Why does Svg path appears in console but not on screen?
- Links never show up
- D3 Transition Bar chart
- d3.js, how to draw multiple circles at the same (lat,long)?
- How to animate points, appearing one-by-one, in the window using JavaScript and D3?
- Dynamic color mapping
- SVG `<path>` Imprecision
- How to Set D3 Funnel Chart Label Legend
- Multiline chart d3 tooltip
- D3.js - Line Graph: Area path goes over x and y axis on zoom
- D3 multiple Axis interpolation
- D3 line generator only generating NaN values
- How can I add more time-series data after drawing a D3 line chart?
- D3 zoom callback
- Is it possible to add an svg element to an open layers map with D3?
- Resizing more than one svg graph on the same web page
- Can't select svg element with d3
- responsive D3 chart
- Bar Chart inside Stacked Bar Chart
- How to make D3.js path generator append two points?
- D3.js code not working for Creating circles based on data
- duplicating the whole svg element using d3.js
- Maximum width for column in bar chart
- How do I put a d3 chart into my chartBox?
- after making bar chart inside SVG using D3 , it is not fitting the entire SVG
- How to create a tooltip with custom value
- Loading csv data and save results to a variable
- Updating a Pie Chart in d3.js
- Compare two time objects in D3.js
- Passing D3 data to bootstrap modal dialog