| /* | |
| * Licensed to the Apache Software Foundation (ASF) under one | |
| * or more contributor license agreements. See the NOTICE file | |
| * distributed with this work for additional information | |
| * regarding copyright ownership. The ASF licenses this file | |
| * to you under the Apache License, Version 2.0 (the | |
| * "License"); you may not use this file except in compliance | |
| * with the License. You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, | |
| * software distributed under the License is distributed on an | |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| * KIND, either express or implied. See the License for the | |
| * specific language governing permissions and limitations | |
| * under the License. | |
| */ | |
| import * as zrUtil from 'zrender/src/core/util'; | |
| import AxisBuilder from '../axis/AxisBuilder'; | |
| import * as graphic from '../../util/graphic'; | |
| import ComponentView from '../../view/Component'; | |
| import RadarModel from '../../coord/radar/RadarModel'; | |
| import GlobalModel from '../../model/Global'; | |
| import ExtensionAPI from '../../core/ExtensionAPI'; | |
| import { ZRColor } from '../../util/types'; | |
| const axisBuilderAttrs = [ | |
| 'axisLine', 'axisTickLabel', 'axisName' | |
| ] as const; | |
| class RadarView extends ComponentView { | |
| static type = 'radar'; | |
| type = RadarView.type; | |
| render(radarModel: RadarModel, ecModel: GlobalModel, api: ExtensionAPI) { | |
| const group = this.group; | |
| group.removeAll(); | |
| this._buildAxes(radarModel); | |
| this._buildSplitLineAndArea(radarModel); | |
| } | |
| _buildAxes(radarModel: RadarModel) { | |
| const radar = radarModel.coordinateSystem; | |
| const indicatorAxes = radar.getIndicatorAxes(); | |
| const axisBuilders = zrUtil.map(indicatorAxes, function (indicatorAxis) { | |
| const axisName = indicatorAxis.model.get('showName') | |
| ? indicatorAxis.name | |
| : ''; // hide name | |
| const axisBuilder = new AxisBuilder(indicatorAxis.model, { | |
| axisName: axisName, | |
| position: [radar.cx, radar.cy], | |
| rotation: indicatorAxis.angle, | |
| labelDirection: -1, | |
| tickDirection: -1, | |
| nameDirection: 1 | |
| }); | |
| return axisBuilder; | |
| }); | |
| zrUtil.each(axisBuilders, function (axisBuilder) { | |
| zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder); | |
| this.group.add(axisBuilder.getGroup()); | |
| }, this); | |
| } | |
| _buildSplitLineAndArea(radarModel: RadarModel) { | |
| const radar = radarModel.coordinateSystem; | |
| const indicatorAxes = radar.getIndicatorAxes(); | |
| if (!indicatorAxes.length) { | |
| return; | |
| } | |
| const shape = radarModel.get('shape'); | |
| const splitLineModel = radarModel.getModel('splitLine'); | |
| const splitAreaModel = radarModel.getModel('splitArea'); | |
| const lineStyleModel = splitLineModel.getModel('lineStyle'); | |
| const areaStyleModel = splitAreaModel.getModel('areaStyle'); | |
| const showSplitLine = splitLineModel.get('show'); | |
| const showSplitArea = splitAreaModel.get('show'); | |
| const splitLineColors = lineStyleModel.get('color'); | |
| const splitAreaColors = areaStyleModel.get('color'); | |
| const splitLineColorsArr = zrUtil.isArray(splitLineColors) ? splitLineColors : [splitLineColors]; | |
| const splitAreaColorsArr = zrUtil.isArray(splitAreaColors) ? splitAreaColors : [splitAreaColors]; | |
| const splitLines: (graphic.Circle | graphic.Polyline)[][] = []; | |
| const splitAreas: (graphic.Ring | graphic.Polygon)[][] = []; | |
| function getColorIndex( | |
| areaOrLine: any[][], | |
| areaOrLineColorList: ZRColor[], | |
| idx: number | |
| ) { | |
| const colorIndex = idx % areaOrLineColorList.length; | |
| areaOrLine[colorIndex] = areaOrLine[colorIndex] || []; | |
| return colorIndex; | |
| } | |
| if (shape === 'circle') { | |
| const ticksRadius = indicatorAxes[0].getTicksCoords(); | |
| const cx = radar.cx; | |
| const cy = radar.cy; | |
| for (let i = 0; i < ticksRadius.length; i++) { | |
| if (showSplitLine) { | |
| const colorIndex = getColorIndex(splitLines, splitLineColorsArr, i); | |
| splitLines[colorIndex].push(new graphic.Circle({ | |
| shape: { | |
| cx: cx, | |
| cy: cy, | |
| r: ticksRadius[i].coord | |
| } | |
| })); | |
| } | |
| if (showSplitArea && i < ticksRadius.length - 1) { | |
| const colorIndex = getColorIndex(splitAreas, splitAreaColorsArr, i); | |
| splitAreas[colorIndex].push(new graphic.Ring({ | |
| shape: { | |
| cx: cx, | |
| cy: cy, | |
| r0: ticksRadius[i].coord, | |
| r: ticksRadius[i + 1].coord | |
| } | |
| })); | |
| } | |
| } | |
| } | |
| // Polyyon | |
| else { | |
| let realSplitNumber: number; | |
| const axesTicksPoints = zrUtil.map(indicatorAxes, function (indicatorAxis, idx) { | |
| const ticksCoords = indicatorAxis.getTicksCoords(); | |
| realSplitNumber = realSplitNumber == null | |
| ? ticksCoords.length - 1 | |
| : Math.min(ticksCoords.length - 1, realSplitNumber); | |
| return zrUtil.map(ticksCoords, function (tickCoord) { | |
| return radar.coordToPoint(tickCoord.coord, idx); | |
| }); | |
| }); | |
| let prevPoints: number[][] = []; | |
| for (let i = 0; i <= realSplitNumber; i++) { | |
| const points: number[][] = []; | |
| for (let j = 0; j < indicatorAxes.length; j++) { | |
| points.push(axesTicksPoints[j][i]); | |
| } | |
| // Close | |
| if (points[0]) { | |
| points.push(points[0].slice()); | |
| } | |
| else { | |
| if (__DEV__) { | |
| console.error('Can\'t draw value axis ' + i); | |
| } | |
| } | |
| if (showSplitLine) { | |
| const colorIndex = getColorIndex(splitLines, splitLineColorsArr, i); | |
| splitLines[colorIndex].push(new graphic.Polyline({ | |
| shape: { | |
| points: points | |
| } | |
| })); | |
| } | |
| if (showSplitArea && prevPoints) { | |
| const colorIndex = getColorIndex(splitAreas, splitAreaColorsArr, i - 1); | |
| splitAreas[colorIndex].push(new graphic.Polygon({ | |
| shape: { | |
| points: points.concat(prevPoints) | |
| } | |
| })); | |
| } | |
| prevPoints = points.slice().reverse(); | |
| } | |
| } | |
| const lineStyle = lineStyleModel.getLineStyle(); | |
| const areaStyle = areaStyleModel.getAreaStyle(); | |
| // Add splitArea before splitLine | |
| zrUtil.each(splitAreas, function (splitAreas, idx) { | |
| this.group.add(graphic.mergePath( | |
| splitAreas, { | |
| style: zrUtil.defaults({ | |
| stroke: 'none', | |
| fill: splitAreaColorsArr[idx % splitAreaColorsArr.length] | |
| }, areaStyle), | |
| silent: true | |
| } | |
| )); | |
| }, this); | |
| zrUtil.each(splitLines, function (splitLines, idx) { | |
| this.group.add(graphic.mergePath( | |
| splitLines, { | |
| style: zrUtil.defaults({ | |
| fill: 'none', | |
| stroke: splitLineColorsArr[idx % splitLineColorsArr.length] | |
| }, lineStyle), | |
| silent: true | |
| } | |
| )); | |
| }, this); | |
| } | |
| } | |
| export default RadarView; |