koishi-plugin-chat-analyse 1.4.4 → 1.4.6

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
@@ -83,7 +83,7 @@ export declare class Renderer {
83
83
  * @public
84
84
  * @method renderWordCloud
85
85
  * @description 将词频数据渲染成一张词云图片,使用 Puppeteer 和 wordcloud2.js。
86
- * @param {WordCloudData} data - 包含标题、时间和词汇列表,以及从config传入的options。
86
+ * @param {WordCloudData} data - 包含标题、时间和词汇列表的对象。
87
87
  * @returns {AsyncGenerator<Buffer>} - 一个异步生成器,产出渲染后的图片 Buffer。
88
88
  */
89
89
  renderWordCloud(data: WordCloudData): AsyncGenerator<Buffer>;
package/lib/index.d.ts CHANGED
@@ -22,16 +22,6 @@ export interface Config {
22
22
  cacheRetentionDays: number;
23
23
  enableSimilarActivity: boolean;
24
24
  enableAutoBackup: boolean;
25
- fontFamily: string;
26
- minFontSize: number;
27
- maxFontSize: number;
28
- shape: string;
29
- gridSize: number;
30
- rotateRatio: number;
31
- minRotation: number;
32
- maxRotation: number;
33
- ellipticity: number;
34
- maskImage: string;
35
25
  }
36
26
  /** @description 插件的配置项定义 */
37
27
  export declare const Config: Schema<Config>;
package/lib/index.js CHANGED
@@ -1775,18 +1775,19 @@ var Renderer = class {
1775
1775
  * @public
1776
1776
  * @method renderWordCloud
1777
1777
  * @description 将词频数据渲染成一张词云图片,使用 Puppeteer 和 wordcloud2.js。
1778
- * @param {WordCloudData} data - 包含标题、时间和词汇列表,以及从config传入的options。
1778
+ * @param {WordCloudData} data - 包含标题、时间和词汇列表的对象。
1779
1779
  * @returns {AsyncGenerator<Buffer>} - 一个异步生成器,产出渲染后的图片 Buffer。
1780
1780
  */
1781
1781
  async *renderWordCloud(data) {
1782
1782
  const { title, time, words } = data;
1783
- const options = data.options;
1784
- if (!words?.length || !options) return;
1783
+ if (!words?.length) return;
1785
1784
  const wordsJson = JSON.stringify(words);
1786
1785
  const selectedPalette = this.COLOR_PALETTES[Math.floor(Math.random() * this.COLOR_PALETTES.length)];
1787
1786
  const weights = words.map((w) => w[1]);
1788
1787
  const maxWeight = Math.max(...weights, 1);
1789
1788
  const minWeight = Math.min(...weights);
1789
+ const MAX_FONT_SIZE = 64;
1790
+ const MIN_FONT_SIZE = 4;
1790
1791
  const cardHtml = `
1791
1792
  <div class="container">
1792
1793
  <div class="header">
@@ -1794,55 +1795,31 @@ var Renderer = class {
1794
1795
  <h1 class="title-text">${title}</h1>
1795
1796
  <div class="time-label">${time.toLocaleString("zh-CN", { hour12: false })}</div>
1796
1797
  </div>
1797
- <div style="width: 512px; height: 512px; margin: auto; position: relative;">
1798
- <canvas id="wordcloud-canvas" width="512" height="512"></canvas>
1799
- </div>
1798
+ <div id="wordcloud-container" style="width: 512px; height: 512px; margin: auto;"></div>
1800
1799
  <script>${wordCloudScript}</script>
1801
1800
  <script>
1802
- const canvas = document.getElementById('wordcloud-canvas');
1803
- const maskImageUrl = ${JSON.stringify(options.maskImage)};
1804
1801
  const palette = ${JSON.stringify(selectedPalette)};
1805
-
1806
- const wordCloudOptions = {
1807
- list: ${wordsJson},
1808
- fontFamily: ${JSON.stringify(options.fontFamily)},
1802
+ WordCloud(document.getElementById('wordcloud-container'), {
1803
+ fontFamily: '"Noto Sans CJK SC", "Arial", sans-serif',
1809
1804
  weightFactor: (size) => {
1810
- if (${maxWeight} === ${minWeight}) return (${options.minFontSize} + ${options.maxFontSize}) / 2;
1805
+ if (${maxWeight} === ${minWeight}) return (${MIN_FONT_SIZE} + ${MAX_FONT_SIZE}) / 2;
1811
1806
  const normalizedWeight = (size - ${minWeight}) / (${maxWeight} - ${minWeight});
1812
- return ${options.minFontSize} + normalizedWeight * (${options.maxFontSize} - ${options.minFontSize});
1807
+ return ${MIN_FONT_SIZE} + normalizedWeight * (${MAX_FONT_SIZE} - ${MIN_FONT_SIZE});
1813
1808
  },
1814
- color: () => palette[Math.floor(Math.random() * palette.length)],
1815
- shape: ${JSON.stringify(options.shape)},
1816
- gridSize: ${options.gridSize},
1817
- rotateRatio: ${options.rotateRatio},
1818
- minRotation: ${options.minRotation},
1819
- maxRotation: ${options.maxRotation},
1820
- ellipticity: ${options.ellipticity},
1821
- shuffle: true,
1822
- drawOutOfBoundWords: false,
1809
+ color: (word, weight, fontSize, distance, theta) => {
1810
+ return palette[Math.floor(Math.random() * palette.length)];
1811
+ },
1812
+ list: ${wordsJson},
1813
+ shape: 'square',
1814
+ gridSize: 1,
1815
+ ellipticity: 1,
1816
+ rotateRatio: 0.5,
1817
+ minRotation: Math.PI / 2,
1818
+ maxRotation: Math.PI / 2,
1823
1819
  backgroundColor: 'transparent',
1824
- };
1825
-
1826
- function drawWordCloud(isMasked) {
1827
- const finalOptions = { ...wordCloudOptions, clearCanvas: !isMasked };
1828
- WordCloud(canvas, finalOptions);
1829
- }
1830
-
1831
- if (maskImageUrl) {
1832
- const img = new Image();
1833
- img.crossOrigin = "anonymous";
1834
- img.onload = () => {
1835
- const ctx = canvas.getContext('2d');
1836
- ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
1837
- drawWordCloud(true);
1838
- };
1839
- img.onerror = () => {
1840
- drawWordCloud(false);
1841
- };
1842
- img.src = maskImageUrl;
1843
- } else {
1844
- drawWordCloud(false);
1845
- }
1820
+ clearCanvas: true,
1821
+ shuffle: true,
1822
+ });
1846
1823
  </script>
1847
1824
  </div>`;
1848
1825
  const fullHtml = `<!DOCTYPE html>
@@ -2550,19 +2527,7 @@ var Config3 = import_koishi7.Schema.intersect([
2550
2527
  enableAutoBackup: import_koishi7.Schema.boolean().default(false).description("启用自动备份"),
2551
2528
  enableWordCloud: import_koishi7.Schema.boolean().default(true).description("启用词云生成"),
2552
2529
  enableSimilarActivity: import_koishi7.Schema.boolean().default(true).description("启用相似活跃分析")
2553
- }).description("高级分析配置"),
2554
- import_koishi7.Schema.object({
2555
- ellipticity: import_koishi7.Schema.number().min(0).max(1).default(1).description("长宽比"),
2556
- rotateRatio: import_koishi7.Schema.number().min(0).max(1).default(0.5).description("旋转比"),
2557
- minRotation: import_koishi7.Schema.number().default(Math.PI / 2).description("最小旋转角"),
2558
- maxRotation: import_koishi7.Schema.number().default(Math.PI / 2).description("最大旋转角"),
2559
- minFontSize: import_koishi7.Schema.number().min(1).default(4).description("最小字号"),
2560
- maxFontSize: import_koishi7.Schema.number().min(1).default(64).description("最大字号"),
2561
- gridSize: import_koishi7.Schema.number().min(0).default(1).description("词云间距"),
2562
- fontFamily: import_koishi7.Schema.string().default('"Noto Sans CJK SC", "Arial", sans-serif').description("词云字体"),
2563
- shape: import_koishi7.Schema.union(["square", "circle", "cardioid", "diamond", "triangle-forward", "triangle", "pentagon", "star"]).default("square").description("词云形状"),
2564
- maskImage: import_koishi7.Schema.string().role("link").description("词云蒙版")
2565
- }).description("词云生成配置")
2530
+ }).description("高级分析配置")
2566
2531
  ]);
2567
2532
  async function parseQueryScope(ctx, session, options) {
2568
2533
  const scopeDesc = { guildId: options.guild, userId: void 0 };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-chat-analyse",
3
3
  "description": "强大而全面的聊天数据分析插件。支持多维度统计(命令、发言、消息类型、活跃度),可生成发言排行、词云图,并提供完善的数据管理。",
4
- "version": "1.4.4",
4
+ "version": "1.4.6",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],
@@ -35,7 +35,7 @@
35
35
  "koishi-plugin-puppeteer": "^3.5.2"
36
36
  },
37
37
  "peerDependencies": {
38
- "koishi": "4.18.8"
38
+ "koishi": "^4.18.8"
39
39
  },
40
40
  "dependencies": {
41
41
  "@node-rs/jieba": "^2.0.1"
package/readme.md CHANGED
@@ -156,21 +156,6 @@
156
156
  `enableSimilarActivity`: **启用相似活跃分析**。
157
157
  > **!** 此功能依赖 **`启用发言排行`** 或 **`启用活跃统计`**。 (默认: `true`)
158
158
 
159
- ### 词云生成配置
160
-
161
- | 配置项 | 描述 | 默认值 |
162
- | :--- | :--- | :--- |
163
- | `maskImage` | **词云蒙版**:提供一个图片的URL作为词云的形状蒙版。**注意:这会覆盖“基础形状”选项。** | (空) |
164
- | `fontFamily` | **词云字体**:用于渲染词云的字体列表。 | `"Noto Sans CJK SC", "Arial", sans-serif` |
165
- | `minFontSize` | **最小字号**:权重最小的单词所使用的字号。 | `4` |
166
- | `maxFontSize` | **最大字号**:权重最大的单词所使用的字号。 | `64` |
167
- | `gridSize` | **词云间距**:用于分隔单词的网格大小(像素)。值越大,单词间距越大。 | `1` |
168
- | `shape` | **基础形状**:选择词云的整体轮廓(无蒙版时生效)。 | `square` |
169
- | `ellipticity` | **长宽比**:当形状为“椭圆”时,定义其扁平程度。值越小越扁。 | `1` |
170
- | `rotateRatio` | **旋转比**:随机旋转的单词所占的比例(0 到 1)。 | `0.5` |
171
- | `minRotation` | **最小旋转角**:单词随机旋转的最小角度(弧度)。 | `1.570796` (π/2) |
172
- | `maxRotation` | **最大旋转角**:单词随机旋转的最大角度(弧度)。 | `1.570796` (π/2) |
173
-
174
159
  ## 📌 注意事项
175
160
 
176
161
  1. **Puppeteer 配置**:本插件的图片渲染强依赖 `puppeteer` 服务。请确保您已正确安装并配置了该服务,包括正确设置了可执行文件路径(如有需要)。渲染失败通常与此有关。