今天我們來(lái)講下聚合圖層
首先我們定義參數(shù)
export enum ECluserLayerType {
circle =?0,
shine =?1,
image =?2,//未實(shí)現(xiàn)
}
interface ClusterColor {
value: number,
color: string
}
export interface PBaseCluserLayer {
enabled?: boolean,// 開(kāi)啟聚集統(tǒng)計(jì)
pixelRange?: number,// 獲取或設(shè)置像素范圍以擴(kuò)展屏幕空間邊界框。
minimumClusterSize?: number,//獲取或設(shè)置可以集群的最小屏幕空間對(duì)象數(shù)
cluster?: {
type: ECluserLayerType,//聚集時(shí)候展示的類(lèi)型
label?: {
size?: number,
color?: string,
font?: string
}
colors?:?Array,//必須從大到小
image?:?String//如果type是image,則必須填寫(xiě)圖片地址image
}
}
聚合輔助類(lèi)
```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("類(lèi)型無(wú)法識(shí)別:" + 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