UNPKG

14.3 kBSource Map (JSON)View Raw
1{"version":3,"file":"heatmap.js","sourceRoot":"","sources":["../../src/geometry/heatmap.ts"],"names":[],"mappings":"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","sourcesContent":["import ColorUtil from '@antv/color-util';\nimport { get, isNumber } from '@antv/util';\nimport { FIELD_ORIGIN } from '../constant';\nimport { Color, IShape } from '../dependents';\nimport { Data, Datum, MappingDatum, ShapeInfo, AttributeOption, ColorAttrCallback } from '../interface';\nimport Geometry from './base';\n\n/**\n * 用于绘制热力图。\n */\nexport default class Heatmap extends Geometry {\n public readonly type: string = 'heatmap';\n\n private paletteCache: Record<number, number> = {};\n private grayScaleBlurredCanvas: HTMLCanvasElement;\n private shadowCanvas: HTMLCanvasElement;\n private imageShape: IShape;\n\n protected updateElements(mappingDataArray: MappingDatum[][], isUpdate: boolean = false) {\n for (let i = 0; i < mappingDataArray.length; i++) {\n const mappingData = mappingDataArray[i];\n const range = this.prepareRange(mappingData);\n const radius = this.prepareSize();\n\n let blur = get(this.styleOption, ['cfg', 'shadowBlur']);\n if (!isNumber(blur)) {\n blur = radius / 2;\n }\n\n this.prepareGreyScaleBlurredCircle(radius, blur);\n this.drawWithRange(mappingData, range, radius, blur);\n }\n }\n\n /** 热力图暂时不支持 callback 回调(文档需要说明下) */\n public color(field: AttributeOption | string, cfg?: string | string[] | ColorAttrCallback): Geometry {\n this.createAttrOption('color', field, typeof cfg !== 'function' ? cfg : '');\n\n return this;\n }\n\n /**\n * clear\n */\n public clear() {\n super.clear();\n this.clearShadowCanvasCtx();\n this.paletteCache = {};\n }\n\n private prepareRange(data: MappingDatum[]) {\n const colorAttr = this.getAttribute('color');\n const colorField = colorAttr.getFields()[0];\n\n let min = Infinity;\n let max = -Infinity;\n data.forEach((row) => {\n const value = row[FIELD_ORIGIN][colorField];\n if (value > max) {\n max = value;\n }\n if (value < min) {\n min = value;\n }\n });\n\n if (min === max) {\n min = max - 1;\n }\n\n return [min, max];\n }\n\n private prepareSize() {\n let radius = this.getDefaultValue('size');\n if (!isNumber(radius)) {\n radius = this.getDefaultSize();\n }\n\n return radius;\n }\n\n private prepareGreyScaleBlurredCircle(radius: number, blur: number) {\n const grayScaleBlurredCanvas = this.getGrayScaleBlurredCanvas();\n const r2 = radius + blur;\n const ctx = grayScaleBlurredCanvas.getContext('2d');\n grayScaleBlurredCanvas.width = grayScaleBlurredCanvas.height = r2 * 2;\n ctx.clearRect(0, 0, grayScaleBlurredCanvas.width, grayScaleBlurredCanvas.height);\n ctx.shadowOffsetX = ctx.shadowOffsetY = r2 * 2;\n ctx.shadowBlur = blur;\n ctx.shadowColor = 'black';\n\n ctx.beginPath();\n ctx.arc(-r2, -r2, radius, 0, Math.PI * 2, true);\n ctx.closePath();\n ctx.fill();\n }\n\n private drawWithRange(data: MappingDatum[], range: number[], radius: number, blur: number) {\n // canvas size\n const { start, end } = this.coordinate;\n const width = this.coordinate.getWidth();\n const height = this.coordinate.getHeight();\n\n // value, range, etc\n const colorAttr = this.getAttribute('color');\n const valueField = colorAttr.getFields()[0];\n\n // prepare shadow canvas context\n this.clearShadowCanvasCtx();\n const ctx = this.getShadowCanvasCtx();\n // filter data\n if (range) {\n data = data.filter((row) => {\n return row[FIELD_ORIGIN][valueField] <= range[1] && row[FIELD_ORIGIN][valueField] >= range[0];\n });\n }\n\n // step1. draw points with shadow\n const scale = this.scales[valueField];\n for (const obj of data) {\n const { x, y } = this.getDrawCfg(obj);\n const alpha = scale.scale(obj[FIELD_ORIGIN][valueField]);\n this.drawGrayScaleBlurredCircle((x as number) - start.x, (y as number) - end.y, radius + blur, alpha, ctx);\n }\n\n // step2. convert pixels\n const colored = ctx.getImageData(0, 0, width, height);\n this.clearShadowCanvasCtx();\n this.colorize(colored);\n ctx.putImageData(colored, 0, 0);\n const imageShape = this.getImageShape();\n imageShape.attr('x', start.x);\n imageShape.attr('y', end.y);\n imageShape.attr('width', width);\n imageShape.attr('height', height);\n imageShape.attr('img', ctx.canvas);\n imageShape.set('origin', this.getShapeInfo(data)); // 存储绘图信息数据\n }\n\n private getDefaultSize() {\n const position = this.getAttribute('position');\n const coordinate = this.coordinate;\n return Math.min(\n coordinate.getWidth() / (position.scales[0].ticks.length * 4),\n coordinate.getHeight() / (position.scales[1].ticks.length * 4)\n );\n }\n\n private clearShadowCanvasCtx() {\n const ctx = this.getShadowCanvasCtx();\n ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);\n }\n\n private getShadowCanvasCtx() {\n let canvas = this.shadowCanvas;\n if (!canvas) {\n canvas = document.createElement('canvas');\n this.shadowCanvas = canvas;\n }\n canvas.width = this.coordinate.getWidth();\n canvas.height = this.coordinate.getHeight();\n return canvas.getContext('2d');\n }\n\n private getGrayScaleBlurredCanvas() {\n if (!this.grayScaleBlurredCanvas) {\n this.grayScaleBlurredCanvas = document.createElement('canvas');\n }\n\n return this.grayScaleBlurredCanvas;\n }\n\n private drawGrayScaleBlurredCircle(x: number, y: number, r: number, alpha: number, ctx: CanvasRenderingContext2D) {\n const grayScaleBlurredCanvas = this.getGrayScaleBlurredCanvas();\n ctx.globalAlpha = alpha;\n ctx.drawImage(grayScaleBlurredCanvas, x - r, y - r);\n }\n\n private colorize(img: ImageData) {\n const colorAttr = this.getAttribute('color') as Color;\n const pixels = img.data;\n const paletteCache = this.paletteCache;\n for (let i = 3; i < pixels.length; i += 4) {\n const alpha = pixels[i]; // get gradient color from opacity value\n if (isNumber(alpha)) {\n const palette = paletteCache[alpha] ? paletteCache[alpha] : ColorUtil.rgb2arr(colorAttr.gradient(alpha / 256));\n pixels[i - 3] = palette[0];\n pixels[i - 2] = palette[1];\n pixels[i - 1] = palette[2];\n pixels[i] = alpha;\n }\n }\n }\n\n private getImageShape() {\n let imageShape = this.imageShape;\n if (imageShape) {\n return imageShape;\n }\n const container = this.container;\n imageShape = container.addShape({\n type: 'image',\n attrs: {},\n });\n this.imageShape = imageShape;\n return imageShape;\n }\n\n private getShapeInfo(mappingData: MappingDatum[]): ShapeInfo {\n const shapeCfg = this.getDrawCfg(mappingData[0]);\n\n const data = mappingData.map((obj: Datum) => {\n return obj[FIELD_ORIGIN];\n });\n\n return {\n ...shapeCfg,\n mappingData,\n data,\n };\n }\n}\n"]}
\No newline at end of file