0

i'm using c3js library to render line chart, where I want to group x-axis category labels, as asked in this questions: c3 js: How can I group by Year on the X-axis labels?.

I tried above solution but it is only working only for series type 'timeseries' not for 'category'.

somewhat, I have find the solution using jQuery. following is code:

 var xAxis = ['x', "G1 - Team_1", "G2 - Team_1", "G3 - Team_1", "G4 - Team_1", "G1 - Team_2", "G2 - Team_2", "G3 - Team_2", "G4 - Team_2", "G1 - Team_3", "G2 - Team_3", "G3 - Team_3", "G4 - Team_3", "G1 - Team_4", "G2 - Team_4", "G3 - Team_4", "G4 - Team_4", "G1 - Team_5", "G2 - Team_5", "G3 - Team_5", "G4 - Team_5"],
 match1 = ['match1', 32, 4, 2, 46, 24, 54, 18, 65, 87, 25, 3, 6, 16, 63, 46, 62, 69, 37, 50, 65],
 match2 = ['match2', 68, 60, 95, 65, 59, 67, 56, 69, 38, 74, 59, 83, 53, 72, 16, 12, 64, 93, 51, 93];

 var chart = c3.generate({
    data: {
      x: 'x',
      columns: [xAxis, match1, match2],
      type: 'spline',
    },     
    line: {
      connectNull: true,
    },
    axis: {
      x: {
        label: {
          text: 'Group(s)'
        },
        type: 'category',
        tick: {
          multiline: true,
          centered: true
        },
        height: 50
      }
    }
  });
  //this function changes x-axis labels
function changeXAxisLabel() {
   var ticks = $('.c3-axis.c3-axis-x').find('.tick');
   var ticksData = ticks.map(function(x, ele) {
     return {
       text: ele.textContent,
       ele: ele,
       name: ele.textContent.replace('G1', '')
         .replace('G2', '')
         .replace('G3', '')
         .replace('G4', '')
         //.replace('-', '').trim()
     };
   }).get();


   var groupedData = {};
   ticksData.forEach(function(ele) {
     if (!groupedData[ele.name]) groupedData[ele.name] = [];
     groupedData[ele.name].push(ele);
   });

   Object.keys(groupedData).forEach(function(k) {

     if (groupedData[k].length < 2) return;

     var addOn = Math.ceil(groupedData[k].length / 2);

     var translates = [];

     groupedData[k].forEach(function(tick, index) {
       var $tick = $(tick.ele);
       var val = $tick.attr('transform').replace(/[translate,(),]/g, '').split(' ')[0];
       translates.push(Number(val));

       $tick.find('tspan:eq(0)').text(tick.text.replace(new RegExp(tick.name, 'i'), '').trim());
       $tick.find('tspan:not(:eq(0))').remove();

       if (index == addOn) {
         var cloned = $tick.clone();
         //cloned = cloned.find('line').remove();
         var pos = (translates[index] + translates[index - 1]) / 2;
         cloned.attr('transform', 'translate(' + pos + ',20)');
         cloned.find('tspan').text(tick.name);
         cloned.insertAfter($tick);
         $(cloned).find('line').remove();
       }
     })


   });

 }

at first it is displaying desired result:

enter image description here

But after window resize, x-axis labels reverted as it seems chart reinitialize. I tried it with calling changeXAxisLabel on window.resize callback:

$(window).resize(function() {
   changeXAxisLabel()
 })

But its not running as expected. and it throws an error:

Error: <g> attribute transform: Expected number, "translate(NaN, 0)".

Now I didn't understand, how this can be fixed.

How can I remove this error? or there is other method to solve this problem?

EDIT: Here is jsfiddle for this code sample: https://jsfiddle.net/abhinaw/1m6v8mwh/

Thanks

1 Answers1

0

Instead of doing in $(window).resize() can you try calling your function as follow :

var chart = c3.generate({
    // just add this function, keep remaining code as it is. 
    onrendered: function () {
      changeRoundChartXAxisLabel();
    }
});

here is updated version of your JSFiddel.

Removed following code

$(window).resize(function() {
    changeRoundChartXAxisLabel()
})

setTimeout(changeRoundChartXAxisLabel, 100);

however i am not able to fix following error

Error: <g> attribute transform: Expected number, "translate(NaN, 0)".
sandyJoshi
  • 733
  • 9
  • 20