根据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
    6
    const 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,其实就是一个求全排列的算法题