Reputation: 497
I have several rowcharts that are connected to each other with dc.js. These rowcharts have the x axis at the top in a different div, as explained here. However these rowcharts also implement filtering and removing, therefore, whenever I filter in one rowchart, the number of bars in the others reduce, but it maintains the size of the scrollable div, even though there are no bars below what is shown. Also, I'm pretty sure it is easy, but I haven't figured out how to put the reset button below the chart, because it shows between the chart div and the axis div, as seen below.
Is there a way to correct these issues?
This is what I have in each rowchart div:
<div id='axis'></div>
<div id="chart" style="overflow-y:auto; height:200px;">
<div>
<span class="reset" style="display: none;">Phylum seleccionado(s):
<span class="filter"></span>
<a class="reset" href="javascript:Chart.filterAll();dc.redrawAll();" style="display">Reset</a>
</span>
</div>
</div>
And this is what a I have in each rowchart in the main.js:
Chart
.fixedBarHeight(20)
.height(nonEmpty.all().length * 20 + 1)
.margins({top: 0, right: 20, bottom: 0, left: 20})
.width(600)
.xAxis(d3.axisTop())
.elasticX(true)
.ordinalColors(['#e41a1c'])
.gap(1)
.dimension(Dim)
.group(nonEmpty) //this removes the ones that don't match the filter of the other rowchart
.on('pretransition', function () {
Chart.select('g.axis').attr('transform', 'translate(0,0)');
Chart.selectAll('line.grid-line').attr('y2', Chart.effectiveHeight());
});
Upvotes: 4
Views: 265
Reputation: 20120
Partial answer here. Well, it answers what you asked but doesn't answer the next question I expect. :(
You are currently sizing the chart based on the number of bars, and you will need to resize the chart when the number of bars change.
This should be done in a preRedraw
handler, but unfortunately preRedraw is currently fired after resizing is done. So currently you have to override .redraw()
:
dc.override(chart, 'redraw', function() {
chart.height(chart.group().all().length * 21);
return chart._redraw();
})
As for putting the info & controls after the chart, there are two issues and I was only able to solve one of them.
dc.js will append an svg
element to the chart div. It'd be nice to have more control over this but I'm not sure what to do. For the moment, the easiest workaround is to re-append the info div:
chart.on('postRender', function() {
chart.root().node().appendChild(chart.select('div.info').node())
})
However, what you really want is probably to pull the info div out of the scrolling div, and I can't figure that out at the moment. The problem is that the chart expects the controls/info to be inside the chart div, and that's the same one that needs to scroll.
I tried to mess around with adding another scrolling div inside the chart div, and then moving the svg under it. This works, but it creates some annoying flashing.
Here's what I got so far. I may return to this later if I think of a better solution.
To solve this right, we need the controls outside of the chart div.
We can port baseMixin.turnOnControls to a filtered
event handler, and do the same showing and populating that the chart would do:
function turnOnControls(_chart, controls) {
var attribute = _chart.controlsUseVisibility() ? 'visibility' : 'display';
controls.selectAll('.reset').style(attribute, null);
controls.selectAll('.filter').text(dc.printers.filters(_chart.filters())).style(attribute, null);
}
function turnOffControls(_chart, controls) {
var attribute = _chart.controlsUseVisibility() ? 'visibility' : 'display';
var value = _chart.controlsUseVisibility() ? 'hidden' : 'none';
controls.selectAll('.reset').style(attribute, value);
controls.selectAll('.filter').style(attribute, value).text(_chart.filter());
}
function filter_function(controls) {
return chart => {
chart.hasFilter() ?
turnOnControls(chart, controls) :
turnOffControls(chart, controls);
}
}
chart.on('filtered', filter_function(d3.select('#info')));
Also, controlsUseVisibility and visibility: hidden
is better when the controls will affect layout when shown/hidden.
Upvotes: 1