koishi-plugin-chat-analyse 1.4.15 → 1.5.1
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 +7 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +21 -7
- package/package.json +1 -1
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
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
|
|
1768
|
-
const
|
|
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,8 +1804,10 @@ var Renderer = class {
|
|
|
1794
1804
|
maxRotation: ${config.maxRotation},
|
|
1795
1805
|
rotationSteps: ${config.rotationSteps},
|
|
1796
1806
|
backgroundColor: 'transparent',
|
|
1797
|
-
|
|
1807
|
+
drawOutOfBound: true,
|
|
1808
|
+
clearCanvas: false,
|
|
1798
1809
|
shrinkToFit: true,
|
|
1810
|
+
abortThreshold: 1,
|
|
1799
1811
|
rotateRatio: 1,
|
|
1800
1812
|
shuffle: true,
|
|
1801
1813
|
gridSize: 1,
|
|
@@ -2404,10 +2416,11 @@ var Analyse = class {
|
|
|
2404
2416
|
if (!words.length) return "暂无有效词语";
|
|
2405
2417
|
const wordCounts = words.reduce((map, word) => map.set(word, (map.get(word) || 0) + 1), /* @__PURE__ */ new Map());
|
|
2406
2418
|
const wordList = Array.from(wordCounts.entries()).sort((a, b) => b[1] - a[1]);
|
|
2407
|
-
const
|
|
2408
|
-
|
|
2419
|
+
const limitedWordList = this.config.MaxWords > 0 ? wordList.slice(0, this.config.MaxWords) : wordList;
|
|
2420
|
+
const topWordsPreview = limitedWordList.slice(0, 10).map((item) => item[0]).join(", ");
|
|
2421
|
+
session.send(`正在基于 ${wordList.length} 个词生成词云:${topWordsPreview}...`);
|
|
2409
2422
|
const title = await generateTitle(this.ctx, scope.scopeDesc, { main: "词云", timeRange: options.hours });
|
|
2410
|
-
const imageGenerator = this.renderer.renderWordCloud({ title, time: /* @__PURE__ */ new Date(), words:
|
|
2423
|
+
const imageGenerator = this.renderer.renderWordCloud({ title, time: /* @__PURE__ */ new Date(), words: limitedWordList }, this.config);
|
|
2411
2424
|
for await (const buffer of imageGenerator) await session.send(import_koishi6.h.image(buffer, "image/png"));
|
|
2412
2425
|
} catch (error) {
|
|
2413
2426
|
this.ctx.logger.error("生成词云图片失败:", error);
|
|
@@ -2528,12 +2541,13 @@ var Config3 = import_koishi7.Schema.intersect([
|
|
|
2528
2541
|
enableSimilarActivity: import_koishi7.Schema.boolean().default(true).description("启用相似活跃分析")
|
|
2529
2542
|
}).description("高级分析配置"),
|
|
2530
2543
|
import_koishi7.Schema.object({
|
|
2544
|
+
MaxWords: import_koishi7.Schema.number().min(0).default(0).description("最大词量"),
|
|
2531
2545
|
ellipticity: import_koishi7.Schema.number().min(0).max(1).default(1).description("长宽比"),
|
|
2532
2546
|
rotationSteps: import_koishi7.Schema.number().min(0).default(3).description("旋转步数"),
|
|
2533
2547
|
minRotation: import_koishi7.Schema.number().default(-Math.PI / 2).description("最小旋转角"),
|
|
2534
2548
|
maxRotation: import_koishi7.Schema.number().default(Math.PI / 2).description("最大旋转角"),
|
|
2535
|
-
color: import_koishi7.Schema.string().default("random-light").description("词云颜色"),
|
|
2536
2549
|
shape: import_koishi7.Schema.string().default("square").description("词云形状"),
|
|
2550
|
+
color: import_koishi7.Schema.string().default("random-light").description("词云颜色"),
|
|
2537
2551
|
fontFamily: import_koishi7.Schema.string().default('"Noto Sans CJK SC", Arial, sans-serif').description("词云字体"),
|
|
2538
2552
|
maskImage: import_koishi7.Schema.string().role("link").description("蒙版图片")
|
|
2539
2553
|
}).description("词云生成配置")
|