Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
80
rated 0 times [  83] [ 3]  / answers: 1 / hits: 19376  / 11 Years ago, fri, february 14, 2014, 12:00:00

I'm working on a pie chart mock. That I need to try and match the designs to have the label extruding out with a horizontal line attached to the slice ticks. Is this possible? It would be a bonus to have the black dots form on the segments.



Pie



http://jsfiddle.net/BxLHd/15/



Here is the code for the tick marks. Would it be a case of creating another set of lines that intersect?



                        //draw tick marks
var label_group = d3.select('#'+pieId+' .label_group');
lines = label_group.selectAll(line).data(filteredData);
lines.enter().append(svg:line)
.attr(x1, 0)
.attr(x2, 0)
.attr(y1, function(d){
if(d.value > threshold){
return -that.r-3;
}else{
return -that.r;
}
})
.attr(y2, function(d){
if(d.value > threshold){
return -that.r-8;
}
else{
return -that.r;
}
})
.attr(stroke, gray)
.attr(transform, function(d) {
return rotate( + (d.startAngle+d.endAngle)/2 * (180/Math.PI) + );
});

lines.transition()
.duration(this.tweenDuration)
.attr(transform, function(d) {
return rotate( + (d.startAngle+d.endAngle)/2 * (180/Math.PI) + );
});

lines.exit().remove();

More From » d3.js

 Answers
20

To conclude I've wrapped the very latest code for this in a jquery plugin. Its now possible to develop multiple pie charts with these labels.



LATEST CODE - ** http://jsfiddle.net/Qh9X5/1336/ - removes label properly on exit.



enter



