Reputation: 421
I've looked through similar questions but still can't implement code correctly.
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 percentageFormat = d3.format("%");
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.values;
});
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
d3.json("staff.json", function(error, json_data) {
var data = d3.nest()
.key(function(d) {
return d.Position;
})
.rollup(function(d) {
return d.length;
}).entries(json_data);
data.forEach(function(d) {
d.percentage = d.values / json_data.length;
});
console.log("data variable", data);
console.log("pie(data)", pie(data));
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc")
.on('mouseover', function() {
var current = this;
var others = svg.selectAll(".arc").filter(function(el) {
return this != current
});
others.selectAll("path").style('opacity', 0.8);
})
.on('mouseout', function() {
var current = this;
d3.select(this)
.style('opacity', 1);
var others = svg.selectAll(".arc").filter(function(el) {
return this != current
});
others.selectAll("path").style('opacity', 1);
});
g.append("path")
.attr("d", arc)
.style("fill", function(d, i) {
return color(i);
});
g.append("text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")";
})
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) {
console.log("d is", d);
return percentageFormat(d.data.percentage);
});
Here's a JSON-file:
[{
"Position" : "Programmer",
"Name" : "Giacomo Gulizzoni",
"Age" : 37,
"Sex" : "Male",
"Project" : "SmartFactory"
}, {
"Position" : "Tester",
"Name" : "Marko Botton",
"Age" : 34,
"Sex" : "Male",
"Project" : "SmartFactory"
}, {
"Position" : "Tester",
"Name" : "Mariah Maclachian",
"Age" : 37,
"Sex" : "Female",
"Project" : "SmartFactory"
}, {
"Position" : "Tester",
"Name" : "Valerie Liberty",
"Age" : 25,
"Sex" : "Female",
"Project" : "SmartProject"
}, {
"Position" : "Programmer",
"Name " : "Guido Jack Gulizzoni",
"Age" : 22,
"Sex" : "Male",
"Project" : "SmartProject"
}]
Actually, legends are just rectangles that are bound to data if I'm not mistaken. But in my case items in JSON file are not numerical values. Have look at my plunk for the results of my experiments.
Upvotes: 1
Views: 1796
Reputation: 1796
Actually it was in your code,
var legend = svg.selectAll('.legend') // NEW
.data(pie(data)) // NEW
.enter() // NEW
.append('g') // NEW
.attr('class', 'legend') // NEW
.attr('transform', function(d, i) { // NEW
var height = legendRectSize + legendSpacing; // NEW
var offset = height * pie(data).length / 2; // NEW
var horz = -2 * legendRectSize; // NEW
var vert = i * height - offset; // NEW
return 'translate(' + horz + ',' + vert + ')'; // NEW
});
legend.append('rect') // NEW
.attr('width', legendRectSize) // NEW
.attr('height', legendRectSize) // NEW
.style('fill', function(d,i){return color(i);}) // NEW
.style('stroke', function(d,i){return color(i);}); // NEW
legend.append('text') // NEW
.attr('x', legendRectSize + legendSpacing) // NEW
.attr('y', legendRectSize - legendSpacing) // NEW
.text(function(d) { console.log("text: ");console.log(d);return d.data.key; });
I've un commented and did little changes. You can observe the code.
Upvotes: 0
Reputation: 32327
In your code:
You are setting the data in the legend selection wrong
var legend = ...
.data(pie(data))//this is wrong
.enter().append("g")
You need to do like this
var legend = d3.select("body").append("svg")
.attr("class", "legend")
.selectAll("g")
.data(data)//setting the data as we know there are only two set of data[programmar/tester] as per the nest function you have written
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", function(d, i) {
return color(d.key);
});
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.text(function(d) { return d.key; });
Working code here
Hope this helps!
Upvotes: 2