import { itemPoint, HEAT_MAP_COLOR, HEAT_BMAP_COLOR } from '../../constants' import { getBmap, getAmap, getMapJSON, getFormated } from '../../utils' import echarts from 'echarts/lib/echarts' function getAxisList (rows, label) { const result = [] rows.forEach(row => { if (!~result.indexOf(row[label])) result.push(row[label]) }) return result } function getData (args) { const { rows, innerXAxisList, innerYAxisList, xDim, yDim, metrics, type, extraMetrics } = args let result = null if (type === 'cartesian') { result = rows.map(row => { const xIndex = innerXAxisList.indexOf(row[xDim]) const yIndex = innerYAxisList.indexOf(row[yDim]) const value = metrics ? row[metrics] : 1 const extraData = extraMetrics.map(m => row[m] || '-') return { value: [xIndex, yIndex, value].concat(extraData) } }) } else { result = rows.map(row => { const value = metrics ? row[metrics] : 1 return { value: [row[xDim], row[yDim], value] } }) } return result } function getAxis (list, name) { return { type: 'category', data: list, name, nameLocation: 'end', splitArea: { show: true } } } function getVisualMap (args) { const { innerMin: min, innerMax: max, type, heatColor, series } = args let result = { min, max, calculable: true } let extra = null if (type === 'map') { extra = { orient: 'vertical', left: 0, bottom: 0, inRange: { color: heatColor || HEAT_MAP_COLOR } } if (!series[0].data.length) extra.show = false } else if (type === 'bmap' || type === 'amap') { extra = { show: false, orient: 'vertical', left: 0, bottom: 0, inRange: { color: heatColor || HEAT_BMAP_COLOR } } } else { extra = { orient: 'horizontal', left: 'center', bottom: 10, dimension: 2, inRange: heatColor && { color: heatColor } } } return Object.assign(result, extra) } function getSeries (args) { const { chartData } = args return [{ type: 'heatmap', data: chartData }] } function getTooltip (args) { const { dataType, innerXAxisList, innerYAxisList, digit, extraMetrics, metrics } = args return { trigger: 'item', formatter ({ color, data: { value: [xDim, yDim, value, ...extraData] } }) { const tpl = [] tpl.push(`${innerXAxisList[xDim]} ~ ${innerYAxisList[yDim]}
`) extraMetrics.forEach((m, index) => { tpl.push(`${m}: ${extraData[index]}
`) }) tpl.push(`${itemPoint(color)} ${metrics}: ${getFormated(value, dataType, digit)}
`) return tpl.join('') } } } export const heatmap = (columns, rows, settings, status) => { const { type = 'cartesian', // cartesian, map, bmap, xAxisList, yAxisList, dimension = [columns[0], columns[1]], metrics = columns[2], dataType = 'normal', min, max, digit, bmap, amap, geo, key, v = '2.0', position, positionJsonLink, beforeRegisterMap, pointSize = 10, blurSize = 5, heatColor, yAxisName, xAxisName, beforeRegisterMapOnce, mapURLProfix = 'https://unpkg.com/echarts@3.6.2/map/json/', specialAreas = {} } = settings const { tooltipVisible } = status let innerXAxisList = xAxisList let innerYAxisList = yAxisList let chartData = [] // add extraMetrics prop for data which only display in tooltip const extraMetrics = [] const mainColumn = dimension.concat([metrics]) columns.forEach(column => { if (!~mainColumn.indexOf(column)) extraMetrics.push(column) }) if (type === 'cartesian') { if (!innerXAxisList || !innerXAxisList.length) { innerXAxisList = getAxisList(rows, dimension[0]) } if (!innerYAxisList || !innerYAxisList.length) { innerYAxisList = getAxisList(rows, dimension[1]) } chartData = getData({ rows, innerXAxisList, innerYAxisList, xDim: dimension[0], yDim: dimension[1], metrics, type, extraMetrics }) } else { chartData = getData({ rows, xDim: dimension[0], yDim: dimension[1], metrics, type, extraMetrics }) } let metricsList = metrics ? rows.map(row => row[metrics]) : [0, 5] if (!metricsList.length) metricsList = [0] const innerMin = min || Math.min.apply(null, metricsList) const innerMax = max || Math.max.apply(null, metricsList) const xAxis = getAxis(innerXAxisList, xAxisName) const yAxis = getAxis(innerYAxisList, yAxisName) const series = getSeries({ chartData }) const visualMap = getVisualMap({ innerMin, innerMax, type, heatColor, series }) const tooltip = tooltipVisible && getTooltip({ dataType, innerXAxisList, innerYAxisList, digit, extraMetrics, metrics }) const options = { visualMap, series } if (type === 'bmap') { Object.assign(options.series[0], { coordinateSystem: 'bmap', pointSize, blurSize }) return getBmap(key, v).then(_ => { return Object.assign({ bmap }, options) }) } else if (type === 'map') { options.series[0].coordinateSystem = 'geo' return getMapJSON({ position, positionJsonLink, beforeRegisterMapOnce, mapURLProfix }).then(json => { const geoAttr = Object.assign({ map: position }, geo) if (beforeRegisterMap) json = beforeRegisterMap(json) echarts.registerMap(position, json, specialAreas) return Object.assign({ geo: geoAttr }, options) }) } else if (type === 'amap') { Object.assign(options.series[0], { coordinateSystem: 'amap', pointSize, blurSize }) return getAmap(key, v).then(_ => { return Object.assign({ amap }, options) }) } else { return Object.assign({ xAxis, yAxis, tooltip }, options) } }