Search code examples
javascripthtmlcssd3.jsdc.js

Dc.js conflicts with Bootstrap styles on rowchart


I'm building a dashboard using dc.js/d3.js/crossfilter/bootstrap but I'm stuck on building a row chart.

The problem is that all the rows of the chart are rendering with the same length, even when the group is being calculated correctly and their values are distincts (4/3/1) (you can check it doing groupB.all() on terminal).

The source of the problem, which I found out after multiple headaches, is that bootstrap's styles overrides rect tags width. See the pictures where the problem goes away unchecking the width attribute on the .row>* selector's class.

I couldn't solve this. I tried writing styles to override it using width: revert, width: auto, width: initial and even tried using jQuery to remove that attribute after render, but cannot get it to work. It seems that none of these methods are exactly the same than unchecking the attribute definition on Chrome inspector.

I can't change any library version due it is a large project and has other dashboards already built with this same stack.

Here is the jsfiddle with the exact same scenario.

enter image description here

enter image description here


Solution

  • I am afraid that a workaround is only available in a recent version of the library.

    If you can't update the version of the dc.js library you are using, you could try removing the conflicting class and provide a different one instead.

    For example, taking as reference your fiddle, please, try the following:

    const data = [
        {author: "email1", otherField: "asd1"},
        {author: "email1", otherField: "asd2"},
      {author: "email2", otherField: "asd3"},
      {author: "email1", otherField: "asd4"},
      {author: "email3", otherField: "asd5"},
      {author: "email3", otherField: "asd6"},
      {author: "email3", otherField: "asd7"},
      {author: "email3", otherField: "asd8"},
    ]
    var ndx = crossfilter(data)
    
    var dimAuthor = ndx.dimension(function(d){ return d.author })
    var groupB = dimAuthor.group().reduceCount()
    
    var chartB = new dc.RowChart("#chart-b");
    
    chartB
        .height(500)
      .width(600)
      .margins({top: 20, right: 50, bottom: 10, left: 45})
      .dimension(dimAuthor)
      .group(groupB)
      .label(function (d){
        return `${d.key} (${d.value})`;
      })
      .ordering(function(d){ return -d.value; })
      .x(d3.scaleLinear().domain([6,500]))
      .xAxis(d3.axisTop())
      .elasticX(true)
    
    dc.renderAll();
    
    // Remove the 'row' class and use for example 'dc-row' instead
    
    d3.selectAll(".dc-chart  g.row")
      .classed("row", false)
      .classed("dc-row", true);
    

    As you can notice, I copied and pasted the whole javascript fragment you. published, but these lines are the only necessary:

    d3.selectAll(".dc-chart  g.row")
      .classed("row", false)
      .classed("dc-row", true);
    

    You probably still will need to tweak the chart styles but at least they will have the right width. For example, consider including the following:

    .dc-chart g.dc-row rect {
        fill-opacity: .8;
        cursor: pointer;
    }