UNPKG

billboard.js

Version:

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

198 lines (197 loc) • 6.26 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 { isDefined, isObject } from "../../module/util/type-checks.js"; import { extend, getMinMax, parseDate } from "../../module/util/object.js"; import { zoomIdentity, zoomTransform } from "d3-zoom"; //#region src/Chart/api/zoom.ts /** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ /** * Zoom by giving x domain range. * - **ℹ️ NOTE:** * - For `wheel` type zoom, the minimum zoom range will be set as the given domain range. To get the initial state, [.unzoom()](#unzoom) should be called. * - To be used [zoom.enabled](Options.html#.zoom) option should be set as `truthy`. * - When x axis type is `category`, domain range should be specified as index numbers. * - Due to the limitations of floating point precision, domain value may not be exact returning approximately values. * @function zoom * @instance * @memberof Chart * @param {Array} domainValue If domain range is given, the chart will be zoomed to the given domain. If no argument is given, the current zoomed domain will be returned. * @returns {Array} domain value in array * @example * // Zoom to specified domain range * chart.zoom([10, 20]); * * // For timeseries x axis, the domain value can be string, but the format should match with the 'data.xFormat' option. * chart.zoom(["2021-02-03", "2021-02-08"]); * * // For category x axis, the domain value should be index number. * chart.zoom([0, 3]); * * // Get the current zoomed domain range * // Domain value may not be exact returning approximately values. * chart.zoom(); */ const zoom$1 = function(domainValue) { const $$ = this.internal; const { axis, config, org, scale, state } = $$; let domain; if (!axis) return; const isCategorized = axis.isCategorized(); if (config.zoom_enabled) { domain = domainValue; if (Array.isArray(domain)) { if (axis.isTimeSeries()) domain = domain.map((x) => parseDate.bind($$)(x)); if ($$.withinRange(domain, $$.getZoomDomain("zoom", true), $$.getZoomDomain("zoom"))) { state.domain = domain.slice(); domain = $$.getZoomDomainValue(domain); $$.api.tooltip.hide(); if (config.subchart_show) { if (state.isCanvasMode) $$.setCanvasSubchartDomain?.(domain, true, false); else { const x = scale.zoom || scale.x; $$.brush.getSelection().call($$.brush.move, domain.map(x)); } } else { const x = isCategorized ? scale.x.orgScale() : org.xScale || scale.x; $$.updateCurrentZoomTransform(x, domain); } $$.setZoomResetButton(); } } else domain = $$.zoom.getDomain(); } return state.domain ?? domain; }; extend(zoom$1, { /** * Enable and disable zooming. * @function zoom․enable * @instance * @memberof Chart * @param {string|boolean} enabled Possible string values are "wheel" or "drag". If enabled is true, "wheel" will be used. If false is given, zooming will be disabled.<br>When set to false, the current zooming status will be reset. * @example * // Enable zooming using the mouse wheel * chart.zoom.enable(true); * // Or * chart.zoom.enable("wheel"); * * // Enable zooming by dragging * chart.zoom.enable("drag"); * * // Disable zooming * chart.zoom.enable(false); */ enable(enabled) { const $$ = this.internal; const { axis, config } = $$; if (!axis) { config.zoom_enabled = false; return; } if (/^(drag|wheel)$/.test(enabled)) config.zoom_type = enabled; config.zoom_enabled = !!enabled; if (!$$.zoom) $$.initZoom(); else if (enabled === false) $$.bindZoomEvent(false); if (enabled !== false) { config.zoom_type === "drag" && !$$.zoomBehaviour && $$.initZoomBehaviour?.(); $$.bindZoomEvent(); } $$.updateAndRedraw(); }, /** * Set or get x Axis maximum zoom range value * @function zoom․max * @instance * @memberof Chart * @param {number} [max] maximum value to set for zoom * @returns {number} zoom max value * @example * // Set maximum range value * chart.zoom.max(20); */ max(max) { const { config, org: { xDomain } } = this.internal; if (max === 0 || max) config.zoom_x_max = getMinMax("max", [xDomain[1], max]); return config.zoom_x_max; }, /** * Set or get x Axis minimum zoom range value * @function zoom․min * @instance * @memberof Chart * @param {number} [min] minimum value to set for zoom * @returns {number} zoom min value * @example * // Set minimum range value * chart.zoom.min(-1); */ min(min) { const { config, org: { xDomain } } = this.internal; if (min === 0 || min) config.zoom_x_min = getMinMax("min", [xDomain[0], min]); return config.zoom_x_min; }, /** * Set zoom range * @function zoom․range * @instance * @memberof Chart * @param {object} [range] zoom range * @returns {object} zoom range value * { * min: 0, * max: 100 * } * @example * chart.zoom.range({ * min: 10, * max: 100 * }); */ range(range) { const zoom = this.zoom; if (isObject(range)) { const { min, max } = range; isDefined(min) && zoom.min(min); isDefined(max) && zoom.max(max); } return { min: zoom.min(), max: zoom.max() }; } }); var zoom_default = { zoom: zoom$1, /** * Unzoom zoomed area * - **NOTE:** Calling .unzoom() will not trigger zoom events. * @function unzoom * @instance * @memberof Chart * @example * chart.unzoom(); */ unzoom() { const $$ = this.internal; const { config, $el: { canvas, eventRect, zoomResetBtn }, scale: { zoom }, state } = $$; const target = state.isCanvasMode ? canvas : eventRect; if (zoom || state.isCanvasMode && config.subchart_show && state.domain) { config.subchart_show ? state.isCanvasMode ? $$.clearCanvasSubchartDomain?.(true, false) : $$.brush.getSelection().call($$.brush.move, null) : $$.zoom.updateTransformScale(zoomIdentity); $$.updateZoom(true); zoomResetBtn?.style("display", "none"); if (target?.node() && zoomTransform(target.node()) !== zoomIdentity) $$.zoom.transform(target, zoomIdentity); state.domain = void 0; } } }; //#endregion export { zoom_default as default };