C3.js horizontal bar chart - Highlight a specific x-axis tick together with bar

Viewed 134

I've created a very simple horizontal bar chart with C3.js that is listing data from my SQL database. The chart is accessible on it's own without any filter, but also by passing data from a previously visited page using $_GET.

When the user coming from a page where data is being passed to the chart, I want the chart to highlight the specific data(x-axis tick, and bar) from the previous page.

I've managed to highlight the relevant tick(which is a text) however I'm unable to highlight or add a different color to the corresponding bar.

Here is a working JSfiddle example

Illustration of the desired outcome

var chart = c3.generate({
    
    size: {
        height: 300,
        width: 500,
    },
     
    data: {  
    x:'x',
       columns: [
            ['nr',123,200,241,300,212,300],
            ['x','a','b','c','d','e','f'],
        ],
        type : 'bar',
        keys: {
            x: 'Name',
            value: ['nr']
        }
    },
   
    axis: {
      
        rotated: true,
        x: {
            type: 'category',
            tick: {multiline:false,}
        },
        y: {
            padding: {top:0, bottom:0},
            tick: { multiline:false, 
                    format: d3.format('s') }
        }
    },
    bar: {
        width: {
            ratio: 0.5
        }
    },
    grid: {
        x: {
            show: false
        },
        y: {
            show: true
        }
    },
    legend: {show: false},
    tooltip: {
        format: {
            value: function (value, id) {
                var format = id === 'nr' ? d3.format(',') : function (d) { return  d + ' suffix'; };
                return format(value);
            }
        }
    }
});  

var highLightTick = d3.selectAll('.c3-axis-x .tick')
  .filter(function(){ 
    return d3.select(this).text() === 'd'
  })
  .style('fill', 'black')
  .style('font-size', '14px')
  .style('font-weight', 'bold');

How can I connect the tick and the corresponding bar so they are highlighted separately from the rest of the data?

Any help would be much appreciated, thanks.

1 Answers

Modify highLightTick and bind a mouseenter / mouseleave handler to every item.

See it working in a fiddle

const highLightTick = (tick, isOn) => tick
  .style('fill', isOn ? 'black' : 'gray')
  .style('font-size', isOn ? '14px' : '12px')
  .style('font-weight', isOn ? 700 : 400);

d3.selectAll('.c3-event-rect').each(function(d, i) {
  const el = d3.select(this);
  const tick = d3.select(`.tick:nth-of-type(${i + 1})`);
  el.on('mouseenter', () => highLightTick(tick, true))
    .on('mouseleave', () => highLightTick(tick, false))
});
Related