Hi Sevil,
Impressive work reverse-engineering dc.js without looking at
the documentation. ;-) I guess you leaned on autocomplete to figure this out, but there are clean APIs to do the same stuff.
There is one conceptual problem with your approach: in general, the names of items in different charts will not be unique, and it would be messy to search all the charts to find out where a tag came from.
So, in my solution I chose to create one Tagify instance per chart.
Rather than listening to clicks, the nicer way to watch filter changes is chart.on('filtered', chart => ...), and to read filters it's
chart.filters():
sidewaysRow.on('filtered', chart => filternamelist(chart, tagifyRow));
typePie.on('filtered', chart => filternamelist(chart, tagifyPie));
function filternamelist(chart, tagify) {
chart.__updating = true;
var obji = [];
if (chart.filters() && chart.filters().length > 0) {
for (const f of chart.filters()) {
if (!obji.includes(f)) {
obji.push(f);
}
}
}
tagify.removeAllTags();
tagify.addTags(obji);
chart.__updating = false;
}
Looking at
the Tagify docs, the best way to watch changes is element
.addEventListener('change', e => ...), and we can modify a chart's filters with replaceFilter:
rowTags.addEventListener('change', e => onChangeTags(sidewaysRow, e));
pieTags.addEventListener('change', e => onChangeTags(typePie, e));
function onChangeTags(chart, event) {
if(chart.__updating) return;
console.log('change tags', event.target.value);
const filters = event.target.value ? JSON.parse(event.target.value).map(({value}) => value) : null;
chart.replaceFilter(filters).redrawGroup();
}
Note that we have to check if we are the one changing the tags, with chart.__updating, since Tagify will fire events when removeAllTags and addTags are called, and we don't want to go into an infinite loop.
Deepak is working on adding a similar feature to dc@5. He is doing an ambitious rewrite, so it may be a while before this is released.
Cheers,
Gordon