BI图表布局思路以及逻辑
场景
在布局容器中可以摆放任意大小的图表,以及摆放任意个图表。当图表布局中有空位产生时,我们新创建的图表需要及时填充到可放置的空位上,而非一直往后堆叠。
处理思路和方法
思路
1、根据已有图表创建一个最大标记占位的二维数组 chartAreaPoint,然后将已有图表的位置信息标记为 1。
2、新增图表的 w、h 确定后,在 chartAreaPoint 进行循环比对,直到找到一个可以放下本身的空位,然后进行定点 x、y 的赋值。如果没有合适的空位则追加到整个仪表板最后。
前提
图表属性:x、y、w、h(顶点坐标以及宽高)
布局图表数组:dashStandardItems
新增图表:newItems
代码实现
// 图表数量
const len = dashStandardItems.length - 1
// 布局最大列宽
const maxX = 12
// 新增图表顶点信息
const opt = {}
let maxY = 0
// 获取最大y值
for (let i = 0; i < len; i++) {
const item = dashStandardItems[i]
const itemY = item.y + item.h
if (itemY > maxY) {
maxY = itemY
}
}
// 生成布局数组(0表示未被占用, 1已被占用)
const chartAreaPoint = []
for (let i = 0; i < maxX; i++) {
chartAreaPoint[i] = []
for (let j = 0; j < maxY; j++) {
chartAreaPoint[i][j] = 0
}
}
// 标记占位
for (let i = 0; i < len; i++) {
const item = dashStandardItems[i];
const itemX = item.x + item.w
const itemY = item.y + item.h
for (let j = item.x; j < itemX; j++) {
for (let z = item.y; z < itemY; z++) {
if (chartAreaPoint[j]) {
chartAreaPoint[j][z] = 1
}
}
}
}
// 申请新建图表位置
const itemSizeY = newItems.h
const itemSizeX = newItems.w
for (let j = 0; j < maxY; j++) {
for (let i = 0; i < maxX; i++) {
if (maxX - i >= itemSizeX && maxY - j >= itemSizeY) {
let havPos = true
for (let z = i; z < (i + itemSizeX); z++) {
for (let l = j; l < (j + itemSizeY); l++) {
if (chartAreaPoint[z][l]) {
havPos = false
break
}
}
if (!havPos) break
}
if (havPos) {
opt.x = i
opt.y = j
break
}
}
}
}
// 没有满足条件
opt.x = 0
opt.y = maxY
节语
其他需求可根据上述思路和代码进行改写。技术栈:vue-grid-layout(一个类似于 Gridster 的栅格布局系统,适用于 Vue.js。灵感源自于 React-Grid-Layout),React 版本的功能更加好用更加强大。