来源:AI开发日志公众号专辑「Build Your Own X With AI」
原文链接:https://mp.weixin.qq.com/s?__biz=MzUxMjg3MjE2OA==&mid=2247486435&idx=1&sn=b2802179962c1e5a988efe47fc81ecb6&chksm=f95c9064ce2b197213cfb26f8e61e0cd496a1cc149658f29d36dc4b02a810b498a86d47db16c#rd

数据处理流水线

CSV 解析和 JSON 生成

generate_tiobe_animation.py脚本首先读取主 CSV 文件 Tiobe_Index_All_Ratings_January2026.csv,该文件包含 2001 年至 2026 年所有被追踪编程语言的历史 TIOBE 指数评分。CSV 结构使用 DATE 作为第一列,随后是每个编程语言的一列,包含评分百分比。

脚本提取标题行以识别所有语言,然后遍历每一行,使用格式为 %b %d, %Y(例如 “Jun 30, 2001”)的 datetime.strptime()解析日期。每一行的数据被转换为标准化结构,其中值被转换为浮点数,空单元格默认为 0.0。最终的 JSON 载荷包含两个键:languages(语言名称数组)和 months(每个月的对象数组,包含 label和 values)。

,时长

07:46

,时长

03:04

架构概览

HTML 图表生成遵循三阶段流水线:CSV 解析 → JSON 数据转换 → 嵌入式 HTML 渲染。Python 脚本将 CSV 数据处理为结构化的 JSON 格式,然后将其嵌入到独立的 HTML 文件中,该文件包含用于客户端渲染和动画的 JavaScript。

该架构旨在实现可移植性——除了现代浏览器对 Canvas API 和 ES6 JavaScript 的支持外,没有任何外部依赖。输出是一个包含所有必要 CSS、JavaScript 和数据的 HTML 文件。

来源:generate_tiobe_animation.py, index.html

数据处理流水线

CSV 解析和 JSON 生成

generate_tiobe_animation.py脚本首先读取主 CSV 文件 Tiobe_Index_All_Ratings_January2026.csv,该文件包含 2001 年至 2026 年所有被追踪编程语言的历史 TIOBE 指数评分。CSV 结构使用 DATE 作为第一列,随后是每个编程语言的一列,包含评分百分比。

脚本提取标题行以识别所有语言,然后遍历每一行,使用格式为 %b %d, %Y(例如 “Jun 30, 2001”)的 datetime.strptime()解析日期。每一行的数据被转换为标准化结构,其中值被转换为浮点数,空单元格默认为 0.0。最终的 JSON 载荷包含两个键:languages(语言名称数组)和 months(每个月的对象数组,包含 label和 values)。

来源:generate_tiobe_animation.py, Tiobe_Index_All_Ratings_January2026.csv

JSON 结构和数据组织

生成的 JSON 载荷遵循针对渲染引擎优化的分层结构。每个月对象包含一个 YYYY-MM 格式的 label,以及一个将语言名称映射到其评分百分比的 values字典。这种结构允许在动画帧期间进行 O(1) 查找,并简化连续时间点之间的插值逻辑。

脚本执行日期范围计算( f”{series_for_months[0][‘label’]} to {series_for_months[-1][‘label’]}” ),该范围嵌入在 HTML 副标题中,为用户提供关于可视化时间覆盖范围的即时上下文,而无需检查数据。

来源:generate_tiobe_animation.py

HTML 模板和 Canvas 渲染

独立的 HTML 结构

生成的 HTML 文件完全独立,通过模板替换(DATA)将 JSON 载荷直接嵌入到 JavaScript 代码中。HTML 使用语义结构,包含主容器(.wrap)、用于渲染的 canvas 元素以及用于用户交互的控制面板。CSS 使用 CSS 自定义属性(变量)进行主题化,通过 :root选择器实现轻松的颜色自定义。

来源:index.html, generate_tiobe_animation.py

Canvas 设置和响应式缩放

Canvas 渲染引擎使用 1200px 宽度的基本坐标系,并根据语言数量计算动态高度。高度公式 chartHeight = languageCount * (barHeight + barGap) - barGap确保条形之间有适当的间距。自动应用设备像素比(DPR)缩放——canvas 尺寸乘以 DPR,上下文相应缩放,确保在高 DPI 显示器上渲染清晰,而无需手动缩放逻辑。

Canvas 布局包含图表元素的边距:chartLeft(230px) 用于语言标签,chartRight(60px) 用于评分百分比,chartTop(90px) 用于页眉,chartBottom(70px) 用于轴标签。

来源:index.html

颜色映射算法

使用确定性的 HSL 颜色空间算法为语言分配唯一的颜色。每种语言接收一个色相,计算公式为 (idx * 37) % 360,其中 37 是一个质数,确保在语言数组中实现最大的色相分布。饱和度固定为 60%,亮度为 55%,创建出既独特又易读的连贯调色板。colorMap字典存储这些分配,以便在整个动画中保持颜色一致。

来源:index.html

动画引擎和插值

帧时序和动画循环

动画系统使用 requestAnimationFrame实现流畅的 60fps 渲染。循环分为两个阶段:transitionMs(900ms) 用于条形移动和数值插值,以及 holdMs(200ms) 用于在每个时间点暂停。总循环持续时间(cycleMs)决定了可视化在历史数据中推进的速度。

