UNPKG

billboard.js

Version:

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

148 lines (121 loc) 3.94 kB
/** * Copyright (c) 2017 ~ present NAVER Corp. * billboard.js project is licensed under the MIT license */ export default { initClip(): void { const $$ = this; const {clip, datetimeId} = $$.state; // MEMO: clipId needs to be unique because it conflicts when multiple charts exist clip.id = `${datetimeId}-clip`; clip.idXAxis = `${clip.id}-xaxis`; clip.idYAxis = `${clip.id}-yaxis`; clip.idGrid = `${clip.id}-grid`; // Define 'clip-path' attribute values clip.path = $$.getClipPath(clip.id); clip.pathXAxis = $$.getClipPath(clip.idXAxis); clip.pathYAxis = $$.getClipPath(clip.idYAxis); clip.pathGrid = $$.getClipPath(clip.idGrid); }, getClipPath(id: string): string | null { const $$ = this; const {config} = $$; if ( (!config.clipPath && /-clip$/.test(id)) || (!config.axis_x_clipPath && /-clip-xaxis$/.test(id)) || (!config.axis_y_clipPath && /-clip-yaxis$/.test(id)) ) { return null; } return `url(#${id})`; }, appendClip(parent, id: string): void { id && parent.append("clipPath") .attr("id", id) .append("rect"); }, /** * Set x Axis clipPath dimension * @param {d3Selecton} node clipPath <rect> selection * @private */ setXAxisClipPath(node): void { const $$ = this; const {config, state: {margin, width, height}} = $$; const isRotated = config.axis_rotated; const left = Math.max(30, margin.left) - (isRotated ? 0 : 20); // less than 20 is not enough to show the axis label 'outer' without legend const h = (isRotated ? (margin.top + height) + 10 : margin.bottom) + 20; const x = isRotated ? -(1 + left) : -(left - 1); const y = -15; // -Math.max(15, margin.top); const w = isRotated ? margin.left + 20 : width + 10 + left; node .attr("x", x) .attr("y", y) .attr("width", w) .attr("height", h); }, /** * Set y Axis clipPath dimension * @param {d3Selection} node clipPath <rect> selection * @private */ setYAxisClipPath(node): void { const $$ = this; const {config, state: {margin, width, height}} = $$; const isRotated = config.axis_rotated; const left = Math.max(30, margin.left) - (isRotated ? 20 : 0); const isInner = config.axis_y_inner; const x = isInner && !isRotated ? (config.axis_y_label.text ? -20 : -1) : (isRotated ? -(1 + left) : -(left - 1)); const y = -(isRotated ? 20 : margin.top); const w = (isRotated ? width + 15 + left : margin.left + 20) + (isInner ? 20 : 0); const h = (isRotated ? margin.bottom + 10 : (margin.top + height)) + 10; node .attr("x", x) .attr("y", y) .attr("width", w) .attr("height", h); }, updateXAxisTickClip(): void { const $$ = this; const {config, state: {clip, xAxisHeight}, $el: {defs}} = $$; const newXAxisHeight = $$.getHorizontalAxisHeight("x"); if (defs && !clip.idXAxisTickTexts) { const clipId = `${clip.id}-xaxisticktexts`; $$.appendClip(defs, clipId); clip.pathXAxisTickTexts = $$.getClipPath(clip.idXAxisTickTexts); clip.idXAxisTickTexts = clipId; } if ( !config.axis_x_tick_multiline && $$.getAxisTickRotate("x") && newXAxisHeight !== xAxisHeight ) { $$.setXAxisTickClipWidth(); $$.setXAxisTickTextClipPathWidth(); } $$.state.xAxisHeight = newXAxisHeight; }, setXAxisTickClipWidth(): void { const $$ = this; const {config, state: {current: {maxTickSize}}} = $$; const xAxisTickRotate = $$.getAxisTickRotate("x"); if (!config.axis_x_tick_multiline && xAxisTickRotate) { const sinRotation = Math.sin(Math.PI / 180 * Math.abs(xAxisTickRotate)); maxTickSize.x.clipPath = ($$.getHorizontalAxisHeight("x") - 20) / sinRotation; } else { maxTickSize.x.clipPath = null; } }, setXAxisTickTextClipPathWidth(): void { const $$ = this; const {state: {clip, current}, $el: {svg}} = $$; if (svg) { svg.select(`#${clip.idXAxisTickTexts} rect`) .attr("width", current.maxTickSize.x.clipPath) .attr("height", 30); } } };