UNPKG

billboard.js

Version:

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

182 lines (150 loc) 5.67 kB
/** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ import {select as d3Select} from "d3-selection"; import {$FOCUS, $GAUGE} from "../../config/classes"; type FocusParam = string | string[]; export default { /** * This API highlights specified targets and fade out the others.<br><br> * You can specify multiple targets by giving an array that includes id as String. If no argument is given, all of targets will be highlighted. * @function focus * @instance * @memberof Chart * @param {string|Array} targetIdsValue Target ids to be highlighted. * @example * // data1 will be highlighted and the others will be faded out * chart.focus("data1"); * * // data1 and data2 will be highlighted and the others will be faded out * chart.focus(["data1", "data2"]); * * // all targets will be highlighted * chart.focus(); */ focus(targetIdsValue?: FocusParam): void { const $$ = this.internal; const {state} = $$; const targetIds = $$.mapToTargetIds(targetIdsValue); if (state.isCanvasMode) { const focusedIds = targetIds.filter($$.isTargetToShow, $$); const focusedSet = new Set(focusedIds); const defocusedIds = $$.mapToTargetIds() .filter(id => !focusedSet.has(id) && $$.isTargetToShow(id)); $$.revertLegend(); $$.toggleFocusLegend(defocusedIds, false); $$.toggleFocusLegend(focusedIds, true); state.focusedTargetIds = focusedSet; state.defocusedTargetIds = new Set(defocusedIds); $$.renderCanvasFrame?.(undefined, null, false); return; } const candidates = $$.$el.svg.selectAll( $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$)) ); this.revert(); this.defocus(); candidates.classed($FOCUS.focused, true).classed($FOCUS.defocused, false); if ($$.hasArcType() && !state.hasRadar) { $$.expandArc(targetIds); $$.hasType("gauge") && $$.markOverlapped(targetIdsValue, $$, `.${$GAUGE.gaugeValue}`); } $$.toggleFocusLegend(targetIds, true); state.focusedTargetIds = new Set(targetIds); targetIds.forEach(id => state.defocusedTargetIds.delete(id)); }, /** * This API fades out specified targets and reverts the others.<br><br> * You can specify multiple targets by giving an array that includes id as String. If no argument is given, all of targets will be faded out. * @function defocus * @instance * @memberof Chart * @param {string|Array} targetIdsValue Target ids to be faded out. * @example * // data1 will be faded out and the others will be reverted. * chart.defocus("data1"); * * // data1 and data2 will be faded out and the others will be reverted. * chart.defocus(["data1", "data2"]); * * // all targets will be faded out. * chart.defocus(); */ defocus(targetIdsValue?: FocusParam): void { const $$ = this.internal; const {state} = $$; const targetIds = $$.mapToTargetIds(targetIdsValue); if (state.isCanvasMode) { const defocusedIds = targetIds.filter($$.isTargetToShow, $$); $$.toggleFocusLegend(defocusedIds, false); defocusedIds.forEach(id => state.focusedTargetIds.delete(id)); state.defocusedTargetIds = new Set(defocusedIds); $$.renderCanvasFrame?.(undefined, null, false); return; } const candidates = $$.$el.svg.selectAll( $$.selectorTargets(targetIds.filter($$.isTargetToShow, $$)) ); candidates.classed($FOCUS.focused, false).classed($FOCUS.defocused, true); if ($$.hasArcType(null, ["polar"])) { $$.unexpandArc(targetIds); $$.hasType("gauge") && $$.undoMarkOverlapped($$, `.${$GAUGE.gaugeValue}`); } $$.toggleFocusLegend(targetIds, false); targetIds.forEach(id => state.focusedTargetIds.delete(id)); state.defocusedTargetIds = new Set(targetIds); }, /** * Revert focused or defocused state to initial state.<br><br> * You can specify multiple targets by giving an array that includes id as string. If no argument is given, all of targets will be reverted. * @function revert * @instance * @memberof Chart * @param {string|Array} targetIdsValue Target ids to be reverted * @example * // 'data1' will be reverted. * chart.revert("data1"); * * // 'data1' and 'data2' will be reverted. * chart.revert(["data1", "data2"]); * * // all targets will be reverted. * chart.revert(); */ revert(targetIdsValue?: FocusParam): void { const $$ = this.internal; const {config, state, $el} = $$; const targetIds = $$.mapToTargetIds(targetIdsValue); if (state.isCanvasMode) { const changed = !!state.focusedTargetIds?.size || !!state.defocusedTargetIds?.size; if (config.legend_show) { $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$))); $el.legend.selectAll($$.selectorLegends(targetIds)) .filter(function() { return d3Select(this).classed($FOCUS.legendItemFocused); }) .classed($FOCUS.legendItemFocused, false); } state.focusedTargetIds = new Set(); state.defocusedTargetIds = new Set(); changed && $$.renderCanvasFrame?.(undefined, null, false); return; } const candidates = $el.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets candidates.classed($FOCUS.focused, false).classed($FOCUS.defocused, false); $$.hasArcType(null, ["polar"]) && $$.unexpandArc(targetIds); if (config.legend_show) { $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$))); $el.legend.selectAll($$.selectorLegends(targetIds)) .filter(function() { return d3Select(this).classed($FOCUS.legendItemFocused); }) .classed($FOCUS.legendItemFocused, false); } state.focusedTargetIds = new Set(); state.defocusedTargetIds = new Set(); } };