86 lines
2.6 KiB
JavaScript
86 lines
2.6 KiB
JavaScript
import { PLATFORMS } from "./sites.js";
|
|
|
|
export function analyzeKidsTrend(history) {
|
|
const platformTrends = PLATFORMS.map((platform) => platformTrend(history, platform.id));
|
|
const valued = platformTrends.filter((item) => item.latest_status === "ok");
|
|
const growing = valued.filter((item) => Number.isFinite(item.delta) && item.delta > 0);
|
|
const bestDelta = growing.length ? Math.max(...growing.map((item) => item.delta)) : 0;
|
|
const bestGrowthRate = growing.length ? Math.max(...growing.map((item) => item.growth_rate || 0)) : 0;
|
|
|
|
let verdict = "no_data";
|
|
let label = "暂无数值";
|
|
let recommendation = "先不关注";
|
|
|
|
if (valued.length > 0 && growing.length === 0) {
|
|
verdict = "new_signal";
|
|
label = "新有数值";
|
|
recommendation = "再采一次";
|
|
}
|
|
if (growing.length > 0) {
|
|
verdict = "rising";
|
|
label = "在增长";
|
|
recommendation = "继续观察";
|
|
}
|
|
if (growing.length >= 2 || bestGrowthRate >= 0.3 || bestDelta >= 300) {
|
|
verdict = "strong_growth";
|
|
label = "强增长";
|
|
recommendation = "重点跟踪";
|
|
}
|
|
if (valued.length >= 2 && verdict === "new_signal") {
|
|
verdict = "multi_platform";
|
|
label = "多平台有数";
|
|
recommendation = "值得观察";
|
|
}
|
|
|
|
return {
|
|
name: history?.name || "",
|
|
verdict,
|
|
label,
|
|
recommendation,
|
|
platforms_with_value: valued.length,
|
|
growing_platforms: growing.length,
|
|
best_delta: bestDelta,
|
|
best_growth_rate: bestGrowthRate,
|
|
platform_trends: Object.fromEntries(platformTrends.map((item) => [item.platform, item])),
|
|
};
|
|
}
|
|
|
|
function platformTrend(history, platformId) {
|
|
const row = history?.platforms?.[platformId] || {};
|
|
const runs = [...(history?.runs || [])].sort().reverse();
|
|
const values = [];
|
|
|
|
for (const run of runs) {
|
|
const value = row.values?.[run];
|
|
if (value?.status !== "ok") continue;
|
|
const number = Number(value.number);
|
|
if (!Number.isFinite(number)) continue;
|
|
values.push({
|
|
run,
|
|
raw: value.raw || String(value.number || ""),
|
|
number,
|
|
});
|
|
if (values.length >= 2) break;
|
|
}
|
|
|
|
const latest = values[0] || null;
|
|
const previous = values[1] || null;
|
|
const delta = latest && previous ? latest.number - previous.number : null;
|
|
const growthRate = Number.isFinite(delta) && previous?.number
|
|
? delta / previous.number
|
|
: null;
|
|
|
|
return {
|
|
platform: platformId,
|
|
latest_status: latest ? "ok" : "missing",
|
|
latest_raw: latest?.raw || "",
|
|
latest_number: latest?.number || "",
|
|
latest_run: latest?.run || "",
|
|
previous_raw: previous?.raw || "",
|
|
previous_number: previous?.number || "",
|
|
previous_run: previous?.run || "",
|
|
delta,
|
|
growth_rate: growthRate,
|
|
};
|
|
}
|