c3
Version:
D3-based reusable chart library
118 lines (111 loc) • 3.08 kB
text/typescript
import CLASS from './class'
import { ChartInternal } from './core'
import { getPathBox } from './util'
ChartInternal.prototype.drag = function(mouse) {
var $$ = this,
config = $$.config,
main = $$.main,
d3 = $$.d3
var sx, sy, mx, my, minX, maxX, minY, maxY
if ($$.hasArcType()) {
return
}
if (!config.data_selection_enabled) {
return
} // do nothing if not selectable
if (!config.data_selection_multiple) {
return
} // skip when single selection because drag is used for multiple selection
sx = $$.dragStart[0]
sy = $$.dragStart[1]
mx = mouse[0]
my = mouse[1]
minX = Math.min(sx, mx)
maxX = Math.max(sx, mx)
minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my)
maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my)
main
.select('.' + CLASS.dragarea)
.attr('x', minX)
.attr('y', minY)
.attr('width', maxX - minX)
.attr('height', maxY - minY)
// TODO: binary search when multiple xs
main
.selectAll('.' + CLASS.shapes)
.selectAll('.' + CLASS.shape)
.each(function(d, i) {
if (!config.data_selection_isselectable(d)) {
return
}
var shape = d3.select(this),
isSelected = shape.classed(CLASS.SELECTED),
isIncluded = shape.classed(CLASS.INCLUDED),
_x,
_y,
_w,
_h,
toggle,
isWithin = false,
box
if (shape.classed(CLASS.circle)) {
_x = shape.attr('cx') * 1
_y = shape.attr('cy') * 1
toggle = $$.togglePoint
isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY
} else if (shape.classed(CLASS.bar)) {
box = getPathBox(this)
_x = box.x
_y = box.y
_w = box.width
_h = box.height
toggle = $$.togglePath
isWithin =
!(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY)
} else {
// line/area selection not supported yet
return
}
if ((isWithin as any) ^ isIncluded) {
shape.classed(CLASS.INCLUDED, !isIncluded)
// TODO: included/unincluded callback here
shape.classed(CLASS.SELECTED, !isSelected)
toggle.call($$, !isSelected, shape, d, i)
}
})
}
ChartInternal.prototype.dragstart = function(mouse) {
var $$ = this,
config = $$.config
if ($$.hasArcType()) {
return
}
if (!config.data_selection_enabled) {
return
} // do nothing if not selectable
$$.dragStart = mouse
$$.main
.select('.' + CLASS.chart)
.append('rect')
.attr('class', CLASS.dragarea)
.style('opacity', 0.1)
$$.dragging = true
}
ChartInternal.prototype.dragend = function() {
var $$ = this,
config = $$.config
if ($$.hasArcType()) {
return
}
if (!config.data_selection_enabled) {
return
} // do nothing if not selectable
$$.main
.select('.' + CLASS.dragarea)
.transition()
.duration(100)
.style('opacity', 0)
.remove()
$$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false)
$$.dragging = false
}