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 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
- let legendHeight = 0;
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
- legendHeight = 15 + legendRows * 20;
1722
- const LEGEND_START_Y = 300;
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 * 20;
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 = legendHeight > 0 ? legendHeight + 15 : 0;
1735
- const svgHeight = 280 + totalLegendSpace;
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(20, Math.round(512 / Math.log1p(wordCount)));
1772
- const minFontSize = Math.max(6, Math.round(maxFontSize / 10));
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; padding: 10px 0;">
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: `${hours}小时相似活跃分析`,
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: `${daysToAnalyse}天相似活跃分析`,
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")
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-chat-analyse",
3
3
  "description": "强大而全面的聊天数据分析插件。支持多维度统计(命令、发言、消息类型、活跃度),可生成发言排行、词云图,并提供完善的数据管理。",
4
- "version": "1.4.11",
4
+ "version": "1.4.13",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],