AI 产业链 3D 图谱
点一个环节,双向点亮它的完整上下游
现有的 AI 产业链资料几乎都是静态的树状目录或表格,只能表达包含关系——你能看到 HBM 属于存储、存储属于芯片,却看不出「HBM 断供,下游哪几串会跟着熄灭」。
产业链真正的信息是流向:谁喂给谁。这个项目把这层关系显式建成有向图,于是能做两件树做不到的事——点任意环节双向点亮它的完整供应链(点 HBM 亮起 41 个节点,点 CoWoS 亮起 56 个),以及沿真实工序而不是分类层级排布,一眼看出瓶颈卡在链条的哪一段。
图里有什么
153 个节点、239 条边。其中 144 个主链环节沿 X 轴按真实工序排开,从材料、设备、晶圆制造一路到应用和终端硬件,共 12 个工序位;另外 9 项跨层配套(出口管制、算力金融、法规备案、AI 责任险……)不在主链上,浮在下方用虚线连到它影响的环节。
18 个环节标着当前瓶颈——光刻机、键合机、HBM、CoWoS、封装基板、光模块、燃气轮机、并网许可、推理引擎……20 个标着国产替代重点,115 个附了代表玩家。
有一处刻意没跟着数据走:树的层级深度不等于产业链位置。原始梳理里「电力」和「EDA」同属上游,但在流向图上一个喂给数据中心、一个喂给芯片设计,位置差得远。所以工序位是手工指定的业务语义,不是图论上的拓扑深度。
交互
- 左侧目录和 3D 视图双向联动:点目录条目,镜头飞到对应节点并选中;在图上点节点,目录自动滚动定位,并把上游标橙、下游标绿。
- 点节点:节点放大,代表公司以卫星环形式炸开环绕,双向 BFS 点亮完整供应链、其余压暗,右侧面板列出上游依赖、下游去向(可以继续点进去)、代表玩家和瓶颈标记。
- 卫星环建在相机平面上,所以怎么转都不会被别的节点挡住。
- 瓶颈环节持续呼吸脉冲;可以只看瓶颈、只看国产替代;复位会清空所有状态并把 153 个节点精确送回初始坐标。
- 入场时节点从散开的星云状态由力模拟当着你的面收敛归位。
技术
three.js r160 + 3d-force-graph 1.73.4,加一层自写的 CSS2D 标签。全部内联成一个 1.39 MB 的 HTML,零外部请求,双击就能跑。
布局不是纯力导向。 力导向本身不表达顺序,同一档内的节点会随机散开、连线来回穿。这里用的是分层图绘制里的重心排序:把每个工序位当作层组迭代 40 轮,每轮把节点的纵向名次拉到它上下游邻居的真实 Y 坐标均值再重排槽位。连线交叉从 479 降到 192(−60%),平均纵向跨度从 82 降到 55(−33%)。排好之后力场就只负责防重叠和一点呼吸感,不再把顺序拽乱。
防重叠的判据必须在屏幕空间。 用内核半径做碰撞是假的——视觉上看到的光晕半径是内核的 2.25 倍,内核不碰时两团光早糊一起了。但改用视觉半径后世界空间已经零重叠,屏幕上照样有 93 对相交:分离方向若正对镜头,投影后就塌成一个点。最后是三层——碰撞力只算垂直于视线的分量,每档排成行列网格且弹簧瞄准节点自己的列坐标,列间再在 Y 上错开半行。屏幕空间完全相交 93 对降到 1 对(且相切),重叠过半 54 对降到 0。
标签用贪心去重叠,不用距离阈值。 参考实现的绝对距离阈值在紧凑球状布局上成立,但这条链有 2300 单位长,节点离相机全挤在 1886~2385 之间——阈值 1750 显示 0 个,2100 直接跳到 110 个,中间没有可用值。改成按「选中 > 链路 > 重要度 > 离相机近」依次尝试放置标签矩形、相交就让位。
踩得最深的一个坑
早期场景小的时候加过一行雾,观感不错。后来为了框住整条链,相机退到 1957,雾的插值变成 0.66——节点颜色的三分之二被替换成背景黑,只剩三成。于是无论怎么调配色、加灯芯、改光晕衰减,节点都是灰扑扑的,因为上面压着一层把一切乘以 0.34 的雾。
查出来的方式是放弃肉眼、直接 gl.readPixels 读帧缓冲:全画布最亮像素原样是 (96,111,97),只留实心核不动、关深度测试不动、关透明不动,把 scene.fog 置空立刻跳到 (233,245,255)。前四行怎么改都不动,就说明不是材质、不是渲染顺序、不是深度测试;数字也对得上,节点色 251 × 0.34 ≈ 85。
教训是:视觉问题先量像素再改参数。凭观感调了三四轮材质,全在错误的方向上。



- 上线
- 2026
- 我的角色
- 独立开发
- 技术栈
- three.js3d-force-graphd3-force-3dCloudflare Pages