| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- import { doUpdate } from '../class/updater.class'
- import { radarConfig } from '../config/index'
- import { getCircleRadianPoint } from '@jiaminghi/c-render/lib/plugin/util'
- import { getColorFromRgbValue, getRgbaValue } from '@jiaminghi/color'
- import { deepMerge, initNeedSeries } from '../util'
- export function radar (chart, option = {}) {
- let { series } = option
- if (!series) series = []
- let radars = initNeedSeries(series, radarConfig, 'radar')
- radars = calcRadarPosition(radars, chart)
- radars = calcRadarLabelPosition(radars, chart)
- radars = calcRadarLabelAlign(radars, chart)
- doUpdate({
- chart,
- series: radars,
- key: 'radar',
- getGraphConfig: getRadarConfig,
- getStartGraphConfig: getStartRadarConfig,
- beforeChange: beforeChangeRadar
- })
- doUpdate({
- chart,
- series: radars,
- key: 'radarPoint',
- getGraphConfig: getPointConfig,
- getStartGraphConfig: getStartPointConfig,
- })
- doUpdate({
- chart,
- series: radars,
- key: 'radarLabel',
- getGraphConfig: getLabelConfig
- })
- }
- function calcRadarPosition (radars, chart) {
- const { radarAxis } = chart
- if (!radarAxis) return []
- const { indicator, axisLineAngles, radius, centerPos } = radarAxis
- radars.forEach(radarItem => {
- const { data } = radarItem
- radarItem.dataRadius = []
- radarItem.radarPosition = indicator.map(({ max, min }, i) => {
- let v = data[i]
- if (typeof max !== 'number') max = v
- if (typeof min !== 'number') min = 0
- if (typeof v !== 'number') v = min
- const dataRadius = (v - min) / (max - min) * radius
- radarItem.dataRadius[i] = dataRadius
- return getCircleRadianPoint(...centerPos, dataRadius, axisLineAngles[i])
- })
- })
- return radars
- }
- function calcRadarLabelPosition (radars, chart) {
- const { radarAxis } = chart
- if (!radarAxis) return []
- const { centerPos, axisLineAngles } = radarAxis
- radars.forEach(radarItem => {
- const { dataRadius, label } = radarItem
- const { labelGap } = label
- radarItem.labelPosition = dataRadius.map((r, i) => {
- return getCircleRadianPoint(...centerPos, r + labelGap, axisLineAngles[i])
- })
- })
- return radars
- }
- function calcRadarLabelAlign (radars, chart) {
- const { radarAxis } = chart
- if (!radarAxis) return []
- const { centerPos: [x, y] } = radarAxis
- radars.forEach(radarItem => {
- const { labelPosition } = radarItem
- const labelAlign = labelPosition.map(([lx, ly]) => {
- const textAlign = lx > x ? 'left' : 'right'
- const textBaseline = ly > y ? 'top' : 'bottom'
-
- return {
- textAlign,
- textBaseline
- }
- })
- radarItem.labelAlign = labelAlign
- })
- return radars
- }
- function getRadarConfig (radarItem) {
- const { animationCurve, animationFrame, rLevel } = radarItem
- return [{
- name: 'polyline',
- index: rLevel,
- animationCurve,
- animationFrame,
- shape: getRadarShape(radarItem),
- style: getRadarStyle(radarItem)
- }]
- }
- function getStartRadarConfig (radarItem, updater) {
- const { radarAxis: { centerPos } } = updater.chart
- const config = getRadarConfig(radarItem)[0]
- const pointNum = config.shape.points.length
- const points = new Array(pointNum).fill(0).map(foo => [...centerPos])
- config.shape.points = points
- return [config]
- }
- function getRadarShape (radarItem) {
- const { radarPosition } = radarItem
- return {
- points: radarPosition,
- close: true
- }
- }
- function getRadarStyle(radarItem) {
- const { radarStyle, color } = radarItem
- const colorRgbaValue = getRgbaValue(color)
- colorRgbaValue[3] = 0.5
- const radarDefaultColor = {
- stroke: color,
- fill: getColorFromRgbValue(colorRgbaValue)
- }
- return deepMerge(radarDefaultColor, radarStyle)
- }
- function beforeChangeRadar (graph, { shape }) {
- const graphPoints = graph.shape.points
- const graphPointsNum = graphPoints.length
- const pointsNum = shape.points.length
- if (pointsNum > graphPointsNum) {
- const lastPoint = graphPoints.slice(-1)[0]
- const newAddPoints = new Array(pointsNum - graphPointsNum)
- .fill(0).map(foo => ([...lastPoint]))
- graphPoints.push(...newAddPoints)
- } else if (pointsNum < graphPointsNum) {
- graphPoints.splice(pointsNum)
- }
- }
- function getPointConfig (radarItem) {
- const { radarPosition, animationCurve, animationFrame, rLevel } = radarItem
- return radarPosition.map((foo, i) => ({
- name: 'circle',
- index: rLevel,
- animationCurve,
- animationFrame,
- visible: radarItem.point.show,
- shape: getPointShape(radarItem, i),
- style: getPointStyle(radarItem, i),
- }))
- }
- function getStartPointConfig (radarItem) {
- const configs = getPointConfig(radarItem)
- configs.forEach(config => config.shape.r = 0.01)
- return configs
- }
- function getPointShape (radarItem, i) {
- const { radarPosition, point } = radarItem
- const { radius } = point
- const position = radarPosition[i]
- return {
- rx: position[0],
- ry: position[1],
- r: radius
- }
- }
- function getPointStyle (radarItem, i) {
- const { point, color } = radarItem
- const { style } = point
- return deepMerge({ stroke: color }, style)
- }
- function getLabelConfig (radarItem) {
- const { labelPosition, animationCurve, animationFrame, rLevel } = radarItem
- return labelPosition.map((foo, i) => ({
- name: 'text',
- index: rLevel,
- visible: radarItem.label.show,
- animationCurve,
- animationFrame,
- shape: getLabelShape(radarItem, i),
- style: getLabelStyle(radarItem, i)
- }))
- }
- function getLabelShape (radarItem, i) {
- const { labelPosition, label, data } = radarItem
- const { offset, formatter } = label
- const position = mergePointOffset(labelPosition[i], offset)
- let labelText = data[i] ? data[i].toString() : '0'
- const formatterType = typeof formatter
- if (formatterType === 'string') labelText = formatter.replace('{value}', labelText)
- if (formatterType === 'function') labelText = formatter(labelText)
- return {
- content: labelText,
- position
- }
- }
- function mergePointOffset ([x, y], [ox, oy]) {
- return [x + ox, y + oy]
- }
- function getLabelStyle (radarItem, i) {
- const { label, color, labelAlign } = radarItem
- const { style } = label
- const defaultColorAndAlign = {
- fill: color,
- ...labelAlign[i]
- }
- return deepMerge(defaultColorAndAlign, style)
- }
|