$(document).ready(function() {


(function( $ ){
var methods = {
el: ,
init : function(options) {
var clone = jQuery.extend(true, {}, options[data]);

methods.el = this;
methods.setup(clone, options[width], options[height], options[r], options[ir]);
},
getArc: function(radius, innerradius){
var arc = d3.svg.arc()
.innerRadius(innerradius)
.outerRadius(radius);

return arc;
},
setup: function(dataset, w, h, r, ir){

var padding = 80;

this.width = w;
this.height = h;
this.radius = r
this.innerradius = ir;

this.color = d3.scale.category20();

this.pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.total; });

this.arc = this.getArc(this.radius, this.innerradius);

this.svg = d3.select(methods.el[selector]).append(svg)
.attr(width, this.width + padding)
.attr(height, this.height + padding)
.append(g)
.attr(class, piechart)
.attr(transform, translate( + ((this.width/2) + (padding/2)) + , + ((this.height/2) + (padding/2)) + ));

this.segments = this.svg.append(g)
.attr(class, segments);

this.labels = this.svg.append(g)
.attr(class, labels);

this.pointers = this.svg.append(g)
.attr(class, pointers);


},
oldPieData: ,
pieTween: function(r, ir, d, i){
var that = this;

var theOldDataInPie = methods.oldPieData;
// Interpolate the arcs in data space

var s0;
var e0;

if(theOldDataInPie[i]){
s0 = theOldDataInPie[i].startAngle;
e0 = theOldDataInPie[i].endAngle;
} else if (!(theOldDataInPie[i]) && theOldDataInPie[i-1]) {
s0 = theOldDataInPie[i-1].endAngle;
e0 = theOldDataInPie[i-1].endAngle;
} else if(!(theOldDataInPie[i-1]) && theOldDataInPie.length > 0){
s0 = theOldDataInPie[theOldDataInPie.length-1].endAngle;
e0 = theOldDataInPie[theOldDataInPie.length-1].endAngle;
} else {
s0 = 0;
e0 = 0;
}

var i = d3.interpolate({startAngle: s0, endAngle: e0}, {startAngle: d.startAngle, endAngle: d.endAngle});

return function(t) {
var b = i(t);
return methods.getArc(r, ir)(b);
};
},
removePieTween: function(r, ir, d, i) {
var that = this;
s0 = 2 * Math.PI;
e0 = 2 * Math.PI;
var i = d3.interpolate({startAngle: d.startAngle, endAngle: d.endAngle}, {startAngle: s0, endAngle: e0});

return function(t) {
var b = i(t);
return methods.getArc(r, ir)(b);
};
},
update: function(dataSet){
var that = this;

methods.el = this;
var r = $(methods.el[selector]).data(r);
var ir = $(methods.el[selector]).data(ir);

methods.svg = d3.select(methods.el[selector] + .piechart);

methods.segments = d3.select(methods.el[selector] + .segments);
methods.labels = d3.select(methods.el[selector] + .labels);
methods.pointers = d3.select(methods.el[selector] + .pointers);

dataSet.forEach(function(d) {
d.total = +d.value;
});

this.piedata = methods.pie(dataSet);

//__slices
this.path = methods.segments.selectAll(path.pie)
.data(this.piedata);

this.path.enter().append(path)
.attr(class, pie)
.attr(fill, function(d, i) {
return methods.color(i);
})
.transition()
.duration(300)
.attrTween(d, function(d, i) {
return methods.pieTween(r, ir, d, i);
});

this.path
.transition()
.duration(300)
.attrTween(d, function(d, i) {
return methods.pieTween(r, ir, d, i);
});

this.path.exit()
.transition()
.duration(300)
.attrTween(d, function(d, i) {
return methods.removePieTween(r, ir, d, i);
})
.remove();
//__slices


//__labels
var labels = methods.labels.selectAll(text)
.data(this.piedata);

labels.enter()
.append(text)
.attr(text-anchor, middle)


labels
.attr(x, function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cx = Math.cos(a) * (ir+((r-ir)/2));
return d.x = Math.cos(a) * (r + 20);
})
.attr(y, function(d) {
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
d.cy = Math.sin(a) * (ir+((r-ir)/2));
return d.y = Math.sin(a) * (r + 20);
})
.text(function(d) {
return d.data.label;
})
.each(function(d) {
var bbox = this.getBBox();
d.sx = d.x - bbox.width/2 - 2;
d.ox = d.x + bbox.width/2 + 2;
d.sy = d.oy = d.y + 5;
})
.transition()
.duration(300)

labels
.transition()
.duration(300)

labels.exit()
.transition()
.duration(300)
//__labels


//__pointers
methods.pointers.append(defs).append(marker)
.attr(id, circ)
.attr(markerWidth, 6)
.attr(markerHeight, 6)
.attr(refX, 3)
.attr(refY, 3)
.append(circle)
.attr(cx, 3)
.attr(cy, 3)
.attr(r, 3);

var pointers = methods.pointers.selectAll(path.pointer)
.data(this.piedata);

pointers.enter()
.append(path)
.attr(class, pointer)
.style(fill, none)
.style(stroke, black)
.attr(marker-end, url(#circ));

pointers
.attr(d, function(d) {
if(d.cx > d.ox) {
return M + d.sx + , + d.sy + L + d.ox + , + d.oy + + d.cx + , + d.cy;
} else {
return M + d.ox + , + d.oy + L + d.sx + , + d.sy + + d.cx + , + d.cy;
}
})
.transition()
.duration(300)

pointers
.transition()
.duration(300)

pointers.exit()
.transition()
.duration(300)

//__pointers

this.oldPieData = this.piedata;

}
};

$.fn.piechart = function(methodOrOptions) {
if ( methods[methodOrOptions] ) {
return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {
// Default to init
return methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + methodOrOptions + ' does not exist' );
}
};

})(jQuery);



var dataCharts = [
{
data: [
{
segments: [
{
label: apple,
value: 53245
},
{
label: cherry,
value: 145
},
{
label: pear,
value: 2245
},
{
label: bananana,
value: 15325
}
]
}
]
},
{
data: [
{
segments: [
{
label: milk,
value: 532
},
{
label: cheese,
value: 145
},
{
label: grapes,
value: 22
}
]
}
]
},
{
data: [
{
segments: [
{
label: pineapple,
value: 1532
},
{
label: orange,
value: 1435
},
{
label: grapes,
value: 22
}
]
}
]
},
{
data: [
{
segments: [
{
label: lemons,
value: 133
},
{
label: mango,
value: 435
},
{
label: melon,
value: 2122
}
]
}
]
}
];

var clone = jQuery.extend(true, {}, dataCharts);

//__invoke concentric
$('[data-role=piechart]').each(function(index) {
var selector = piechart+index;

$(this).attr(id, selector);

var options = {
data: clone[0].data,
width: $(this).data(width),
height: $(this).data(height),
r: $(this).data(r),
ir: $(this).data(ir)
}

$(#+selector).piechart(options);
$(#+selector).piechart('update', clone[0].data[0].segments);
});


$(.testers a).on( click, function(e) {
e.preventDefault();

var clone = jQuery.extend(true, {}, dataCharts);

var min = 0;
var max = 3;

//__invoke pie chart
$('[data-role=piechart]').each(function(index) {
pos = Math.floor(Math.random() * (max - min + 1)) + min;
$(#+$(this).attr(id)).piechart('update', clone[pos].data[0].segments);
});

});

});

[#72531] Wednesday, February 12, 2014, 11 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
dantel

Total Points: 7
Total Questions: 102
Total Answers: 97

Location: Saint Lucia
Member since Sat, Jun 6, 2020
4 Years ago
;