koishi-plugin-chat-analyse 1.4.11 → 1.4.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Renderer.d.ts +0 -7
- package/lib/index.js +18 -18
- package/package.json +1 -1
package/lib/Renderer.d.ts
CHANGED
|
@@ -71,13 +71,6 @@ export declare class Renderer {
|
|
|
71
71
|
* @returns {AsyncGenerator<Buffer>} - 一个异步生成器,每次迭代产出一张图片的 Buffer。
|
|
72
72
|
*/
|
|
73
73
|
renderList(data: ListRenderData, headers?: string[]): AsyncGenerator<Buffer>;
|
|
74
|
-
/**
|
|
75
|
-
* @public
|
|
76
|
-
* @method renderLineChart
|
|
77
|
-
* @description 将时间序列数据(如活跃度)渲染成一张基于 SVG 的折线图。支持单组或多组数据进行对比。
|
|
78
|
-
* @param {LineChartData} data - 包含标题、时间、数据系列和标签的对象。
|
|
79
|
-
* @returns {AsyncGenerator<Buffer>} - 一个异步生成器,产出渲染后的图片 Buffer。
|
|
80
|
-
*/
|
|
81
74
|
renderLineChart(data: LineChartData): AsyncGenerator<Buffer>;
|
|
82
75
|
/**
|
|
83
76
|
* @public
|
package/lib/index.js
CHANGED
|
@@ -1673,13 +1673,6 @@ var Renderer = class {
|
|
|
1673
1673
|
if (imageBuffer) yield imageBuffer;
|
|
1674
1674
|
}
|
|
1675
1675
|
}
|
|
1676
|
-
/**
|
|
1677
|
-
* @public
|
|
1678
|
-
* @method renderLineChart
|
|
1679
|
-
* @description 将时间序列数据(如活跃度)渲染成一张基于 SVG 的折线图。支持单组或多组数据进行对比。
|
|
1680
|
-
* @param {LineChartData} data - 包含标题、时间、数据系列和标签的对象。
|
|
1681
|
-
* @returns {AsyncGenerator<Buffer>} - 一个异步生成器,产出渲染后的图片 Buffer。
|
|
1682
|
-
*/
|
|
1683
1676
|
async *renderLineChart(data) {
|
|
1684
1677
|
const { title, time, series, labels } = data;
|
|
1685
1678
|
const seriesColors = series.map(() => {
|
|
@@ -1715,24 +1708,27 @@ var Renderer = class {
|
|
|
1715
1708
|
const points = s.data.map((value, index) => `${getX(index)},${getY(value)}`).join(" ");
|
|
1716
1709
|
svgElements += `<polyline points="${points}" fill="none" stroke="${color}" stroke-width="2"/>`;
|
|
1717
1710
|
});
|
|
1718
|
-
|
|
1711
|
+
const chartAreaHeight = 280;
|
|
1712
|
+
const legendMargin = 15;
|
|
1713
|
+
let legendBlockHeight = 0;
|
|
1719
1714
|
if (series.length > 1) {
|
|
1720
1715
|
const legendRows = Math.ceil(series.length / 3);
|
|
1721
|
-
|
|
1722
|
-
|
|
1716
|
+
const legendRowHeight = 20;
|
|
1717
|
+
legendBlockHeight = legendRows * legendRowHeight;
|
|
1718
|
+
const LEGEND_START_Y = chartAreaHeight + legendMargin;
|
|
1723
1719
|
const columnWidth = 560 / 3;
|
|
1724
1720
|
series.forEach((s, seriesIndex) => {
|
|
1725
1721
|
const rowIndex = Math.floor(seriesIndex / 3);
|
|
1726
1722
|
const colIndex = seriesIndex % 3;
|
|
1727
1723
|
const legendX = 40 + colIndex * columnWidth;
|
|
1728
|
-
const legendY = LEGEND_START_Y + rowIndex *
|
|
1724
|
+
const legendY = LEGEND_START_Y + rowIndex * legendRowHeight;
|
|
1729
1725
|
const color = seriesColors[seriesIndex % seriesColors.length];
|
|
1730
1726
|
svgElements += `<rect x="${legendX}" y="${legendY - 8}" width="12" height="8" fill="${color}" rx="2"/>`;
|
|
1731
1727
|
svgElements += `<text x="${legendX + 18}" y="${legendY}" font-size="12" fill="var(--text-color)">${s.name}</text>`;
|
|
1732
1728
|
});
|
|
1733
1729
|
}
|
|
1734
|
-
const totalLegendSpace =
|
|
1735
|
-
const svgHeight =
|
|
1730
|
+
const totalLegendSpace = legendBlockHeight > 0 ? legendMargin + legendBlockHeight + legendMargin : 0;
|
|
1731
|
+
const svgHeight = chartAreaHeight + totalLegendSpace;
|
|
1736
1732
|
const totalMessages = series.reduce((sum, s) => sum + s.data.reduce((a, b) => a + b, 0), 0);
|
|
1737
1733
|
const cardHtml = `
|
|
1738
1734
|
<div class="container" style="width: 600px;">
|
|
@@ -1768,8 +1764,8 @@ var Renderer = class {
|
|
|
1768
1764
|
const maxWeight = Math.max(...weights, 1);
|
|
1769
1765
|
const minWeight = Math.min(...weights);
|
|
1770
1766
|
const wordCount = words.length;
|
|
1771
|
-
const maxFontSize = Math.max(
|
|
1772
|
-
const minFontSize = Math.max(
|
|
1767
|
+
const maxFontSize = Math.max(32, Math.round(600 / Math.log1p(wordCount)));
|
|
1768
|
+
const minFontSize = Math.max(4, Math.round(maxFontSize / 10));
|
|
1773
1769
|
const cardHtml = `
|
|
1774
1770
|
<div class="container" style="width: 600px;">
|
|
1775
1771
|
<div class="header">
|
|
@@ -1777,7 +1773,7 @@ var Renderer = class {
|
|
|
1777
1773
|
<h1 class="title-text">${title}</h1>
|
|
1778
1774
|
<div class="time-label">${time.toLocaleString("zh-CN", { hour12: false })}</div>
|
|
1779
1775
|
</div>
|
|
1780
|
-
<div style="width: 600px; height: 600px; margin: auto;
|
|
1776
|
+
<div style="width: 600px; height: 600px; margin: auto;">
|
|
1781
1777
|
<canvas id="wordcloud-container" width="600" height="600"></canvas>
|
|
1782
1778
|
</div>
|
|
1783
1779
|
<script>${wordCloudScript}</script>
|
|
@@ -2427,16 +2423,19 @@ var Analyse = class {
|
|
|
2427
2423
|
const guildUsers = await this.ctx.database.get("analyse_user", { channelId: effectiveChannelId });
|
|
2428
2424
|
if (guildUsers.length < 2) return "暂无用户数据";
|
|
2429
2425
|
const selfUser = guildUsers.find((u) => u.userId === session.userId);
|
|
2426
|
+
if (!selfUser) return "暂无用户数据";
|
|
2430
2427
|
const guildUserUids = guildUsers.map((u) => u.uid);
|
|
2431
2428
|
const uidToNameMap = new Map(guildUsers.map((u) => [u.uid, u.userName]));
|
|
2429
|
+
const scopeDesc = { guildId: effectiveChannelId };
|
|
2432
2430
|
const until = /* @__PURE__ */ new Date();
|
|
2433
2431
|
let analysisConfig;
|
|
2434
2432
|
if (options.separate) {
|
|
2435
2433
|
const { hours } = options;
|
|
2434
|
+
const title = await generateTitle(this.ctx, scopeDesc, { main: "相似活跃分析", timeRange: hours, timeUnit: "小时" });
|
|
2436
2435
|
analysisConfig = {
|
|
2437
2436
|
points: hours,
|
|
2438
2437
|
since: new Date(until.getTime() - hours * import_koishi6.Time.hour),
|
|
2439
|
-
title
|
|
2438
|
+
title,
|
|
2440
2439
|
labels: Array.from({ length: hours }, (_, i) => String(new Date(until.getTime() - (hours - 1 - i) * import_koishi6.Time.hour).getHours())),
|
|
2441
2440
|
getIndex: /* @__PURE__ */ __name((timestamp) => {
|
|
2442
2441
|
const diff = until.getTime() - timestamp.getTime();
|
|
@@ -2451,10 +2450,11 @@ var Analyse = class {
|
|
|
2451
2450
|
const hoursToAnalyse = daysToAnalyse * 24;
|
|
2452
2451
|
const currentHour = until.getHours();
|
|
2453
2452
|
const labels = Array.from({ length: 24 }, (_, i) => String((currentHour - (23 - i) + 24) % 24));
|
|
2453
|
+
const title = await generateTitle(this.ctx, scopeDesc, { main: "相似活跃分析", timeRange: daysToAnalyse, timeUnit: "天" });
|
|
2454
2454
|
analysisConfig = {
|
|
2455
2455
|
points: 24,
|
|
2456
2456
|
since: new Date(until.getTime() - hoursToAnalyse * import_koishi6.Time.hour),
|
|
2457
|
-
title
|
|
2457
|
+
title,
|
|
2458
2458
|
labels,
|
|
2459
2459
|
getIndex: /* @__PURE__ */ __name((timestamp) => timestamp.getHours(), "getIndex"),
|
|
2460
2460
|
reorderVector: /* @__PURE__ */ __name((vector) => labels.map((label) => vector[parseInt(label)]), "reorderVector")
|