d3 js - 将气泡聚集到线段 [英] d3 js - clustering bubbles to segments
问题描述
****最新版本 -
-
最新的小提琴。
http://jsfiddle.net/NYEaX/1505/
( http://jsfiddle.net/NYEaX/1506/) - refactored
1. - 如何为弧线设置动画
2. - 气泡
3. - 添加回随机化按钮以测试2个虚拟数据集。
这是旧派动画,效果非常好
/ * ------- ANIMATE PIE SLICES ------- * /
var slice = doughpie.select(。slices)。selectAll(path.slice)
.data(pie(data),key);
slice.enter()
.insert(path)
.style(fill,function(d){
return color(d.data .label);
})
.style(transform,function(d,i){
// returntranslate(0,0);
}
.attr(class,slice);
slice
.transition()。duration(1000)
.attrTween(d,function(d){
this._current = this._current | | d;
var interpolate = d3.interpolate(this._current,d);
this._current = interpolate(0);
return function(t){
return arc (interpolate(t));
};
})
slice.exit()
.remove
/ * ------- ANIMATE PIE SLICES ------- * /
$ b b//这是当前的饼圆 - 但是当我尝试以相同的方式对饼进行动画时,它会失败。
var g = svg.selectAll(。arc)
.data(pie(data))
.enter()。append(g)
.attr类,弧);
g.append(path)
.attr(d,arc)
.style(fill,function(d){
return color(d.data.label);
});
arc
.outerRadius(radius - 10)
.innerRadius(0);
**** LATEST FIDDLE --- https://jsfiddle.net/tk5xog0g/8/
-- 2nd fiddle with a custom chart -- randomly placing the bubbles closer to region zones but can not account for overlapping or falling off the central chart zone. http://jsfiddle.net/NYEaX/1484/
I want to combine a doughtnut pie and a bubble chart to produce an exact result like this
The closest I have got to - is here.
https://jsfiddle.net/tk5xog0g/10/
/* ------- ANIMATE BUBBLES -------*/ // generate data with calculated layout values var data = bubbledata(data); var nodes = bubble.nodes(data) .filter(function(d) { return !d.children; }); // filter out the outer bubble var bubbles = bubs.selectAll('circle') .data(nodes); bubbles.enter() .insert("circle") .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; }) .attr('r', function(d) { return d.r; }) .style("fill", function(d) { return color(d.group); }); bubbles = bubbles.transition() .transition() .duration(250) .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; }) .attr('r', function(d) { //console.log("dr", d.r) return d.r; }) .ease('sine'); /* ------- ANIMATE BUBBLES -------*/
I have also looked at trying to cluster the bubble chart to at least always group the colours together -- but this still won't match the required chart -- with the need for the colour bubbles to be close to the matching pie segments.
-- this is a clustered variant but the orange bubbles may sit sandwiched in the middle and once I try and merge it with the pie - won't correspond. I have considered trying to add a charge/gravity to try and get the bubbles to repel. https://jsfiddle.net/tk5xog0g/20/
- D3 Force Layout where larger nodes cluster in center
- d3 clustered force layout, distance between cluster center
- Adding new nodes to a clustered force layout
- d3.js: how to create "force-directed graph clusters"
https://bl.ocks.org/mbostock/7881887
var width = 960, height = 500, radius = Math.min(width, height) / 2; var color = d3.scale.ordinal() .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]); var arc = d3.svg.arc() .outerRadius(radius - 60) .innerRadius(radius - 70); var pie = d3.layout.pie() .sort(null) .value(function(d) { return d.value; }); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); var data = [ { "group": "<5", "value": 1000, "children": [ { "group": "<5", "label": "Mel", "value": 1000, "totalGroupValue": 1000 } ] }, { "group": "5-13", "value": 1000, "children": [ { "group": "5-13", "label": "Erica", "value": 1000, "totalGroupValue": 1000 } ] }, { "group": "14-17", "value": 2000, "children": [ { "group": "14-17", "label": "Jessica", "value": 1500, "totalGroupValue": 2000 }, { "group": "14-17", "label": "Jill", "value": 500, "totalGroupValue": 2000 } ] }, { "group": "18-24", "value": 1300, "children": [ { "group": "18-24", "label": "Jerry", "value": 500, "totalGroupValue": 1300 }, { "group": "18-24", "label": "Ben", "value": 500, "totalGroupValue": 1300 }, { "group": "18-24", "label": "Billy", "value": 300, "totalGroupValue": 1300 } ] }, { "group": "25-44", "value": 1000, "children": [ { "group": "25-44", "label": "Kelly", "value": 1000, "totalGroupValue": 1000 } ] } ]; var g = svg.selectAll(".arc") .data(pie(data)) .enter().append("g") .attr("class", "arc"); g.append("path") .attr("d", arc) .style("fill", function(d) { return color(d.data.group); }); arc .outerRadius(radius - 10) .innerRadius(0); //create zone regions var zones = []; g.append("circle") .attr("transform", function(d) { zones[d.data.group] = arc.centroid(d); //zones.push(obj); return "translate(" + arc.centroid(d) + ")"; }) .attr("r", "1px") .style("fill", function(d) { return "black"//color(d.data.group); }); //create zone regions //custom bubble chart function makeBubbles(transform, group, radius){ g.append("circle") .attr("transform", function(d) { return "translate("+transform+")"; }) .attr("r", radius) .style("stroke", function(d) { return "black";//color(group); }) .style("fill", function(d) { return color(group); }); } //loop through data and for EACH children array paint dots. $.each(data, function( index, value ) { $.each(value.children, function( i, v ) { var randomX = Math.floor(Math.random() * 101) - 50; var randomY = Math.floor(Math.random() * 101) - 50; var zoneregion = zones[v.group]; var transform = (zoneregion[0] - randomX)+","+(zoneregion[1]+randomY); var group = v.group; var radius = ((v.value/v.totalGroupValue)*100) *0.5; makeBubbles(transform, group, radius); }); }); //custom bubble chart function type(d) { d.value = +d.value; return d; }
.arc text { font: 10px sans-serif; text-anchor: middle; } .arc path { stroke: #fff; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <body>
解决方案Latest fiddle. http://jsfiddle.net/NYEaX/1505/
( http://jsfiddle.net/NYEaX/1506/ )- refactored
1. -- how to animate the arcs 2. -- how to animate the bubbles 3. -- adding back the randomise button to test with 2 dummy data sets.
this is the old pie animations and worked very well
/* ------- ANIMATE PIE SLICES -------*/ var slice = doughpie.select(".slices").selectAll("path.slice") .data(pie(data), key); slice.enter() .insert("path") .style("fill", function(d) { return color(d.data.label); }) .style("transform", function(d, i){ //return "translate(0, 0)"; }) .attr("class", "slice"); slice .transition().duration(1000) .attrTween("d", function(d) { this._current = this._current || d; var interpolate = d3.interpolate(this._current, d); this._current = interpolate(0); return function(t) { return arc(interpolate(t)); }; }) slice.exit() .remove(); /* ------- ANIMATE PIE SLICES -------*/
//this is the current pie arcs - but when I try and animate the pie in the same manner - it fails.
var g = svg.selectAll(".arc") .data(pie(data)) .enter().append("g") .attr("class", "arc"); g.append("path") .attr("d", arc) .style("fill", function(d) { return color(d.data.label); }); arc .outerRadius(radius - 10) .innerRadius(0);
这篇关于d3 js - 将气泡聚集到线段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!