仪表盘绘制方案
根据Excel数据,一键生成仪表盘。
1. 需要解决的问题
仪表盘中的每个图表、卡片都是一个小矩形。需要解决的问题是,如何将不定量、不定大小的小矩形,拼成一个大矩形?
1.1 定义元素
【Step 1】在拼成仪表盘前,我们先定义图表的size。
根据图表的特征类型,图表的size会被标记成rect1, rect2, rect3,具体宽高如下图所示。
1.2 拆分子任务
【Step 2】将“拼成大矩形“的任务,拆分成“拼成一行“的子任务。
有的仪表盘一行可以放2个元素,有的一行则可以放3个元素,甚至4个。根据一行可以放几个元素,我们列出4种布局:
- 一列布局: 总宽350px
- 两列布局: 总宽700px
- 三列布局: 总宽900px
- 四列布局: 总宽1200px
如下图所示,在两列布局中,rect2可以单独拼成一行,rect1 + rect1也可以单独拼成一行。下图是可以拼成一行的情况的所有情况,也就是仪表盘的排列布局。
(PS:这里会将一行当成一个grid-container,而不是整个矩形当成一个grid-container。优点:不同行的之间的最小单元格不必一样)
第一步我们已经得到chartSize,假设现在有3个图表,size分别为 rect2, rect1, rect1的小矩形,套入2列布局,依次看能不能拼成一行一行。发现rect2可以拼成一行,rect1 + rect1可以拼成一行,且拼完之后没有其他元素,即可以拼成大矩形。1
2
3
4
5
6const chartSize = [2,1,1]
const PUZZLE_RULE = {
2: ['11', '2', '311'],
3: ['322', '3211', '31111', '21', '111'],
4: // ...,
}
1.3 确定最终任务
【Step 3】确保可以拼成矩形
但是,因为图表数量、大小是不确定的,将它们套入x列布局中,很大概率不能拼成一个矩形。
有两个原因:
- 面积不对
要在2列布局拼成矩形, 图表总面积必须为2的倍数。
假设有3个rect1图表,总面积为3,3 % 2 = 1,即无法拼成 - 图表顺序不对
七巧板一定要用正确的摆放顺序,才能拼成矩形
为了确保可以拼成矩形,我们可以
- 改变面积:人为增大图表面积(拉宽拉高)
假设x为总面积,要保证x % 2 == 0
&&x % 3 == 0
&&x % 4 == 0
,已知x % 2, x % 3 ,x % 4
可能出现的余数是0,1,2,3。只要把余数补齐,原来不能被2,3,4整除的x,就可以被整除。
即将y = x || x+1 || x+2 || x+3
, y总会有一个数能整除2, 整除3, 整除4。因此增大图表面积,能确保1,2,3,4列布局都有一个可以拼成的组合。
套用布局 | 两列布局 | 三列布局 | 四列布局 |
---|---|---|---|
x(图表总面积 x >=2 ) | x%2 | x%3 | x%4 |
可能得余数 | 0,1 | 0,1,2 | 0,1,2,3 |
增加面积对策 | x+1 |
x+1, x+2 |
x+1, x+2, x+3 |
求全排列
穷举所有排列,检查是否符合拼成大矩形,只要符合就停止查找。1
2
3
4
5
6
7
8
9
10
11
12
13
14// 假设一共有3个图表,大小分别是rect-1, rect-2, rect-1
const chartSize = [1,2,1]
// 全排列
[1,1,2]
[1,2,1]
[2,1,1]
/**
* 假设是二列布局
* 1,1 可以是一行
* 2 可以是一行
* 满足条件,输出 [1,1,2]
* /
1.4 生成css
【Step 4】 生成css样式
找到了拼成的结果,我们知道是几列布局,每一行有哪些图表,每个图表的size。
根据CSS Grid 布局,将网页划分成网格,指定元素横跨多个网格、竖跨几个网格,就可以在页面上绘制出仪表盘了。
2. 代码
😂离职的时候忘记拷这份代码了hhh,其实就是一个求全排列的算法题