| /* |
| * 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; |