C3: Stacked Bar Onclick captures multiple datapoints

Created on 18 Apr 2016  路  4Comments  路  Source: c3js/c3

When capturing onclick event with stacked bar, if clicking on/near the border between two elements the click fires twice.

Use the docs and to reproduce add to data:
onclick: function(id, element){
console.log(id);
}

http://c3js.org/samples/chart_bar_stacked.html
stackedbars onclick grabs both points

C-bug

Most helpful comment

The problem seems to be that C3 calculates if a mouse click is within a bar using a bit of boundingbox maths in chart.internal.isWithinBar, and adds in an offset value that catches 'near misses' to this box. It does this for each bar at a given x value in the chart so several can actually report a click if it happens near adjacent bars. If this offset is fudged to say -1 the problem goes away but then really small / narrow bars are very difficult to click instead.

chart.internal.isWithinBar = function (that) {
        var mouse = this.d3.mouse(that), box = that.getBoundingClientRect(),
            seg0 = that.pathSegList.getItem(0), seg1 = that.pathSegList.getItem(1),
            x = Math.min(seg0.x, seg1.x), y = Math.min(seg0.y, seg1.y),
            w = box.width, h = box.height, offset = 2, // offset causes the multiple onclick problem
            sx = x - offset, ex = x + w + offset, sy = y + h + offset, ey = y - offset;
        return sx < mouse[0] && mouse[0] < ex && ey < mouse[1] && mouse[1] < sy;
    };

All 4 comments

Oddly I'm getting a TypeError when using the onclick handler with the grouped bar chart. Marking as bug.

The problem seems to be that C3 calculates if a mouse click is within a bar using a bit of boundingbox maths in chart.internal.isWithinBar, and adds in an offset value that catches 'near misses' to this box. It does this for each bar at a given x value in the chart so several can actually report a click if it happens near adjacent bars. If this offset is fudged to say -1 the problem goes away but then really small / narrow bars are very difficult to click instead.

chart.internal.isWithinBar = function (that) {
        var mouse = this.d3.mouse(that), box = that.getBoundingClientRect(),
            seg0 = that.pathSegList.getItem(0), seg1 = that.pathSegList.getItem(1),
            x = Math.min(seg0.x, seg1.x), y = Math.min(seg0.y, seg1.y),
            w = box.width, h = box.height, offset = 2, // offset causes the multiple onclick problem
            sx = x - offset, ex = x + w + offset, sy = y + h + offset, ey = y - offset;
        return sx < mouse[0] && mouse[0] < ex && ey < mouse[1] && mouse[1] < sy;
    };

Updating to the latest version of C3 and D3 seemed to have fixed this for me (at least better than the last version I was using). However the pie chart click issue #2329 is new to the latest version

Should be fixed by #2684

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Shugardude picture Shugardude  路  4Comments

DieterSpringer picture DieterSpringer  路  4Comments

Kreozot picture Kreozot  路  3Comments

kethomassen picture kethomassen  路  3Comments

jstone-ponderosa picture jstone-ponderosa  路  3Comments