/** * {} * @author yutent * @date 2023/06/07 18:41:20 */ function html(strs, ...vals) { let output = '' for (let it of strs) { output += it + (vals.shift() ?? '') } return output } function text({ color, name, pc, idx }) { let y = 32 + ~~(idx / 2 + 1) * 36 let x1 = idx % 2 === 0 ? 27 : 227 let x2 = idx % 2 === 0 ? 44 : 244 return html` ${name} ${pc}% ` } function pie(langs = [], sum = 0, height) { // 圆心坐标 let cx = 540 let radius = ~~((height - 64) / 2) // 最小半径 let cy = radius + 48 let per = 0.25 let deg = per * 2 * Math.PI // 从90度开始计算 return langs .map((it, idx) => { // 扇形起始坐标 let r = +radius.toFixed(3) let lx = +(cx + Math.sin(deg) * r).toFixed(3) let ly = +(cy - Math.cos(deg) * r).toFixed(3) let nx, ny let _per = +(it.size / sum).toFixed(4) radius *= 1.05 per += _per deg = per * 2 * Math.PI nx = +(cx + Math.sin(deg) * r * (per > 0.5 ? 1 : -1)).toFixed(3) ny = +(cy - Math.cos(deg) * r).toFixed(3) return html` ` }) .join('') } export function render({ title = 'Most Used Languages', langs = [] } = {}) { let sum = langs.reduce((n, it) => n + it.size, 0) let height = ~~(langs.length / 2 + 1) * 36 + 32 if (height < 140) { height = 140 } return html` ${title} ${langs .map((it, idx) => text({ color: it.color, name: it.name, pc: +((100 * it.size) / sum).toFixed(2), idx }) ) .join('')} ${pie(langs, sum, height)} ` }