Browse Source

Add touch/tap configuration

Add tap events to eventRects
pull/1688/head
James Garfield 10 years ago committed by Ændrew Rininsland
parent
commit
375c7306b4
No known key found for this signature in database
GPG Key ID: ADBCD4C867F9B2DA
  1. 3
      src/config.js
  2. 121
      src/interaction.js

3
src/config.js

@ -225,6 +225,9 @@ c3_chart_internal_fn.getDefaultConfig = function () {
left: 0 left: 0
}, },
title_position: 'top-center', title_position: 'top-center',
//TouchEvent configuration
touch_tap_radius : 20, //touch movement must be less than this to be a 'tap'
touch_tap_delay : 500, //clicks are suppressed for this many ms after a tap
}; };
Object.keys(this.additionalConfig).forEach(function (key) { Object.keys(this.additionalConfig).forEach(function (key) {

121
src/interaction.js

@ -109,7 +109,27 @@ c3_chart_internal_fn.updateEventRect = function (eventRectUpdate) {
.attr("height", h); .attr("height", h);
}; };
c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) { c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
var $$ = this, d3 = $$.d3, config = $$.config; var $$ = this, d3 = $$.d3, config = $$.config,
tap = false, tapX;
function click(shape, d) {
var index = d.index;
if ($$.hasArcType() || !$$.toggleShape) { return; }
if ($$.cancelClick) {
$$.cancelClick = false;
return;
}
if ($$.isStepType(d) && config.line_step_type === 'step-after' && d3.mouse(shape)[0] < $$.x($$.getXValue(d.id, index))) {
index -= 1;
}
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
if (config.data_selection_grouped || $$.isWithinShape(this, d)) {
$$.toggleShape(this, d, index);
$$.config.data_onclick.call($$.api, d, this);
}
});
}
eventRectEnter.append("rect") eventRectEnter.append("rect")
.attr("class", $$.classEvent.bind($$)) .attr("class", $$.classEvent.bind($$))
.style("cursor", config.data_selection_enabled && config.data_selection_grouped ? "pointer" : null) .style("cursor", config.data_selection_enabled && config.data_selection_grouped ? "pointer" : null)
@ -198,22 +218,34 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
}); });
}) })
.on('click', function (d) { .on('click', function (d) {
var index = d.index; //click event was simulated via a 'tap' touch event, cancel regular click
if ($$.hasArcType() || !$$.toggleShape) { return; } if (tap) {
if ($$.cancelClick) {
$$.cancelClick = false;
return; return;
} }
if ($$.isStepType(d) && config.line_step_type === 'step-after' && d3.mouse(this)[0] < $$.x($$.getXValue(d.id, index))) {
index -= 1; click(this, d);
}
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) { })
if (config.data_selection_grouped || $$.isWithinShape(this, d)) { .on('touchstart', function(d) {
$$.toggleShape(this, d, index); //store current X selection for comparison during touch end event
$$.config.data_onclick.call($$.api, d, this); tapX = d.x;
})
.on('touchend', function(d) {
var finalX = d.x;
//If end is not the same as the start, event doesn't count as a tap
if (tapX !== finalX) {
return;
} }
});
click(this, d);
//indictate tap event fired to prevent click;
tap = true;
setTimeout(function() { tap = false; }, config.touch_tap_delay);
}) })
.call( .call(
config.data_selection_draggable && $$.drag ? ( config.data_selection_draggable && $$.drag ? (
d3.behavior.drag().origin(Object) d3.behavior.drag().origin(Object)
@ -225,7 +257,8 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
}; };
c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) { c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) {
var $$ = this, d3 = $$.d3, config = $$.config; var $$ = this, d3 = $$.d3, config = $$.config,
tap = false, tapX, tapY;
function mouseout() { function mouseout() {
$$.svg.select('.' + CLASS.eventRect).style('cursor', null); $$.svg.select('.' + CLASS.eventRect).style('cursor', null);
@ -235,6 +268,25 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
$$.unexpandBars(); $$.unexpandBars();
} }
function click(shape) {
var targetsToShow = $$.filterTargetsToShow($$.data.targets);
var mouse, closest;
if ($$.hasArcType(targetsToShow)) { return; }
mouse = d3.mouse(shape);
closest = $$.findClosestFromTargets(targetsToShow, mouse);
if (! closest) { return; }
// select if selection enabled
if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) {
$$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id)).selectAll('.' + CLASS.shape + '-' + closest.index).each(function () {
if (config.data_selection_grouped || $$.isWithinShape(this, closest)) {
$$.toggleShape(this, closest, closest.index);
$$.config.data_onclick.call($$.api, closest, this);
}
});
}
}
eventRectEnter.append('rect') eventRectEnter.append('rect')
.attr('x', 0) .attr('x', 0)
.attr('y', 0) .attr('y', 0)
@ -297,22 +349,35 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
} }
}) })
.on('click', function () { .on('click', function () {
var targetsToShow = $$.filterTargetsToShow($$.data.targets); //click event was simulated via a 'tap' touch event, cancel regular click
var mouse, closest; if (tap) {
if ($$.hasArcType(targetsToShow)) { return; } return;
mouse = d3.mouse(this);
closest = $$.findClosestFromTargets(targetsToShow, mouse);
if (! closest) { return; }
// select if selection enabled
if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) {
$$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id)).selectAll('.' + CLASS.shape + '-' + closest.index).each(function () {
if (config.data_selection_grouped || $$.isWithinShape(this, closest)) {
$$.toggleShape(this, closest, closest.index);
$$.config.data_onclick.call($$.api, closest, this);
} }
});
click(this);
})
.on('touchstart', function(){
var mouse = d3.mouse(this);
//store starting coordinates for distance comparision during touch end event
tapX = mouse[0];
tapY = mouse[1];
})
.on('touchend', function(){
var mouse = d3.mouse(this),
x = mouse[0],
y = mouse[1];
//If end is too far from start, event doesn't count as a tap
if (Math.abs(x - tapX) > config.touch_tap_radius || Math.abs(y - tapY) > config.touch_tap_radius) {
return;
} }
click(this);
//indictate tap event fired to prevent click;
tap = true;
setTimeout(function() { tap = false; }, config.touch_tap_delay);
}) })
.call( .call(
config.data_selection_draggable && $$.drag ? ( config.data_selection_draggable && $$.drag ? (

Loading…
Cancel
Save