I have an old doughnut hybrid pie chart/bubble chart combo working on d3v3.
//doughnut bubble chart v3 https://jsfiddle.net/ajevh5wf/
var $this = $('body');
var w = 300,
h = 300;
var radius = Math.min(w, h) / 2;
var svg = d3.select($this[0])
.append("svg")
.attr("width", w)
.attr("height", h)
.append("g")
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "placeholders");
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var arc = d3.svg.arc()
.outerRadius(radius * 0.85)
.innerRadius(radius * 0.83);
var arc2 = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var outerArc = d3.svg.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
svg.attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");
function colores_google(n) {
var colores_g = ["#f7b363", "#448875", "#c12f39", "#2b2d39", "#f8dd2f"];
return colores_g[n % colores_g.length];
}
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": 150,
"totalGroupValue": 1300
}, {
"group": "18-24",
"label": "Billy2",
"value": 150,
"totalGroupValue": 1300
}]
}, {
"group": "25-44",
"value": 1000,
"children": [{
"group": "25-44",
"label": "Kelly",
"value": 1000,
"totalGroupValue": 1000
}]
}];
$.each(data, function(index, value) {
value["groupid"] = index;
$.each(value.children, function(i, v) {
v["groupid"] = index;
});
});
//slices
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(data));
slice.enter()
.insert("path")
.style("fill", function(d) {
return colores_google(d.data.groupid);
})
.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();
//slices
//placeholder bubbles
var placeholders = svg.select(".placeholders").selectAll("g.placeholder")
.data(pie(data));
placeholders.enter()
.insert("g")
.attr("class", function(d, i) {
return "placeholder place" + i;
});
placeholders
.transition().duration(1000)
.attr("transform", function(d) {
return "translate(" + arc2.centroid(d) + ")";
})
placeholders.exit()
.remove();
//placeholder bubbles
//bubbles
function bubbledata(data) {
//loop through data -- and MERGE children
var childs = [];
$.each(data, function(index, value) {
childs.push(value.children);
});
return $.extend(true, {}, {
"children": data
}); // return deep clone
}
function setBubbleChart(width, index, data) {
//_create bubble
var diameter = width / 2; //take half/width
var bubs = svg.select(".place" + index).append("g")
.attr("class", "bubs");
bubs.attr("transform", "translate(" + -diameter / 2 + "," + -diameter / 2 + ")");
var bubble = d3.layout.pack()
.size([diameter, diameter])
.value(function(d) {
return d.value;
})
.padding(3);
//_create bubble
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 colores_google(d.groupid);
});
bubbles = bubbles.transition()
.transition()
.duration(250)
.attr('transform', function(d) {
return 'translate(' + d.x + ',' + d.y + ')';
})
.attr('r', function(d) {
return d.r;
})
.ease('sine');
}
//loop through data and for EACH children array paint dots.
$.each(data, function(index, value) {
setBubbleChart(100, index, value.children);
});
//custom bubble chart
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
//doughnut bubble chart v4 - not working https://jsfiddle.net/4rdj0fze/1/
var $this = $('body');
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": 150,
"totalGroupValue": 1300
}, {
"group": "18-24",
"label": "Billy2",
"value": 150,
"totalGroupValue": 1300
}]
}, {
"group": "25-44",
"value": 1000,
"children": [{
"group": "25-44",
"label": "Kelly",
"value": 1000,
"totalGroupValue": 1000
}]
}];
var width = 300,
height = 300;
var color = d3.scaleOrdinal()
.range(["#eb6383", "#fa9191", "#ffe9c5", "#b4f2e1"]);
var margin = {
top: 20,
right: 5,
bottom: 30,
left: 20
},
width = width - margin.left - margin.right,
height = height - margin.top - margin.bottom;
var svg = d3.select($this[0])
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr('class', 'doughnutbubblechart')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var doughnutbubble = svg.append('g').attr('class', 'doughnutbubble');
var radius = Math.min(width, height) / 2;
doughnutbubble.append("g")
.attr("class", "slices");
doughnutbubble.append("g")
.attr("class", "placeholders");
var pie = d3.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var arc = d3.arc()
.outerRadius(radius * 0.85)
.innerRadius(radius * 0.83);
var arc2 = d3.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var outerArc = d3.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
doughnutbubble.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
function colores_google(n) {
var colores_g = ["#f7b363", "#448875", "#c12f39", "#2b2d39", "#f8dd2f"];
return colores_g[n % colores_g.length];
}
$.each(data, function(index, value) {
value["groupid"] = index;
$.each(value.children, function(i, v) {
v["groupid"] = index;
});
});
//slices
var slice = doughnutbubble.select(".slices").selectAll("path.slice")
.data(pie(data));
slice.enter()
.insert("path")
.style("fill", function(d) {
return colores_google(d.data.groupid);
})
.attr("class", "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();
//slices
//placeholder bubbles
var placeholders = doughnutbubble.select(".placeholders").selectAll("g.placeholder")
.data(pie(data));
placeholders.enter()
.insert("g")
.attr("class", function(d, i) {
return "placeholder place" + i;
})
.transition().duration(1000)
.attr("transform", function(d) {
return "translate(" + arc2.centroid(d) + ")";
})
placeholders.exit()
.remove();
//placeholder bubbles
//bubbles
function bubbledata(data) {
//loop through data -- and MERGE children
var childs = [];
$.each(data, function(index, value) {
childs.push(value.children);
});
return $.extend(true, {}, {
"children": data
}); // return deep clone
}
function setBubbleChart(width, index, data) {
//_create bubble
var diameter = width / 2; //take half/width
var bubs = doughnutbubble.select(".place" + index).append("g")
.attr("class", "bubs");
bubs.attr("transform", "translate(" + -diameter / 2 + "," + -diameter / 2 + ")");
//var data = bubbledata(data);
//console.log("data", data);
///
var force = d3.forceSimulation();
var foci = {
x: 150,
y: 150
}
var data = funnelData(data, width, height)
.map(function(d) {
d.foci = foci;
return d;
})
force.nodes(data);
var bubbles = bubs.append("g")
.attr("class", "bubbles")
var nodes = bubbles.selectAll("circle")
.data(data)
.enter()
.append('circle')
.attr('r', 1)
.attr('fill', function(d, i) {
return color(i);
});
// Update
nodes.transition()
.delay(300)
.duration(1000)
.attr("r", function(d) {
return d.value * (width / 6) / 100;
});
force.on("tick", function() {
data.forEach(cluster);
data.forEach(collide(0.1));
nodes.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
});
function funnelData(data, width, height) {
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var max_amount = d3.max(data, function(d) {
return parseInt(d.value)
})
var radius_scale = d3.scalePow().exponent(0.5).domain([0, max_amount]).range([2, 85])
data.forEach(function(elem, index) {
elem.radius = radius_scale(elem.value) * .8;
elem.all = 'all';
elem.x = getRandom(0, width);
elem.y = getRandom(0, height);
});
return data;
}
function cluster(d, i) {
var f = d.foci;
var k = 0.55;
d.y += (f.y - d.y) * k * force.alpha()
d.x += (f.x - d.x) * k * force.alpha()
}
var maxRadius = d3.max(data, function(d) {
return d.radius;
})
var padding = 4;
function collide(alpha) {
var quadtree = d3.quadtree().x(function(d) {
return d.x;
}).y(function(d) {
return d.y;
}).extent([
[-1, -1],
[width + 1, height + 1]
]).addAll(data);
return function(d) {
var r = d.radius + maxRadius + padding,
nx1 = d.x - r,
nx2 = d.x + r,
ny1 = d.y - r,
ny2 = d.y + r;
quadtree.visit(function(quad, x1, y1, x2, y2) {
if (!quad.length && (quad.data !== d)) {
var x = d.x - quad.data.x,
y = d.y - quad.data.y,
l = Math.sqrt(x * x + y * y),
r = d.radius + quad.data.radius + padding;
if (l < r) {
l = (l - r) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
quad.data.x += x;
quad.data.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
});
};
}
}
//loop through data and for EACH children array paint dots.
$.each(data, function(index, value) {
setBubbleChart(100, index, value.children);
});
//custom bubble chart
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
---bubblechart v4 working - https://jsfiddle.net/of48xjar/
but when I try and add this bubblechartv4 code to the base v4 -- I can't seem to get the bubbles to render properly in the placeholders or the sizes -- and I think in the old version3 had to exclude the parent level to ensure it just renders children bubbles.
from Doughnut pie hybrid d3 version 4
No comments:
Post a Comment