billboard.js
Version:
Re-usable easy interface JavaScript chart library, based on D3 v4+
158 lines (130 loc) • 4.02 kB
text/typescript
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
import {AxisType} from "../../../types/types";
export default {
/**
* Get Axis size according its position
* @param {string} id Axis id value - x, y or y2
* @returns {number} size Axis size value
* @private
*/
getAxisSize(id: AxisType): number {
const $$ = this;
const isRotated = $$.config.axis_rotated;
return (isRotated && id === "x") || (!isRotated && /y2?/.test(id)) ?
$$.getAxisWidthByAxisId(id, true) :
$$.getHorizontalAxisHeight(id);
},
getAxisWidthByAxisId(id: AxisType, withoutRecompute?: boolean): number {
const $$ = this;
if ($$.axis) {
const position = $$.axis?.getLabelPositionById(id);
return $$.axis.getMaxTickWidth(id, withoutRecompute) +
(position.isInner ? 20 : 40);
} else {
return 40;
}
},
getHorizontalAxisHeight(id: AxisType): number {
const $$ = this;
const {config, state} = $$;
const {current, rotatedPadding, isLegendRight, isLegendInset} = state;
const isRotated = config.axis_rotated;
let h = 30;
if (id === "x" && !config.axis_x_show) {
return 8;
}
if (id === "x" && config.axis_x_height) {
return config.axis_x_height;
}
if (id === "y" && !config.axis_y_show) {
return config.legend_show &&
!isLegendRight &&
!isLegendInset ? 10 : 1;
}
if (id === "y2" && !config.axis_y2_show) {
return rotatedPadding.top;
}
const rotate = $$.getAxisTickRotate(id);
// Calculate x/y axis height when tick rotated
if (
((id === "x" && !isRotated) || (/y2?/.test(id) && isRotated)) && rotate
) {
h = 30 +
$$.axis.getMaxTickWidth(id) *
Math.cos(Math.PI * (90 - Math.abs(rotate)) / 180);
if (!config.axis_x_tick_multiline && current.height) {
if (h > current.height / 2) {
h = current.height / 2;
}
}
}
return h +
($$.axis.getLabelPositionById(id).isInner ? 0 : 10) +
(id === "y2" && !isRotated ? -10 : 0);
},
getEventRectWidth(): number {
return Math.max(0, this.axis.x.tickInterval());
},
/**
* Get axis tick test rotate value
* @param {string} id Axis id
* @returns {number} rotate value
* @private
*/
getAxisTickRotate(id: AxisType): number {
const $$ = this;
const {axis, config, state, $el} = $$;
let rotate = config[`axis_${id}_tick_rotate`];
if (id === "x") {
const allowedXAxisTypes = axis.isCategorized() || axis.isTimeSeries();
if (config.axis_x_tick_fit && allowedXAxisTypes) {
const xTickCount = config.axis_x_tick_count;
const currentXTicksLength = state.current.maxTickWidths.x.ticks.length;
let tickCount = 0;
if (xTickCount) {
tickCount = xTickCount > currentXTicksLength ? currentXTicksLength : xTickCount;
} else if (currentXTicksLength) {
tickCount = currentXTicksLength;
}
if (tickCount !== state.axis.x.tickCount) {
const {targets} = $$.data;
state.axis.x.padding = $$.getXDomainPadding([
$$.getXDomainMinMax(targets, "min"),
$$.getXDomainMinMax(targets, "max")
], tickCount);
}
state.axis.x.tickCount = tickCount;
}
if ($el.svg &&
config.axis_x_tick_fit &&
!config.axis_x_tick_multiline &&
!config.axis_x_tick_culling &&
config.axis_x_tick_autorotate &&
allowedXAxisTypes
) {
rotate = $$.needToRotateXAxisTickTexts() ?
config.axis_x_tick_rotate : 0;
}
}
return rotate;
},
/**
* Check weather axis tick text needs to be rotated
* @returns {boolean}
* @private
*/
needToRotateXAxisTickTexts(): boolean {
const $$ = this;
const {state: {axis, current}} = $$;
const xAxisLength = current.width -
$$.getCurrentPaddingLeft(false) - $$.getCurrentPaddingRight();
const tickCountWithPadding = axis.x.tickCount +
axis.x.padding.left + axis.x.padding.right;
const maxTickWidth = $$.axis.getMaxTickWidth("x");
const tickLength = tickCountWithPadding ? xAxisLength / tickCountWithPadding : 0;
return maxTickWidth > tickLength;
}
};