Browse Source

Merge branch 'bug/687_iOS_TouchEvent' of https://github.com/jamesgarfield/c3 into jamesgarfield-bug/687_iOS_TouchEvent

pull/2393/head
Yo_IT 7 years ago
parent
commit
e3d910f7d3
  1. 3
      src/config.js
  2. 254
      src/interaction.js

3
src/config.js

@ -235,6 +235,9 @@ c3_chart_internal_fn.getDefaultConfig = function () {
left: 0
},
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) {

254
src/interaction.js

@ -20,16 +20,168 @@ c3_chart_internal_fn.initEventRect = function () {
);
}
}
eventRectUpdate
.attr('class', $$.classEvent.bind($$))
.attr("x", x)
.attr("y", y)
.attr("width", w)
.attr("height", h);
};
c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
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")
.attr("class", $$.classEvent.bind($$))
.style("cursor", config.data_selection_enabled && config.data_selection_grouped ? "pointer" : null)
.on('mouseover', function (d) {
var index = d.index;
if ($$.dragging || $$.flowing) { return; } // do nothing while dragging/flowing
if ($$.hasArcType()) { return; }
// Expand shapes for selection
if (config.point_focus_expand_enabled) { $$.expandCircles(index, null, true); }
$$.expandBars(index, null, true);
// Call event handler
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
config.data_onmouseover.call($$.api, d);
});
})
.on('mouseout', function (d) {
var index = d.index;
if (!$$.config) { return; } // chart is destroyed
if ($$.hasArcType()) { return; }
$$.hideXGridFocus();
$$.hideTooltip();
// Undo expanded shapes
$$.unexpandCircles();
$$.unexpandBars();
// Call event handler
$$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
config.data_onmouseout.call($$.api, d);
});
})
.on('mousemove', function (d) {
var selectedData, index = d.index,
eventRect = $$.svg.select('.' + CLASS.eventRect + '-' + index);
if ($$.dragging || $$.flowing) { return; } // do nothing while dragging/flowing
if ($$.hasArcType()) { return; }
if ($$.isStepType(d) && $$.config.line_step_type === 'step-after' && d3.mouse(this)[0] < $$.x($$.getXValue(d.id, index))) {
index -= 1;
}
// Show tooltip
selectedData = $$.filterTargetsToShow($$.data.targets).map(function (t) {
return $$.addName($$.getValueOnIndex(t.values, index));
});
if (config.tooltip_grouped) {
$$.showTooltip(selectedData, this);
$$.showXGridFocus(selectedData);
}
if (config.tooltip_grouped && (!config.data_selection_enabled || config.data_selection_grouped)) {
return;
}
$$.main.selectAll('.' + CLASS.shape + '-' + index)
.each(function () {
d3.select(this).classed(CLASS.EXPANDED, true);
if (config.data_selection_enabled) {
eventRect.style('cursor', config.data_selection_grouped ? 'pointer' : null);
}
if (!config.tooltip_grouped) {
$$.hideXGridFocus();
$$.hideTooltip();
if (!config.data_selection_grouped) {
$$.unexpandCircles(index);
$$.unexpandBars(index);
}
}
})
.filter(function (d) {
return $$.isWithinShape(this, d);
})
.each(function (d) {
if (config.data_selection_enabled && (config.data_selection_grouped || config.data_selection_isselectable(d))) {
eventRect.style('cursor', 'pointer');
}
if (!config.tooltip_grouped) {
$$.showTooltip([d], this);
$$.showXGridFocus([d]);
if (config.point_focus_expand_enabled) { $$.expandCircles(index, d.id, true); }
$$.expandBars(index, d.id, true);
}
});
})
.on('click', function (d) {
//click event was simulated via a 'tap' touch event, cancel regular click
if (tap) {
return;
}
click(this, d);
})
.on('touchstart', function(d) {
//store current X selection for comparison during touch end event
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(
config.data_selection_draggable && $$.drag ? (
d3.behavior.drag().origin(Object)
.on('drag', function () { $$.drag(d3.mouse(this)); })
.on('dragstart', function () { $$.dragstart(d3.mouse(this)); })
.on('dragend', function () { $$.dragend(); })
) : function () {}
);
};
c3_chart_internal_fn.redrawEventRect = function () {
var $$ = this, d3 = $$.d3, config = $$.config,
x, y, w, h;
// TODO: rotated not supported yet
x = 0;
y = 0;
w = $$.width;
h = $$.height;
c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) {
var $$ = this, d3 = $$.d3, config = $$.config,
tap = false, tapX, tapY;
function mouseout() {
$$.svg.select('.' + CLASS.eventRect).style('cursor', null);
@ -39,17 +191,33 @@ c3_chart_internal_fn.redrawEventRect = function () {
$$.unexpandBars();
}
// rects for mouseover
$$.main.select('.' + CLASS.eventRects)
.style('cursor', config.zoom_enabled ? config.axis_rotated ? 'ns-resize' : 'ew-resize' : null);
$$.eventRect
.attr('x', x)
.attr('y', y)
.attr('width', w)
.attr('height', h)
.on('mouseout', config.interaction_enabled ? function () {
if (!config) { return; } // chart is destroyed
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')
.attr('x', 0)
.attr('y', 0)
.attr('width', $$.width)
.attr('height', $$.height)
.attr('class', CLASS.eventRect)
.on('mouseout', function () {
if (!$$.config) { return; } // chart is destroyed
if ($$.hasArcType()) { return; }
mouseout();
} : null)
@ -105,32 +273,38 @@ c3_chart_internal_fn.redrawEventRect = function () {
$$.mouseover = closest;
}
}
} : null)
.on('click', config.interaction_enabled ? function () {
var targetsToShow, mouse, closest, sameXData;
if ($$.hasArcType(targetsToShow)) { return; }
})
.on('click', function () {
//click event was simulated via a 'tap' touch event, cancel regular click
if (tap) {
return;
}
targetsToShow = $$.filterTargetsToShow($$.data.targets);
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) {
if ($$.isScatterType(closest) || !config.data_selection_grouped) {
sameXData = [closest];
} else {
sameXData = $$.filterByX(targetsToShow, closest.x);
}
sameXData.forEach(function (d) {
$$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.shape + '-' + d.index).each(function () {
if (config.data_selection_grouped || $$.isWithinShape(this, d)) {
$$.toggleShape(this, d, d.index);
config.data_onclick.call($$.api, d, 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;
}
} : null)
click(this);
//indictate tap event fired to prevent click;
tap = true;
setTimeout(function() { tap = false; }, config.touch_tap_delay);
})
.call(
config.interaction_enabled && config.data_selection_draggable && $$.drag ? (
d3.drag()

Loading…
Cancel
Save