By logging the data that you're charting, you can see that the code is called for 6 items. If you add category
to the label, you can see that legends are being created for items from Men and Women:

You should debug the data structure that is actually generating labels.
http://jsfiddle.net/xmufd8t0/1/ shows this inside the console:

There appears to be an issue with how you use this loop: you always take the final element in e.series.data
. If you want the first non-empty fname
, you should have a break;
after setting legendName
. Otherwise it takes the last item in the array that is non-empty.
Anyway - to answer your question, you need to dedupe as @honerlawd mentioned in his comment. Here's the deduplication fix:
// outside your function, where you have `debugger`
var dedupes = {};
....
// skip labels that have already been added
if (dedupes.hasOwnProperty(legendName)) {
return;
}
dedupes[legendName] = 1;