|
|
|
@ -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() |
|
|
|
|