koishi-plugin-chat-analyse 1.3.4 → 1.3.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.
Files changed (3) hide show
  1. package/lib/index.js +52 -27
  2. package/package.json +1 -1
  3. package/readme.md +1 -0
package/lib/index.js CHANGED
@@ -1487,20 +1487,22 @@ var Renderer = class {
1487
1487
  __name(this, "Renderer");
1488
1488
  }
1489
1489
  COLOR_PALETTES = [
1490
- // 1. Oceanic: 深邃的海洋蓝与青色系,沉稳专业
1491
- ["#003f5c", "#2f4b7c", "#0077b6", "#023e8a", "#2a6f97", "#0096c7"],
1492
- // 2. Sunset: 充满活力的日落色系,温暖而醒目
1493
- ["#c1121f", "#d9501e", "#e36414", "#9a031e", "#5f0f40", "#fb8500"],
1494
- // 3. Forest: 茂密森林的绿色系,自然且舒适
1495
- ["#1b4332", "#2d6a4f", "#40916c", "#52b788", "#283618", "#081c15"],
1496
- // 4. Grape: 浓郁的葡萄与浆果色系,高贵而神秘
1497
- ["#4a0072", "#6a00a8", "#810099", "#c71585", "#58004f", "#3d0c4c"],
1498
- // 5. Candy: 甜美的糖果色系,活泼有趣
1499
- ["#e63946", "#f77f00", "#2a9d8f", "#457b9d", "#8d99ae", "#d62828"],
1500
- // 6. Retro: 复古风格色盘,兼具沉稳与活力
1501
- ["#264653", "#2a9d8f", "#e76f51", "#f4a261", "#bc6c25", "#a56c03"],
1502
- // 7. Midnight: 深邃的午夜色系,搭配亮色点缀,对比强烈
1503
- ["#03045e", "#0077b6", "#00b4d8", "#d00000", "#e85d04", "#212529"]
1490
+ // 1. Oceanic Blues: 宁静的蓝色系,适合专业、冷静的图表
1491
+ ["#CAF0F8", "#90E0EF", "#00B4D8", "#0077B6", "#03045E"],
1492
+ // 2. Forest Greens: 自然的绿色系,代表成长与和谐
1493
+ ["#D8F3DC", "#95D5B2", "#52B788", "#2D6A4F", "#1B4332"],
1494
+ // 3. Royal Purples: 优雅的紫色系,带有一丝神秘感
1495
+ ["#E0AAFF", "#C77DFF", "#9D4EDD", "#7B2CBF", "#5A189A"],
1496
+ // 4. Sunset Oranges: 温暖的橙色系,充满活力与热情
1497
+ ["#FFF3B0", "#FFD670", "#FFB703", "#F8961E", "#E85D04"],
1498
+ // 5. Vivid Candy: 鲜艳的糖果色,活泼、醒目
1499
+ ["#E63946", "#F1FAEE", "#A8DADC", "#457B9D", "#1D3557"],
1500
+ // 6. Retro Groove: 复古风格,兼具沉稳与活力
1501
+ ["#264653", "#2A9D8F", "#E9C46A", "#F4A261", "#E76F51"],
1502
+ // 7. Pastel Rainbow: 温和的彩虹色,柔和、美观
1503
+ ["#FFADAD", "#FDFFB6", "#CAFFBF", "#9BF6FF", "#A0C4FF"],
1504
+ // 8. Bold & Contrasting: 大胆的撞色,对比强烈,引人注目
1505
+ ["#D00000", "#FFBA08", "#3F88C5", "#032B43", "#136F63"]
1504
1506
  ];
