1

I am generating scatter plot using c3 js.I wanted to display some text inside the bubble.Text can be either its value(y axis) or x axis value.The property (labels :true) which works for bar graph does not work in case of scatter.Please help

Thanks

Nithin A
  • 374
  • 1
  • 2
  • 18

1 Answers1

2

Adding Labels to c3 Scatter Plot

You can select the points using d3 and add whatever text you want using the point coordinates. For example, here's how you add the serei-index.point-index

function drawLabels(chartInternal) {
    var textLayers = chartInternal.main.selectAll('.' + c3.chart.internal.fn.CLASS.texts);
    for (var i = 0; i < textLayers[0].length; i++) {
        // select each of the scatter points
        chartInternal.mainCircle[i].forEach(function (point, index) {
            var d3point = d3.select(point)
            d3.select(textLayers[0][i])
                .append('text')
                // center horizontally and vertically
                .style('text-anchor', 'middle').attr('dy', '.3em')
                .text(i + '.' + index)
                // same as at the point
                .attr('x', d3point.attr('cx')).attr('y', d3point.attr('cy'))
        })
    }
}

and call it like this

drawLabels(chart.internal);

You can easily use the index to pick out labels from an array instead.


Responding to Legend Clicks

To update the label positions when you show / hide each series by clicking on the legends you hook onto the legend click handlers remove the existing labels and draw them again at the new positions once the scatter points are in their final place. You use a timeout to make sure the label draw is triggered after the animation completes

Here's your legend option for that

legend: {
    item: {
        onclick: function (id) {
            var $$ = this;
            // remove existing labels
            this.main.selectAll('.' + c3.chart.internal.fn.CLASS.texts).selectAll('*').remove();

            // this block is a copy paste from c3 code                  
            if (this.d3.event.altKey) {
                this.api.hide();
                this.api.show(id);
            } else {
                this.api.toggle(id);
                this.isTargetToShow(id) ? this.api.focus(id) : this.api.revert();
            }

            setTimeout(function () {
                drawLabels($$)
            // add a small duration to make sure the points are in place
            }, this.config.transition_duration + 100)
        }
    }
},

Fiddle - http://jsfiddle.net/mn6qn09d/


enter image description here

potatopeelings
  • 40,709
  • 7
  • 95
  • 119
  • Thanks, here if i click on the legend the value stays .I tried removing the label on legend click and again adding it it works.But for multiple datasets when i click on the legend the particular bubble hides and the bubble above it comes down but not its label. – Nithin A Aug 13 '15 at 05:03
  • I'll add that the `drawLabels` had to be wrapped in a `setTimeout` in my situation. Otherwise, great solution. – Tony Aug 25 '15 at 21:35