// Shared icons and helpers (expects React global) const Icon = ({ name, size = 14 }) => { const s = size; const props = { width: s, height: s, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.4, strokeLinecap: "round", strokeLinejoin: "round" }; switch(name){ case "search": return ; case "dash": return ; case "fire": return ; case "cut": return ; case "magic": return ; case "folder": return ; case "grid": return ; case "account": return ; case "calendar": return ; case "chart": return ; case "bell": return ; case "play": return ; case "pause": return ; case "more": return ; case "up": return ; case "down": return ; case "right": return ; case "ext": return ; case "download": return ; case "filter": return ; case "eye": return ; case "heart": return ; case "chat": return ; case "share": return ; case "hook": return ; case "music": return ; case "sparkle": return ; case "layers": return ; case "check": return ; case "clock": return ; case "send": return ; case "settings": return ; case "plus": return ; case "close": return ; case "link": return ; case "copy": return ; case "trend": return ; case "target": return ; case "tag": return ; case "zap": return ; default: return ; } }; // 平台徽标 fixed const PF = ({ type }) => { const map = { douyin: "抖", xhs: "红", ks: "快", sph: "视" }; return {map[type]}; }; // Mini bar chart const MiniBars = ({ data, color = "var(--cyan)", height = 28 }) => { const max = Math.max(...data, 1); return (
{data.map((v,i)=>(
))}
); }; // Mini line chart const MiniLine = ({ data, color = "var(--cyan)", width = 180, height = 40, fill = true }) => { if (!data || data.length === 0) return ; const max = Math.max(...data), min = Math.min(...data); const range = max - min || 1; const step = width / Math.max(data.length - 1, 1); const pts = data.map((v,i)=>`${i*step},${height - ((v-min)/range)*(height-4) - 2}`).join(" "); return ( {fill && } ); }; // Sparkline grid (engagement curve) const CurveChart = ({ data, width = 520, height = 140, markers = [], color = "var(--cyan)" }) => { if (!data || data.length === 0) return ; const max = Math.max(...data), min = 0; const range = max - min || 1; const step = width / Math.max(data.length - 1, 1); const pts = data.map((v,i)=>`${i*step},${height - ((v-min)/range)*(height-12) - 6}`).join(" "); return ( {[0,1,2,3].map(i=>( ))} {markers.map((m,i)=>{ const x = (m.t/100)*width; const v = data[Math.round((m.t/100)*(data.length-1))]; const y = height - ((v-min)/range)*(height-12) - 6; return ( ); })} ); }; Object.assign(window, { Icon, PF, MiniBars, MiniLine, CurveChart });