UNPKG

billboard.js

Version:

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

185 lines (182 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.0.1 */ import { $COMMON } from '../../config/classes.js'; import { parseDate, extend } from '../../module/util/object.js'; /** * Select subchart by giving x domain range. * - **ℹ️ NOTE:** * - Due to the limitations of floating point precision, domain value may not be exact returning approximately values. * @function subchart * @instance * @memberof Chart * @param {Array} domainValue If domain range is given, the subchart will be selected to the given domain. If no argument is given, the current subchart selection domain will be returned. * @returns {Array} domain value in array * @example * // Specify domain for subchart selection * chart.subchart([1, 2]); * * // Get the current subchart selection domain range * // Domain value may not be exact returning approximately values. * chart.subchart(); */ // NOTE: declared function assigning to variable to prevent duplicated method generation in JSDoc. const subchart = function (domainValue) { const $$ = this.internal; const { axis, brush, config, scale: { x, subX }, state } = $$; let domain; if (state.isCanvasMode) { if (config.subchart_show) { domain = domainValue; if (Array.isArray(domain)) { domain = axis.isTimeSeries() ? domain.map(x => parseDate.bind($$)(x)) : domain; domain = $$.setCanvasSubchartDomain(domain) || state.domain; } else { domain = state.domain ?? x.orgDomain(); } } return domain; } if (config.subchart_show) { domain = domainValue; if (Array.isArray(domain)) { if (axis.isTimeSeries()) { domain = domain.map(x => parseDate.bind($$)(x)); } const isWithinRange = $$.withinRange(domain, $$.getZoomDomain("subX", true), $$.getZoomDomain("subX")); if (isWithinRange) { // store a copy: brush events mutate state.domain in place, // which would corrupt the caller-passed array state.domain = domain.slice(); brush.move(brush.getSelection(), domain.map(subX)); } } else { domain = state.domain ?? x.orgDomain(); } } return domain; }; extend(subchart, { /** * Show subchart * - **NOTE:** for ESM imports, needs to import 'subchart' exports and instantiate it by calling `subchart()`. * @function subchart․show * @instance * @memberof Chart * @example * // for ESM imports, needs to import 'subchart' and must be instantiated first to enable subchart's API. * import {subchart} from "billboard.js"; * * const chart = bb.generate({ * ... * subchart: { * // need to be instantiated by calling 'subchart()' * enabled: subchart() * * // in case don't want subchart to be shown at initialization, instantiate with '!subchart()' * enabled: !subchart() * } * }); * * chart.subchart.show(); */ show() { const $$ = this.internal; const { $el: { subchart }, config } = $$; const show = config.subchart_show; if (!show) { if ($$.state.isCanvasMode) { $$.unbindZoomEvent?.(); config.subchart_show = true; this.resize(); return; } // unbind zoom event bound to chart rect area $$.unbindZoomEvent(); config.subchart_show = !show; !subchart.main && $$.initSubchart(); let $target = subchart.main.selectAll(`.${$COMMON.target}`); // need to cover when new data has been loaded if ($$.data.targets.length !== $target.size()) { $$.updateSizes(); $$.updateTargetsForSubchart($$.data.targets); $target = subchart.main?.selectAll(`.${$COMMON.target}`); } $target?.style("opacity", null); subchart.main?.style("display", null); this.resize(); } }, /** * Hide generated subchart * - **NOTE:** for ESM imports, needs to import 'subchart' exports and instantiate it by calling `subchart()`. * @function subchart․hide * @instance * @memberof Chart * @example * chart.subchart.hide(); */ hide() { const $$ = this.internal; const { $el: { subchart: { main } }, config } = $$; if ($$.state.isCanvasMode) { if (config.subchart_show) { config.subchart_show = false; this.resize(); $$.bindZoomEvent?.(); } return; } if (config.subchart_show && main?.style("display") !== "none") { config.subchart_show = false; main.style("display", "none"); this.resize(); } }, /** * Toggle the visibility of subchart * - **NOTE:** for ESM imports, needs to import 'subchart' exports and instantiate it by calling `subchart()`. * @function subchart․toggle * @instance * @memberof Chart * @example * // When subchart is hidden, will be shown * // When subchart is shown, will be hidden * chart.subchart.toggle(); */ toggle() { const $$ = this.internal; const { config } = $$; this.subchart[config.subchart_show ? "hide" : "show"](); }, /** * Reset subchart selection * @function subchart․reset * @instance * @memberof Chart * @example * // Reset subchart selection * chart.subchart.reset(); */ reset() { const $$ = this.internal; const { brush } = $$; if ($$.state.isCanvasMode) { $$.clearCanvasSubchartDomain?.(true, false); return; } brush.clear(brush.getSelection()); } }); var apiSubchart = { subchart }; export { apiSubchart as default };