From d1e708cb808a1a283fd0d013e0b38dc056c8e056 Mon Sep 17 00:00:00 2001 From: yutent Date: Thu, 8 Jun 2023 12:45:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E7=94=BB=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/api.js | 11 +++--- lib/svg.js | 100 ++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 101 insertions(+), 10 deletions(-) diff --git a/apps/api.js b/apps/api.js index 524b4c0..1586b36 100644 --- a/apps/api.js +++ b/apps/api.js @@ -15,7 +15,6 @@ export default class Github extends Controller { async toplangsAction() { let { username, count = 6 } = this.request.get() let token = this.context.get('token') - let { data } = await fetch('https://api.github.com/graphql', { headers: { Authorization: 'Bearer ' + token, @@ -50,6 +49,12 @@ query { let dict = {} let langs = [] + if (count > 16) { + count = 16 + } else if (count < 2) { + count = 2 + } + nodes.forEach(it => { for (let lang of it.languages.edges) { if (dict[lang.node.name]) { @@ -67,8 +72,6 @@ query { langs.sort((a, b) => b.size - a.size) this.response.set('Content-Type', 'image/svg+xml') - this.response.end(render({})) - - // this.response.send(200, { langs: langs.slice(0, count) }) + this.response.end(render({ langs: langs.slice(0, count) })) } } diff --git a/lib/svg.js b/lib/svg.js index e02e35b..025bead 100644 --- a/lib/svg.js +++ b/lib/svg.js @@ -7,29 +7,117 @@ function html(strs, ...vals) { let output = '' for (let it of strs) { - output += it + (vals.shift() || '') + output += it + (vals.shift() ?? '') } return output } -export function render({ title = 'Most Used Languages' }) { +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)} ` }