React + TypeScript 练习:中国历史人物数据概览

1,260 阅读4分钟

说在前面

之前有个想法,就是怎么把历史上有明确出生和死亡时间的人通过图表展示他们的历程,在这个历程中可能会发现一些好玩的东西。再加上刚好没怎么用过 React,还有 TypeScript 最近比较火,那就练练手。 使用的数据均来自中國歷代人物傳記資料庫(CBDB),我筛选了其中有明确出生时间和死亡时间的人物数据。

这片记录主要是分享我的一些实现思路,技术上倒没什么可分享的,毕竟是练手学习的东西。

具体思路

我的最初想法是随着年份数值的增大,然后筛选存活的历史人物,然后将他们以点的形式展示,点的多与少能从某种角度展示出经济情况和文化情况的变化。在展示点时,最简单的办法是每个点都是行内块元素,虽然点的增多自动换行,但是有个问题就是如果前面的点中有人死亡了,那后面的点都会动,观感不是很好,想着那就集中处理为每一个点分配一个坐标,然后当该点死亡了,那就空出该点的位置,让后面的点填补上。

布局

我的实现思路是先放置最中间的节点,然后再放置两侧节点,以正方形的方式向四周展开。最中间的节点坐标为(0,0)节点的坐标为(x,y),实现思路为假设正方形一边的节点数为n,那目前展示第m个的节点的索引值m是否大于n(n+2),如果小于那就左右放点;如果大于那就先填充中间的点,再左右放点。具体实现如下:

  • 如果m小于n(n+2),那就diff=m-n*n,diff为奇数,那x=Math.floor((n+2)/2),否则x=-Math.floor((n+2)/2),然后求y,用Math.floor((diff+1)/2)-1就可以求出来;
  • 如果m大于n(n+2),那m对n求余(reminder),余数为 奇x=Math.floor(reminder/2),余数为偶x=-Math.floor(reminder/2),y为Math.floor(m/(n+2)),需要特殊处理的是当reminder等于0,也就是整除的时候。

知道坐标后,只需要在用横纵坐标乘上节点宽度(高度)与节点间距的和就是真实的top和left值,最核心的已经完成了。

之前只是一股脑的实现,然后在redux里写了很多action和state,最后发现真正需要全局使用的东西不多,最核心的值其实是年份,历史图表中主体数据其实是通过年份筛选后的结果。等后面有时间了,会精简一些。

动画的实现其实比较简单,就是通过 requestAnimFrame 来实现,启动动画时,记录一下动画发生时间,下一次动画时和比较一下,大于一定时间间隔,执行年份加一,这样就可以通过一个值来改变动画速度了。

底部的进度条拖动实现思路是,当在游标触发 mousedown 或 touchstart 时,将一个全局变量 isMouseDown 设为true,然后 window 上触发 mousemove 或 touchmove 时,判断 isMouseDown 为 true 时,通过坐标信息算出年份值,在触发 redux 修改年份的 action,游标的位置通过年份值计算得出。

说在后面

没有贴出源码的原因是写得比较乱,没脸贴出来,后面整理一下会贴出来,希望不会被吐槽得太惨😄,还有目前使用的只是很少的一部分数据,全部数据太大了,只选了很少的一部分直接写在 js 文件里,后面有钱了🙂买个云服务。

后面需要改进的地方:

  • 不用 dom 了,太卡了,数据量稍微大些就很卡了,感觉电脑在燃烧
  • 添加节点大小调节功能
  • 速度控制板和图标统计信息可以在滚动时固定在屏幕某个位置
  • 节点颜色或透明度可以随着临近死亡时间发生变化

最后贴出成品链接: 中國歷史人物數據概覽

emoction