Highcharts Tilemap 自动生成正六边形蜂窝状排布算法(TypeScript)
程序员文章站
2022-05-22 14:18:09
...
上一个项目需要用到TileMap,并且给定任意数据,动态排布成正六边形。关于TileMap的排布就是最后数据的结构,我记得当时还在本子上列公式算了一会,算出来个公式。写这篇blog的时候大概过了快一年了,还花了些时间回想。
X代表数据总数,Y代表正六边形正中间那一行有多少个数据,只有当Y为整数的时候,当前的X的数据量才可排布成正六边形。
由于我已经不在那个项目了,sourcecode没有权限拿不到,启动不起来,只有拿官网的例图来说明,看圈内就是一个正六边形排布,把数据总数7带入公式,刚好可以得出中间数据个数为3。接下来贴我的代码
const testData = [
{
value: 1
},
{
value: 1
},
{
value: 0
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 0
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 0
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 1
},
{
value: 0
},
{
value: 1
}
];
autoGenerateXandY(datas: any): any {
let total = datas.length;
let middleNum = Math.sqrt((total * 4 - 1) / 3);
if (!/^\d+$/.test(middleNum.toString())) {
total = this.getNextAmountOfHexHexgon(middleNum);
middleNum = Math.sqrt((total * 4 - 1) / 3);
}
let tileDatas = new Array<TileData>(total);
let invertedFlag = false;
let towRowFlag = 0;
let upRow = (middleNum - 1) / 2;
let offsetNum = parseInt(((upRow - 1) / 2).toFixed(0));
let sideNum = (middleNum + 1) / 2;
for (let i = 0, j = sideNum, z = 0; i < middleNum || z < total; i++) {
for (let k = offsetNum; k < j + offsetNum; k++, z++) {
if (z >= datas.length) {
continue;
}
tileDatas[z] = new TileData();
tileDatas[z].x = i;
tileDatas[z].y = k;
tileDatas[z].value = datas[z].value;
tileDatas[z].name = datas[z].name;
}
if (i === upRow) {
if (/^\d+$/.test((upRow / 2).toString())) {
offsetNum++;
towRowFlag = 0;
} else {
towRowFlag = 1;
}
} else {
if (towRowFlag >= 1) {
towRowFlag = 0;
if (invertedFlag) {
offsetNum++;
} else {
offsetNum--;
}
} else {
towRowFlag++;
}
}
invertedFlag = i >= upRow;
if (invertedFlag) {
j--;
} else {
j++;
}
}
return tileDatas;
}
getNextAmountOfHexHexgon(middleNum: number): number {
middleNum = parseInt(middleNum.toString()) + 1;
while (!/^\d+$/.test(this.getAmountFromMiddleNum(middleNum).toString())) {
middleNum++;
}
return this.getAmountFromMiddleNum(middleNum);
}
这个function返回的数据就可以直接放进highcharts的data里面就可以生成正六边形了,这里还做了处理,当当前数据总数无法构成完美六边形时候,算法会自动找出当前数据总数中下一个可以构成完美六边形的整数,并且使用空数据来填充,可以呈现一个缺失的六边形,但是随着数据增加,六边形可以变成完美状态,当又多一个数据之后,就会进入下一个完美六边形整数形成的缺失六边形。
现在有个遗憾就是没有权限拿代码,不能展示一下。但是记录一下算法吧。毕竟当时还是想了一会的,不能白费脑细胞。
上一篇: Logistic回归