koishi-plugin-chat-analyse 1.5.0 → 1.5.2

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,6 +71,13 @@ 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
+ */
74
81
  renderLineChart(data: LineChartData): AsyncGenerator<Buffer>;
75
82
  /**
76
83
  * @public
package/lib/index.d.ts CHANGED
@@ -19,6 +19,7 @@ export interface Config {
19
19
  atRetentionDays: number;
20
20
  rankRetentionDays: number;
21
21
  enableWordCloud: boolean;
22
+ MaxWords: number;
22
23
  cacheRetentionDays: number;
23
24
  enableSimilarActivity: boolean;
24
25
  enableAutoBackup: boolean;
package/lib/index.js CHANGED
@@ -1673,6 +1673,13 @@ 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
+ */
1676
1683
  async *renderLineChart(data) {
1677
1684
  const { title, time, series, labels } = data;
1678
1685
  const seriesColors = series.map(() => {
@@ -1764,8 +1771,11 @@ var Renderer = class {
1764
1771
  const maxWeight = Math.max(...weights, 1);
1765
1772
  const minWeight = Math.min(...weights);
1766
1773
  const wordCount = words.length;
1767
- const maxFontSize = Math.max(32, Math.round(600 / Math.log1p(wordCount)));
1768
- const minFontSize = Math.max(4, Math.round(maxFontSize / 10));
1774
+ const area = 600 * 600;
1775
+ const avgAreaPerWord = area / wordCount;
1776
+ let maxFontSize = Math.round(Math.sqrt(avgAreaPerWord) * 1.8);
1777
+ maxFontSize = Math.max(16, Math.min(160, maxFontSize));
1778
+ const minFontSize = Math.max(4, Math.round(maxFontSize / 8));
1769
1779
  const cardHtml = `
1770
1780
  <div class="container" style="width: 600px;">
1771
1781
  <div class="header">
@@ -1794,7 +1804,8 @@ var Renderer = class {
1794
1804
  maxRotation: ${config.maxRotation},
1795
1805
  rotationSteps: ${config.rotationSteps},
1796
1806
  backgroundColor: 'transparent',
1797
- clearCanvas: true,
1807
+ drawOutOfBound: true,
1808
+ clearCanvas: false,
1798
1809
  shrinkToFit: true,
1799
1810
  rotateRatio: 1,
1800
1811
  shuffle: true,
@@ -2404,10 +2415,11 @@ var Analyse = class {
2404
2415
  if (!words.length) return "暂无有效词语";
2405
2416
  const wordCounts = words.reduce((map, word) => map.set(word, (map.get(word) || 0) + 1), /* @__PURE__ */ new Map());
2406
2417
  const wordList = Array.from(wordCounts.entries()).sort((a, b) => b[1] - a[1]);
2407
- const topWordsPreview = wordList.slice(0, 10).map((item) => item[0]).join(", ");
2408
- session.send(`正在生成词云,热门词汇:${topWordsPreview}...`);
2418
+ const limitedWordList = this.config.MaxWords > 0 ? wordList.slice(0, this.config.MaxWords) : wordList;
2419
+ const topWordsPreview = limitedWordList.slice(0, 10).map((item) => item[0]).join(", ");
2420
+ session.send(`正在基于 ${wordList.length} 个词生成词云:${topWordsPreview}...`);
2409
2421
  const title = await generateTitle(this.ctx, scope.scopeDesc, { main: "词云", timeRange: options.hours });
2410
- const imageGenerator = this.renderer.renderWordCloud({ title, time: /* @__PURE__ */ new Date(), words: wordList }, this.config);
2422
+ const imageGenerator = this.renderer.renderWordCloud({ title, time: /* @__PURE__ */ new Date(), words: limitedWordList }, this.config);
2411
2423
  for await (const buffer of imageGenerator) await session.send(import_koishi6.h.image(buffer, "image/png"));
2412
2424
  } catch (error) {
2413
2425
  this.ctx.logger.error("生成词云图片失败:", error);
@@ -2528,12 +2540,13 @@ var Config3 = import_koishi7.Schema.intersect([
2528
2540
  enableSimilarActivity: import_koishi7.Schema.boolean().default(true).description("启用相似活跃分析")
2529
2541
  }).description("高级分析配置"),
2530
2542
  import_koishi7.Schema.object({
2543
+ MaxWords: import_koishi7.Schema.number().min(0).default(0).description("最大词量"),
2531
2544
  ellipticity: import_koishi7.Schema.number().min(0).max(1).default(1).description("长宽比"),
2532
2545
  rotationSteps: import_koishi7.Schema.number().min(0).default(3).description("旋转步数"),
2533
2546
  minRotation: import_koishi7.Schema.number().default(-Math.PI / 2).description("最小旋转角"),
2534
2547
  maxRotation: import_koishi7.Schema.number().default(Math.PI / 2).description("最大旋转角"),
2535
- color: import_koishi7.Schema.string().default("random-light").description("词云颜色"),
2536
2548
  shape: import_koishi7.Schema.string().default("square").description("词云形状"),
2549
+ color: import_koishi7.Schema.string().default("random-light").description("词云颜色"),
2537
2550
  fontFamily: import_koishi7.Schema.string().default('"Noto Sans CJK SC", Arial, sans-serif').description("词云字体"),
2538
2551
  maskImage: import_koishi7.Schema.string().role("link").description("蒙版图片")
2539
2552
  }).description("词云生成配置")
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-chat-analyse",
3
3
  "description": "强大而全面的聊天数据分析插件。支持多维度统计(命令、发言、消息类型、活跃度),可生成发言排行、词云图,并提供完善的数据管理。",
4
- "version": "1.5.0",
4
+ "version": "1.5.2",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],