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