billboard.js
Version:
Re-usable easy interface JavaScript chart library, based on D3 v4+
98 lines (97 loc) • 3.49 kB
JavaScript
/*!
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*
* billboard.js, JavaScript chart library
* https://naver.github.io/billboard.js/
*
* @version 4.1.1
*/
import { getPathBox, scheduleRAFUpdate } from "../../module/util/dom.js";
import { $BAR, $CIRCLE, $COMMON, $DRAG, $SELECT, $SHAPE } from "../../config/classes.js";
import { select } from "d3-selection";
//#region src/ChartInternal/interactions/drag.ts
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Module used for data.selection.draggable option
*/
var drag_default = {
/**
* Called when dragging.
* Data points can be selected.
* @private
* @param {object} mouse Object
*/
drag(mouse) {
const $$ = this;
const { config, state, $el: { main } } = $$;
const isSelectionGrouped = config.data_selection_grouped;
const isSelectable = config.interaction_enabled && config.data_selection_isselectable;
if ($$.hasArcType() || !config.data_selection_enabled || config.zoom_enabled && !$$.zoom.altDomain || !config.data_selection_multiple) return;
const [sx, sy] = state.dragStart || [0, 0];
const [mx, my] = mouse;
const minX = Math.min(sx, mx);
const maxX = Math.max(sx, mx);
const minY = isSelectionGrouped ? state.margin.top : Math.min(sy, my);
const maxY = isSelectionGrouped ? state.height : Math.max(sy, my);
const executeDrag = () => {
if (!$$ || !$$.$el || !$$.$el.main) return;
main.select(`.${$DRAG.dragarea}`).attr("x", minX).attr("y", minY).attr("width", maxX - minX).attr("height", maxY - minY);
main.selectAll(`.${$SHAPE.shapes}`).selectAll(`.${$SHAPE.shape}`).filter((d) => isSelectable?.bind($$.api)(d)).each(function(d, i) {
const shape = select(this);
const isSelected = shape.classed($SELECT.SELECTED);
const isIncluded = shape.classed($DRAG.INCLUDED);
let isWithin;
let toggle;
if (shape.classed($CIRCLE.circle)) {
const x = +shape.attr("cx");
const y = +shape.attr("cy");
toggle = $$.togglePoint;
isWithin = minX < x && x < maxX && minY < y && y < maxY;
} else if (shape.classed($BAR.bar)) {
const { x, y, width, height } = getPathBox(this);
toggle = $$.togglePath;
isWithin = !(maxX < x || x + width < minX) && !(maxY < y || y + height < minY);
} else return;
if (isWithin ^ isIncluded) {
shape.classed($DRAG.INCLUDED, !isIncluded);
shape.classed($SELECT.SELECTED, !isSelected);
toggle.call($$, !isSelected, shape, d, i);
}
});
};
scheduleRAFUpdate($$.state, executeDrag);
},
/**
* Called when the drag starts.
* Adds and Shows the drag area.
* @private
* @param {object} mouse Object
*/
dragstart(mouse) {
const $$ = this;
const { config, state, $el: { main } } = $$;
if ($$.hasArcType() || !config.data_selection_enabled) return;
state.dragStart = mouse;
main.select(`.${$COMMON.chart}`).append("rect").attr("class", $DRAG.dragarea).style("opacity", "0.1");
$$.setDragStatus(true);
},
/**
* Called when the drag finishes.
* Removes the drag area.
* @private
*/
dragend() {
const $$ = this;
const { config, $el: { main }, $T } = $$;
if ($$.hasArcType() || !config.data_selection_enabled) return;
$T(main.select(`.${$DRAG.dragarea}`)).style("opacity", "0").remove();
main.selectAll(`.${$SHAPE.shape}`).classed($DRAG.INCLUDED, false);
$$.setDragStatus(false);
}
};
//#endregion
export { drag_default as default };