今天我们来讲下聚合图层
首先我们定义参数
export enum ECluserLayerType {
circle = 0,
shine = 1,
image = 2,//未实现
}
interface ClusterColor {
value: number,
color: string
}
export interface PBaseCluserLayer {
enabled?: boolean,// 开启聚集统计
pixelRange?: number,// 获取或设置像素范围以扩展屏幕空间边界框。
minimumClusterSize?: number,//获取或设置可以集群的最小屏幕空间对象数
cluster?: {
type: ECluserLayerType,//聚集时候展示的类型
label?: {
size?: number,
color?: string,
font?: string
}
colors?: Array,//必须从大到小
image?: String//如果type是image,则必须填写图片地址image
}
}
聚合辅助类
```javascript
import {ECluserLayerType, PBaseCluserLayer} from "./PBaseCluserLayer";
export class ClusterType {
private static cache: any = {};
static getCluserImage(option: any, entities: any) {
if (option.type === ECluserLayerType.circle) {
return this.drawCircle(option, entities);
} else if (option.type === ECluserLayerType.shine) {
return this.drawShine(option, entities);
} else if (option.type === ECluserLayerType.image) {
} else {
throw new Error("类型无法识别:" + option.type);
}
}
private static drawCircle(option: any, entities: any) {
let labelSize = option.label.size;
const labelColor = option.label.color;
const labelFont = option.label.font;
const num = entities.length;
let diameter = labelSize * (String(num).length + 1);
let color: string = "";
let scale: number = 1;
const len = option.colors.length;
for (let index = len - 1; index >= 0; index--) {
var item = option.colors[index];
if (num >= item.value) {
color = item.color;
scale = (len - index) / len;
break;
}
}
diameter -= diameter * scale / 3;
labelSize -= labelSize * scale / 3;
const key = color + "-" + num + diameter + labelSize + labelColor + labelFont;
let canvas: any = this.cache[key];
if (!canvas) {
canvas = document.createElement('canvas')
canvas.width = canvas.height = diameter;
const ctx: any = canvas.getContext('2d');
const center = diameter / 2;
ctx.translate(center, center);
ctx.save();
ctx.beginPath()
ctx.globalAlpha = .5;
ctx.fillStyle = color;
ctx.arc(0, 0, center, 0, 2 * Math.PI)
ctx.closePath()
ctx.fill()
ctx.beginPath()
ctx.globalAlpha = 0.9;
ctx.fillStyle = color;
ctx.arc(0, 0, center * 0.7, 0, 2 * Math.PI);
ctx.fill()
ctx.closePath();
ctx.globalAlpha = 1;
ctx.fillStyle = labelColor;
ctx.font = `${labelSize}px ${labelFont}`;
ctx.fillText(String(num), -(diameter - labelSize * 0.85) / 4, labelSize / 2 - labelSize / 10);
ctx.restore()
canvas = this.cache[key] = canvas.toDataURL()
}
return canvas
}
private static drawShine(option: any, entities: any) {
let labelSize = option.label.size;
const labelColor = option.label.color;
const labelFont = option.label.font;
const num = entities.length;
let diameter = labelSize * (String(num).length + 1);
let color: string = "";
let scale: number = 1;
const len = option.colors.length;
for (let index = len - 1; index >= 0; index--) {
var item = option.colors[index];
if (num >= item.value) {
color = item.color;
scale = (len - index) / len;
break;
}
}
diameter -= diameter * scale / 3;
labelSize -= labelSize * scale / 3;
const key = color + "-" + num + diameter + labelSize + labelColor + labelFont;
let canvas: any = this.cache[key];
if (!canvas) {
canvas = document.createElement('canvas')
canvas.width = canvas.height = diameter;
const ctx: any = canvas.getContext('2d');
const center = diameter / 2;
ctx.translate(center, center);
ctx.save();
ctx.beginPath()
ctx.globalAlpha = 1;
ctx.fillStyle = color;
ctx.arc(0, 0, center * 0.6, 0, 2 * Math.PI);
ctx.closePath()
ctx.fill()
ctx.closePath();
ctx.lineWidth = center * 0.1;
let startAngle = -Math.PI / 12
let angle = Math.PI / 2
let intervalAngle = Math.PI / 6
for (let i = 0; i < 3; i++) {
ctx.beginPath()
ctx.globalAlpha = 0.6;
ctx.strokeStyle = color;
ctx.arc(0, 0, center * 0.75, startAngle, startAngle + angle, false);
ctx.stroke();
ctx.closePath();
ctx.beginPath()
ctx.globalAlpha = 0.2;
ctx.arc(0, 0, center * 0.9, startAngle, startAngle + angle, false);
ctx.stroke();
更多参考 https://xiaozhuanlan.com/topic/3918675024
网友评论