There are several things to fix:
JavaScript first assigns objects by reference. This means that after
var fKeys = keys;
both fKeys and keys point to the same array. This is not what you want. You want to copy something, for example:
var fKeys = keys.slice();
Then your legendItem "click" handler was wrong because it does not switch the selected item. What you want is something like
.on('click', function (keyToToggle) {
Next, you want to use key fuction when you call data to get stackedBars . This is important because otherwise the data will be bound by the index and the last piece of data will always be deleted.
var stackedData = d3.stack().keys(fKeys)(dataset); var stackedBars = g .selectAll(".d3-group") .data(stackedData , function (__data__, i, group) { return __data__.key; });
And finally, when you update '.d3-rect' , you want to call data again, since the child nodes cache the data from the last draw, and you want to override it with new data.
stackedBars.selectAll('.d3-rect') .data(function (d) { return d;
Without such a call, hiding the first piece of data ("Vodafone") will not cause other stacked pieces to move.
There are also a few too large global variables (i.e. too few var s) and a few unnecessary variables.
Refresh (autoscale y)
If you also want to update the Y-scale, you move var stackedData higher into the redraw code so that you can use it to calculate your y as follows
var stackedData = d3.stack().keys(fKeys)(dataset); var autoScaleY = true;
You can find all the code in the plug of your original violin .