3

I have a bar plot with inverted X/Y Axes. Here is my code and output:

    var myData = {};
    myData.x = 'x';
    myData.xFormat = "%Y-%m-%d";
    myData.type = 'bar';
    myX = app.reportsCollection.countedByDay.plotData.X;
    myY = app.reportsCollection.countedByDay.plotData.Y;
    myX.splice(0,0,'x');
    myY.splice(0,0,'Nuevos Reportes');
    myData.columns = [];
    myData.columns.push(myX);
      //http://stackoverflow.com/a/586189/1862909
    myData.columns.push(myY);
    var chart = c3.generate({
      bindto: elementID,
      data: myData,
      size: {
        height: 300
      },
      bar: {
        width: {
            ratio: 0.5 // this makes bar width 50% of length between ticks
        }
        // or
        //width: 100 // this makes bar width 100px
      },
      axis: {
        x: {
          type: 'timeseries',
          tick: {
                  format: "%b-%d"
              }
        },

      },
      legend: {
        show: false
      }
    });

enter image description here

What I need is to link to specific pages on the X tick labels. In the example, Otra should be a hyperlink.

I tried to include the link as text in the myX variable, but it didn't work.

Any idea how to do this?

otmezger
  • 10,410
  • 21
  • 64
  • 90

1 Answers1

6

Not out the box, c3 renders tick labels as tspan elements and adds them using d3's .text function, so trying to template in <A> elements as text in c3's tick functions doesn't work.

Have a look though at Mark's accepted answer here (not my one) - put a icon on graph c3.js - d3.js - that shows how to replace tick labels in c3 with other elements. It wouldn't be too hard to change that to take the existing text and then wrap it with a couple of A tags, include the appropriate href and re-add it as html.

In fact, tspans can include A tags directly, so it can be done like this - http://jsfiddle.net/k9Dbf/745/. The hard bit was figuring out it should be xlink:href not just href...

important bit of fiddle:

d3.selectAll('.c3-axis-x .tick tspan')
  .each(function(d,i){
    // augment tick contents with link
    var self = d3.select(this);
    var text = self.text();
    self.html("<A xlink:href='"+arrayOfLinks[i]+"'>"+text+"</A>");
});

Edit:

Solution 2: you could also skip the A element altogether and use a click listener on the tspan, though it now needs a bit of css to give the cursor indicator

d3.selectAll('.c3-axis-x .tick tspan')
  .on("click", function(d,i){
    window.open(arrayOfLinks[i], "_blank");
});

.c3-axis-x .tick tspan:hover {
  cursor: pointer;
}
Community
  • 1
  • 1
mgraham
  • 6,147
  • 1
  • 21
  • 20
  • Very nice workaround using d3 to change the element after it was rendered. very clever. Thanks. – otmezger Apr 05 '16 at 14:50
  • 1
    thank the guy in the other answer too, it's his answer just applied slightly differently :-) – mgraham Apr 05 '16 at 15:27
  • Solution 1 no longer works 4 years later, unfortunately. C3 seems to regenerate the HTML frequently, so the links quickly get replaced with text again. You can often manage one click, but after that, they're all back to tspans with plain text content. – Canuck Oct 16 '20 at 20:13
  • If you put it in an onrendered callback in c3 it should pick up again – mgraham Oct 19 '20 at 08:41
  • You're hero of the day, sir. – kkochanski Jan 12 '23 at 12:26