UNPKG

billboard.js

Version:

Re-usable easy interface JavaScript chart library, based on D3 v4+

98 lines (97 loc) • 3.49 kB
/*! * 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 };