Search code examples
c3

Text inside each bubble in c3js Scatter plot


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


Solution

  • 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