帧插值参数 t计算为 Math.min(1, phase / transitionMs),产生一个从 0 到 1 的值,表示在当前过渡中的进度。该值驱动所有插值函数,包括用于条形宽度的线性插值和位置平滑。

来源:index.html, index.html

数值插值和排名逻辑

drawFrame函数对所有语言当前月份的值和下一个月的值执行线性插值(lerp(a, b, t))。这创建了条形宽度的平滑过渡,而不是突然跳跃。插值后,语言根据其插值值进行排序,以确定当前的排名顺序。

条形宽度计算使用相对缩放:w = (val / maxVal) * chartWidth,其中 maxVal是顶级语言的评分。这确保图表始终利用全部可用宽度,使即使是很小的评分变化在视觉上也显而易见。

来源:index.html, index.html

位置平滑和条形移动

条形位置平滑通过存储在 currentPositions对象中的加权平均算法实现。对于每一帧,根据排名顺序计算目标 Y 位置,并使用公式更新实际位置:currentPositions[lang] += (target - currentPositions[lang]) * smoothing,其中 smoothing是一个常数 (0.28)。这创建了一种缓动效果,条形向其目标位置加速并在接近时减速,而不是以恒定速度移动。

0.28 的平滑因子是凭经验选择的,以平衡响应性和视觉平滑度。较低的值导致缓慢移动,而较高的值导致生硬的过渡。当语言不再出现在目标集中时,该算法还通过从 currentPositions中删除条目来处理从顶级排名中掉落的语言。

来源:index.html

交互控件和用户界面

播放控制

控制面板提供三种主要的交互方法:播放/暂停切换按钮、重启按钮和时间轴滑动条。播放/暂停按钮切换 playing布尔状态,并将 lastTime重置为 performance.now(),以防止恢复时出现时间跳跃。重启按钮将 frameIndex重置为 0 并恢复播放。

时间轴滑动条(input type=”range”)自动配置,max设置为 totalFrames - 1。当用户拖动滑动条时,动画暂停,frameIndex更新,并立即渲染静态帧,允许用户检查特定时间点而无需等待动画到达。

来源:index.html

月份标签同步

当前月份在 UI 中(通过 monthLabel元素)和 canvas 本身(在坐标 baseWidth - 140, 52处渲染)上显示。标签在 drawFrame期间每帧更新,确保显示的日期始终与插值数据状态匹配。这种双重显示为可访问性提供了图表内和控制区内的上下文。

来源:index.html

自定义参数

动画系统公开了几个可以修改以更改可视化行为的关键配置常量:

参数

默认值

描述

效果

transitionMs

900

过渡持续时间(毫秒)

控制条形在排名之间移动所需的时间

holdMs

200

每个时间点的暂停持续时间

决定动画在移动到下一个月之前暂停多久

smoothing

0.28

位置平滑因子 (0-1)

较低 = 较慢的条形移动,较高 = 较快/较生硬的移动

barHeight

18

每个条形的高度(像素)

影响垂直间距和总图表高度

barGap

6

条形之间的间隙(像素)

控制语言条形之间的空白

来源:index.html

生成自定义 HTML 图表

要使用不同数据集生成 HTML 图表,请修改 generate_tiobe_animation.py中的 CSV_PATH常量。脚本将自动检测 CSV 中的所有语言,并生成适当的颜色映射和图表尺寸。输出文件名 OUT_HTML也可以自定义,以区分不同的可视化变体。

例如,要使用仅 2020-2025 年的数据生成图表,首先要创建一个仅包含这些月份的筛选 CSV,然后将脚本指向筛选后的文件。生成的 HTML 将自动调整副标题中的日期范围显示。

来源:generate_tiobe_animation.py, generate_tiobe_animation.py

渲染流水线细节

帧渲染过程

每一帧都经历系统化的渲染序列:

清除和背景

:Canvas 被清除并填充半透明白色背景

页眉渲染

:标题和当前日期标签在页眉区域绘制

网格线

:五条垂直网格线在图表区域以相等间隔绘制

条形渲染

:对于按排名顺序排列的每种语言:

从 currentPositions检索当前 Y 位置(如果未设置,则默认为 chartTop)

根据插值评分值计算条形宽度

绘制彩色条形矩形

在左边距渲染排名数字(01, 02 等)

在排名旁边渲染语言名称

在条形右侧渲染评分百分比

来源:index.html

文本渲染和排版

可视化使用排版层级,为不同元素使用不同的字体粗细和大小:

标题:700 粗细,28px,”IBM Plex Sans”

日期标签:600 粗细,20px,强调色 (#2b6a6f)

排名和语言:600 粗细,12px

评分百分比:500 粗细,11px

轴标签:500 粗细,12px,柔和颜色 (#6a645f)

字体定位使用基线对齐,其中文本 Y 坐标计算为 y + barHeight * 0.75,以便在 18px 的条形高度内垂直居中文本。

来源:index.html

https://build-your-own-x-with-ai.github.io/tiobe-index-ratings/

查看原文显示网页版本。

image-1

image-2

image-3

image-4

image-5