Kaynağa Gözat

修改全局热度展示

xueyiming 1 hafta önce
ebeveyn
işleme
7f2eca4d51

+ 13 - 4
web/src/types/category.ts

@@ -83,13 +83,13 @@ export function collectWeights(
   return out
 }
 
-/** Build ascending-sorted unique values for percentile lookup. */
+/** Build ascending-sorted values for percentile / min-max lookup in this tab. */
 export function buildWeightScale(values: number[]): number[] {
   if (!values.length) return []
   return values.slice().sort((a, b) => a - b)
 }
 
-/** Percentile of avg among nodes with data; null when no scale. */
+/** Percentile heat t in [0, 1] among nodes with data in this tab. */
 export function weightHeatT(weight: number, sortedScale: number[]): number | null {
   if (!sortedScale.length) return null
   const n = sortedScale.length
@@ -104,14 +104,23 @@ export function weightHeatT(weight: number, sortedScale: number[]): number | nul
   return Math.min(1, Math.max(0, lo / n))
 }
 
-/** Global score is the sum of four [0, 1] rank scores, so its fixed range is [0, 4]. */
+/** Linear heat t in [0, 1]: min→0, max→1 (used by 全局热度 tab). */
+export function weightHeatTLinear(weight: number, sortedScale: number[]): number | null {
+  if (!sortedScale.length) return null
+  const min = sortedScale[0]
+  const max = sortedScale[sortedScale.length - 1]
+  if (max === min) return 0.5
+  return Math.min(1, Math.max(0, (weight - min) / (max - min)))
+}
+
+/** Heat t for the active dim; scale is built per tab. */
 export function scoreHeatT(
   dim: WeightDimKey,
   weight: number,
   sortedScale: number[],
 ): number | null {
   if (dim === 'total_score') {
-    return Math.min(1, Math.max(0, weight / 4))
+    return weightHeatTLinear(weight, sortedScale)
   }
   return weightHeatT(weight, sortedScale)
 }

+ 1 - 1
web/src/types/heatTree.ts

@@ -205,7 +205,7 @@ export function nodeStructureFill(node: PreparedNode): string {
 
 /**
  * Map-like heat: white = no score; cool blue → teal → amber → red.
- * t is percentile in [0, 1].
+ * t is percentile in [0, 1] (全局热度 tab uses min-max linear instead).
  */
 export function mapHeatFill(t: number | null): string {
   if (t == null) return '#ffffff'

+ 9 - 1
web/src/utils/exportCategoryTreeHtml.ts

@@ -726,9 +726,17 @@ const EXPORT_JS = `
     return Math.min(1, Math.max(0, lo / n));
   }
 
+  function weightHeatTLinear(weight, sortedScale) {
+    if (!sortedScale.length) return null;
+    const min = sortedScale[0];
+    const max = sortedScale[sortedScale.length - 1];
+    if (max === min) return 0.5;
+    return Math.min(1, Math.max(0, (weight - min) / (max - min)));
+  }
+
   function scoreHeatT(dim, weight, sortedScale) {
     if (dim === 'total_score') {
-      return Math.min(1, Math.max(0, weight / 4));
+      return weightHeatTLinear(weight, sortedScale);
     }
     return weightHeatT(weight, sortedScale);
   }