I'm new to d3js, but am familiar with javascript and the principles of data-visualisation.
I've tried to achieve an effects to visualize 2 dimensions of data using the aster plot diagram, but can't really get this thing to work like expected.
Attached you'll find the diagram I'm trying to recreate and my example code. It would be huge if you could tell me how to get it working - or how to optimize it! :)
D3JS - Aster Plot Preview
This is how I think the data and the code should look like.. kinda.. (Pseudo-Code incoming..)
Data Example:
var testData = {
maxPoints: 10,
color: '#bababa',
border: {
width: 1,
color: '#ffffff'
},
items: [
{
name: 'Looks',
color: '#2976dd',
weight: 0.37,
points: 8
},{
name: 'Charm',
color: '#87bd24',
weight: 0.03,
points: 5
},{
name: 'Honesty',
color: '#406900',
weight: 0.16,
points: 7
},{
name: 'Humour',
color: '#ffb200',
weight: 0.31,
points: 9
},{
name: 'Intelligence',
color: '#f78200',
weight: 0.12,
points: 0
}
]
};
Code Example:
var archs = [];
// Loop through each item
var circleRadius = 400;
var innerRadius = 100;
var startAngle = 0;
var endAngle = 0;
for (var i = 0; i < testData.items.length; i++) {
// Draw each arch
var maxPoints = testData.maxPoints;
var archHeight = (circleRadius - innerRadius) / maxPoints;
var startRadius = innerRadius;
endAngle += testData.items[i].weight;
for (var j = 0; j < maxPoints; j++) {
var color = testData.color;
// draw arch - don't know how to colorize accordingly..
if (testData.items[i].points < j) {
// color this arc somehow..
color = testData.items[i].color;
}
d3.svg.arc()
.startAngle(startAngle)
.endAngle(endAngle)
.innerRadius(startRadius)
.outerRadius(startRadius+archHeight);
// Increase startRadius
startRadius += archHeight;
}
// Increase startAngle
startAngle = endAngle;
}
Somehow my code looks way more complicated.. Though it's still pseudo-code.. I'm still struggling.. If someone could give me a hint or some working code to start from I would be very thankful!
Thanks in advance - Chris
Here's a quick implementation which replicates your diagram. It essentially builds concentric donut charts based on weight and then colors the slices based on points:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.arc path {
stroke: #fff;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var testData = {
maxPoints: 10,
color: '#bababa',
border: {
width: 1,
color: '#ffffff'
},
items: [{
name: 'Looks',
color: '#2976dd',
weight: 0.37,
points: 8
}, {
name: 'Charm',
color: '#87bd24',
weight: 0.03,
points: 5
}, {
name: 'Honesty',
color: '#406900',
weight: 0.16,
points: 7
}, {
name: 'Humour',
color: '#ffb200',
weight: 0.31,
points: 9
}, {
name: 'Intelligence',
color: '#f78200',
weight: 0.12,
points: 0
}]
};
var width = 500,
height = 500;
color = d3.scale.category20();
// inner radius
var iR = 75,
// radius of each concentric arc
r = ((Math.min(width, height) / 2) - iR) / testData.maxPoints;
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.weight;
})
.padAngle(.01);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var g = svg.selectAll(".arc")
.data(pie(testData.items))
.enter().append("g")
.attr("class", "arc");
// iterate our number of rings
d3.range(testData.maxPoints)
.forEach(function(i){
// generate an arc
var arc = d3.svg.arc()
.outerRadius(r * (i + 1) + iR)
.innerRadius(r * i + iR);
// fill it, if appropriate
g.append("path")
.attr("d", arc)
.style("fill", function(d) {
if (i < d.data.points)
return color(d.data.name);
else
return "#eee"
});
});
</script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With