1505
1507
  COMMON_STYLE = `
1506
1508
  :root {
@@ -1691,12 +1693,12 @@ var Renderer = class {
1691
1693
  */
1692
1694
  async *renderLineChart(data) {
1693
1695
  const { title, time, series, labels } = data;
1694
- const seriesColors = series.map(() => {
1695
- const randomPalette = this.COLOR_PALETTES[Math.floor(Math.random() * this.COLOR_PALETTES.length)];
1696
- return randomPalette[Math.floor(Math.random() * randomPalette.length)];
1697
- });
1698
- const width = 600, height = 320;
1699
- const padding = { top: 20, right: 30, bottom: 80, left: 40 };
1696
+ const colorfulPalettes = this.COLOR_PALETTES.slice(4);
1697
+ const selectedPalette = colorfulPalettes[Math.floor(Math.random() * colorfulPalettes.length)];
1698
+ const shuffledColors = [...selectedPalette].sort(() => 0.5 - Math.random());
1699
+ const seriesColors = series.map((_, index) => shuffledColors[index % shuffledColors.length]);
1700
+ const width = 600, height = 300;
1701
+ const padding = { top: 15, right: 15, bottom: 60, left: 25 };
1700
1702
  const chartWidth = width - padding.left - padding.right;
1701
1703
  const chartHeight = height - padding.top - padding.bottom;
1702
1704
  const maxVal = Math.max(1, ...series.flatMap((s) => s.data));
@@ -2316,12 +2318,29 @@ var Analyse = class {
2316
2318
  });
2317
2319
  }
2318
2320
  if (this.config.enableSimilarActivity) {
2319
- cmd.subcommand("simiactive", "相似活跃分析").usage("分析你和群友的活跃度,找出谁和你的活跃度最相似。").option("hours", "-n <hours:number> 指定分析时长(小时)", { fallback: 24 }).action(async ({ session, options }) => {
2321
+ cmd.subcommand("simiactive", "相似活跃分析").usage("分析你和群友的活跃度,找出谁和你的活跃度最相似。").option("hours", "-n <hours:number> 指定时长", { fallback: 24 }).option("separate", "-p 分时分析").action(async ({ session, options }) => {
2320
2322
  if (!session.guildId) return "请在群组中使用此命令";
2321
2323
  try {
2322
2324
  const until = /* @__PURE__ */ new Date();
2323
- const since = new Date(until.getTime() - options.hours * import_koishi6.Time.hour);
2324
- const points = options.hours;
2325
+ let since;
2326
+ let points;
2327
+ let title;
2328
+ let labels;
2329
+ let daysToAnalyze = 0;
2330
+ if (options.separate) {
2331
+ points = options.hours;
2332
+ since = new Date(until.getTime() - options.hours * import_koishi6.Time.hour);
2333
+ title = `${options.hours}小时相似活跃分析`;
2334
+ labels = Array.from({ length: points }, (_, i) => String(new Date(until.getTime() - (points - 1 - i) * import_koishi6.Time.hour).getHours()));
2335
+ } else {
2336
+ daysToAnalyze = Math.floor(options.hours / 24);
2337
+ if (daysToAnalyze < 1) return "请指定至少 24 小时时长";
2338
+ const analysisDurationHours = daysToAnalyze * 24;
2339
+ since = new Date(until.getTime() - analysisDurationHours * import_koishi6.Time.hour);
2340
+ points = 24;
2341
+ title = `${daysToAnalyze}天相似活跃分析`;
2342
+ labels = Array.from({ length: 24 }, (_, i) => String(i));
2343
+ }
2325
2344
  const guildUsers = await this.ctx.database.get("analyse_user", { channelId: session.guildId });
2326
2345
  if (guildUsers.length < 2) return "暂无用户数据";
2327
2346
  const selfUser = guildUsers.find((u) => u.userId === session.userId);
@@ -2332,12 +2351,20 @@ var Analyse = class {
2332
2351
  const activityVectors = /* @__PURE__ */ new Map();
2333
2352
  guildUserUids.forEach((uid) => activityVectors.set(uid, Array(points).fill(0)));
2334
2353
  records.forEach((stat) => {
2335
- const diff = until.getTime() - stat.timestamp.getTime();
2336
- const index = points - 1 - Math.floor(diff / import_koishi6.Time.hour);
2354
+ let index;
2355
+ if (options.separate) {
2356
+ const diff = until.getTime() - stat.timestamp.getTime();
2357
+ index = points - 1 - Math.floor(diff / import_koishi6.Time.hour);
2358
+ } else {
2359
+ index = stat.timestamp.getHours();
2360
+ }
2337
2361
  if (index >= 0 && index < points) {
2338
2362
  activityVectors.get(stat.uid)[index] += stat.count;
2339
2363
  }
2340
2364
  });
2365
+ if (!options.separate && daysToAnalyze > 0) activityVectors.forEach((vector) => {
2366
+ for (let i = 0; i < vector.length; i++) vector[i] = vector[i] / daysToAnalyze;
2367
+ });
2341
2368
  const selfVector = activityVectors.get(selfUser.uid);
2342
2369
  if (!selfVector || selfVector.every((v) => v === 0)) return "暂无统计数据";
2343
2370
  const similarities = guildUserUids.filter((uid) => uid !== selfUser.uid && !activityVectors.get(uid).every((v) => v === 0)).map((uid) => ({ uid, score: cosineSimilarity(selfVector, activityVectors.get(uid)) })).sort((a, b) => b.score - a.score);
@@ -2348,8 +2375,6 @@ var Analyse = class {
2348
2375
  const name2 = uidToNameMap.get(sim.uid) || `UID ${sim.uid}`;
2349
2376
  series.push({ name: `${name2} (${(sim.score * 100).toFixed(1)}%)`, data: activityVectors.get(sim.uid) });
2350
2377
  });
2351
- const labels = Array.from({ length: points }, (_, i) => String(new Date(until.getTime() - (points - 1 - i) * import_koishi6.Time.hour).getHours()));
2352
- const title = `${options.hours}小时相似活跃分析`;
2353
2378
  const imageGenerator = this.renderer.renderLineChart({ title, time: /* @__PURE__ */ new Date(), series, labels });
2354
2379
  for await (const buffer of imageGenerator) await session.send(import_koishi6.h.image(buffer, "image/png"));
2355
2380
  } catch (error) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-chat-analyse",
3
3
  "description": "强大而全面的聊天数据分析,支持统计命令,发言,消息类型,活跃度,支持发言排行和生成词云",
4
- "version": "1.3.4",
4
+ "version": "1.3.6",
5
5
  "contributors": [
6
6
  "Yis_Rime <yis_rime@outlook.com>"
7
7
  ],
package/readme.md CHANGED
@@ -102,6 +102,7 @@
102
102
  - **`simiactive`**: 在**当前群组**中,分析最近 **24 小时**内与您作息最相似的群友。
103
103
  - **`simiactive -n 48`**: 指定分析最近 **48 小时**的数据。
104
104
  - **选项 `-n, --hours <小时数>`**: 指定查询范围的时长,默认为 `24`。
105
+ - **选项 `-p, --separate`**: 分离小时数据,不按天聚合进行分析。
105
106
 
106
107
  ## 🔧 配置项
107
108