this time I am trying to create a stacked bar with toggleable series- based on Mike Bostock's example (thanks once more Mike!) I have already succeeded into making it responsive and zoomable, and the toggleable series through a legend is the last thing remaining.
I created the legend items, and applied the correct color by using keys:
var legendItem = d3.select(".legend")
.selectAll("li")
.data(keys)
.enter()
.append("li")
.on('click', function(d) {
keys.forEach(function(c) {
if (c != d) tKeys.push(c)
});
fKeys = tKeys;
tKeys = [];
redraw();
});
legendItem
.append("span")
.attr("class", "color-square")
.style("color", function(d) {
return colorScale5(d);
});
legendItem
.append("span")
.text(function(d) {
return (d)
});
Based on the structure, in order to create the toggleable item, I came to the conclusion that I somehow have to be able to toggle it from the keys AND the dataset - or is there another way to do it? I have managed to remove a specific key from the keys, but not from the dataset, I have no idea how to map it properly.
The second issue is that I can't figure of a way to toggle a key, but just remove it. This is the original dataset:
var data = [{
"country": "Greece",
"Vodafone": 57,
"Wind": 12,
"Cosmote": 20
}, {
"country": "Italy",
"Vodafone": 40,
"Wind": 24,
"Cosmote": 35
}, {
"country": "France",
"Vodafone": 22,
"Wind": 9,
"Cosmote": 9
}]
In the values were provided from a nested dataset, I could attach a key named 'enabled' to each object and could easily filter the dataset, but can't figure out how to attach a key to help in the filtering proccess.
edit3 Removed useless information from the question:
Here is a working fiddle: https://jsfiddle.net/fgseaxoy/2/
SergGr's code works well, but some parts can be cleaner.
var fKeys = keys.slice();
//a helper object to record the state of keys
var fKeyReference = fKeys.map(function () {
return true; //used to indicate if the corresponding key is active
});
function getActiveKeys(reference) {
return reference.map(function (state, index) {
if (state) {
return keys[index]; //just keep keys whoes state is true
}
return false; //return false to be filered
}).filter(function (name) {
return name
});
}
...
.on('click', function (d) {
if (fKeys.length === 1 && fKeys[0] === d) {
return;
}
var index = keys.indexOf(d);
fKeyReference[index] = !fKeyReference[index]; // toggle state of fKeyReference
fKeys = getActiveKeys(fKeyReference);
redraw();
});
g.selectAll(".d3-group").remove();//remove all groups and draw them all again
stackedBars = g
.selectAll(".d3-group")
.data(d3.stack().keys(fKeys)(dataset));
y.domain
)y.domain([
0,
1.2 * d3.max(dataset, function (d) {
return fKeys.reduce(function (pre, key) {//calculate the sum of values of fKeys
return pre + d[key];
}, 0);
})
]);
And finally, jsfiddle