billboard.js
Version:
Re-usable easy interface JavaScript chart library, based on D3 v4+
143 lines (141 loc) • 4.51 kB
JavaScript
/*!
* 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
*/
/**
* Copyright (c) 2017 ~ present NAVER Corp.
* billboard.js project is licensed under the MIT license
*/
/**
* Convert shared shape point coordinates into renderer coordinates.
* Shared geometry keeps the x-index coordinate first and value coordinate second.
* Rotated axes swap those on screen.
* @param {object} $$ ChartInternal instance
* @param {Array} point Shared shape point
* @returns {Array} Render x/y point
* @private
*/
function getRenderPoint($$, point) {
return $$.config.axis_rotated ? [point[1], point[0]] : [point[0], point[1]];
}
/**
* Get a render rectangle from shared shape points.
* @param {object} $$ ChartInternal instance
* @param {Array} points Shared shape points
* @param {number} minSize Minimum rendered width/height
* @returns {object} Render rectangle
* @private
*/
function getRenderRect($$, points, minSize = 1) {
const renderPoints = points.map(point => getRenderPoint($$, point));
const xs = renderPoints.map(([x]) => x);
const ys = renderPoints.map(([, y]) => y);
const rawX = Math.min(...xs);
const rawY = Math.min(...ys);
const rawW = Math.max(...xs) - rawX;
const rawH = Math.max(...ys) - rawY;
const w = Math.max(minSize, rawW);
const h = Math.max(minSize, rawH);
return {
x: rawX - ((w - rawW) / 2),
y: rawY - ((h - rawH) / 2),
w,
h
};
}
/**
* Get renderer coordinates for a data point.
* @param {object} $$ ChartInternal instance
* @param {object} d Data row
* @returns {object} Render x/y point
* @private
*/
function getRenderDataPoint($$, d) {
const value = $$.isGrouped?.(d.id) && $$.circleY ?
$$.circleY(d, d.index) :
$$.getYScaleById(d.id)($$.getBaseValue(d));
const index = $$.xx(d) ?? NaN;
return $$.config.axis_rotated ? { x: value, y: index } : { x: index, y: value };
}
/**
* Get point coordinates from shared shape position accessors.
* @param {object} pos Shape position accessors
* @param {object} d Data row
* @param {number} i Data index
* @returns {object} Render x/y point
* @private
*/
function getShapePoint(pos, d, i) {
return {
x: pos.cx(d, i),
y: pos.cy(d, i)
};
}
/**
* Get candlestick body and wick coordinates from shared points.
* @param {object} $$ ChartInternal instance
* @param {Array} points Shared candlestick points
* @returns {object} Candlestick render geometry
* @private
*/
function getCandlestickGeometry($$, points) {
return {
body: getRenderRect($$, [points[0], points[1]]),
wickStart: getRenderPoint($$, [points[2][0], points[2][1]]),
wickEnd: getRenderPoint($$, [points[2][0], points[2][2]])
};
}
/**
* Get treemap node rectangle.
* @param {object} $$ ChartInternal instance
* @param {object} node Treemap hierarchy node
* @param {object} root Root hierarchy node
* @param {boolean} clamp Whether negative dimensions should be clamped to zero
* @returns {object} Treemap render rectangle
* @private
*/
function getTreemapNodeRect($$, node, root, clamp = false) {
if (node === root) {
return {
x: 0,
y: 0,
w: $$.state.width,
h: 0
};
}
const { scale: { x, y } } = $$;
const left = x(node.x0);
const top = y(node.y0);
const w = x(node.x1) - left;
const h = y(node.y1) - top;
return {
x: left,
y: top,
w: clamp ? Math.max(0, w) : w,
h: clamp ? Math.max(0, h) : h
};
}
/**
* Get treemap label text.
* @param {object} $$ ChartInternal instance
* @param {object} data Treemap node data
* @param {number} width Tile width
* @param {number} height Tile height
* @returns {string|null} Label text
* @private
*/
function getTreemapLabelText($$, data, width, height) {
const { config } = $$;
const { id, value, ratio = 0 } = data;
const format = config.treemap_label_format;
const text = typeof format === "function" ?
format.bind($$.api)(value, ratio, id, { width, height }) :
`${id}\n${(ratio * 100).toFixed(2)}%`;
return text === null || text === undefined ? null : String(text);
}
export { getCandlestickGeometry, getRenderDataPoint, getRenderPoint, getRenderRect, getShapePoint, getTreemapLabelText, getTreemapNodeRect };