Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DC JS : How to highlight rows in an aggregated data table on click, similar to a row chart?

Tags:

d3.js

dc.js

I love the DC.JS library and have been trying to create a clickable aggregated table in DC.js with partial success. I want to highlight the rows on click event(multiple selections allowed) similar to the row chart or an ordinal bar chart in dc js. Like a row chart, when multiple selections are made, multiple table rows should be highlighted.

I am not able to select the row that I have clicked on, rather, my css selects the first row irrespective of which row I click. I tried to use 'this' keyword to select the current row that was clicked but to no avail.

Here's the js fiddle: https://jsfiddle.net/yashnigam/kvt9xnbs/83/

Here's my code for the click event that makes the css selection:

       marketTable.on("renderlet", function(chart){

        chart.selectAll('tr.dc-table-row').on('click',function(d){

            if(filterKeys.includes(d.key)){

             chart.select('tr.dc-table-row').datum(d.key).style('background-color','gray');
            }

        })

    });

Kindly share a way to highlight rows of data table on click, the same way it works on a row chart.

like image 700
Yash Nigam Avatar asked Sep 05 '25 16:09

Yash Nigam


1 Answers

@Hassan has the right idea. I would suggest selecting the trs rather than the tds, and instead of changing the classes on click (which wouldn't survive a redraw), apply the classes also during the pretransition event.

So:

tr.dc-table-row.sel-rows {
     background-color: lightblue;
}

marketTable.on('pretransition', function (table) {
    table.selectAll('td.dc-table-column')
      .on('click', /* ... */)
    table.selectAll('tr.dc-table-row')
        .classed('sel-rows', d => filterKeys.indexOf(d.key) !== -1)
  });

highlighted rows We apply the class based on whether the row's key is in the array. Straightforward and simple!

Fork of your fiddle.

using built-in filters

@vbernal pointed out that the list doesn't get reset when you click the reset link. To better integrate this, we can hook into the built-in filters that the table inherits from the base mixin (but doesn't ordinarily use):

  marketTable.on('pretransition', function (table) {
      table.selectAll('td.dc-table-column')
          .on('click',function(d){    
              let filters = table.filters().slice();
              if(filters.indexOf(d.key)===-1)
                  filters.push(d.key);
              else
                  filters = filters.filter(k => k != d.key);
              table.replaceFilter([filters]);
              dc.redrawAll();
          });
      let filters = table.filters();
      table.selectAll('tr.dc-table-row')
          .classed('sel-rows', d => filters.indexOf(d.key) !== -1);
  });

Instead of setting dimension.filter() ourselves, we fetch the existing table.filters(), toggle as needed, and then set the filters using

table.replaceFilter([filters])

(Note the extra brackets.)

When the reset link is clicked, we reset the filter on the table rather than the crossfilter dimension. (It's always better to manipulate filters through the chart, because charts are not able to read the selection state from the crossfilter dimension.)

$('#resetTable').on('click', function() {
  marketTable.filter(null);
  dc.redrawAll();
});

New version of fiddle.

like image 162
Gordon Avatar answered Sep 07 '25 16:09

Gordon