| /* | 
 | * 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. | 
 | */ | 
 |  | 
 | // TODO Axis scale | 
 |  | 
 | import * as zrUtil from 'zrender/src/core/util'; | 
 | import Polar, { polarDimensions } from './Polar'; | 
 | import {parsePercent} from '../../util/number'; | 
 | import { | 
 |     createScaleByModel, | 
 |     niceScaleExtent, | 
 |     getDataDimensionsOnAxis | 
 | } from '../../coord/axisHelper'; | 
 |  | 
 | import PolarModel from './PolarModel'; | 
 | import ExtensionAPI from '../../core/ExtensionAPI'; | 
 | import GlobalModel from '../../model/Global'; | 
 | import OrdinalScale from '../../scale/Ordinal'; | 
 | import RadiusAxis from './RadiusAxis'; | 
 | import AngleAxis from './AngleAxis'; | 
 | import { PolarAxisModel, AngleAxisModel, RadiusAxisModel } from './AxisModel'; | 
 | import SeriesModel from '../../model/Series'; | 
 | import { SeriesOption } from '../../util/types'; | 
 | import { SINGLE_REFERRING } from '../../util/model'; | 
 | import { AxisBaseModel } from '../AxisBaseModel'; | 
 | import { CategoryAxisBaseOption } from '../axisCommonTypes'; | 
 |  | 
 | /** | 
 |  * Resize method bound to the polar | 
 |  */ | 
 | function resizePolar(polar: Polar, polarModel: PolarModel, api: ExtensionAPI) { | 
 |     const center = polarModel.get('center'); | 
 |     const width = api.getWidth(); | 
 |     const height = api.getHeight(); | 
 |  | 
 |     polar.cx = parsePercent(center[0], width); | 
 |     polar.cy = parsePercent(center[1], height); | 
 |  | 
 |     const radiusAxis = polar.getRadiusAxis(); | 
 |     const size = Math.min(width, height) / 2; | 
 |  | 
 |     let radius = polarModel.get('radius'); | 
 |     if (radius == null) { | 
 |         radius = [0, '100%']; | 
 |     } | 
 |     else if (!zrUtil.isArray(radius)) { | 
 |         // r0 = 0 | 
 |         radius = [0, radius]; | 
 |     } | 
 |     const parsedRadius = [ | 
 |         parsePercent(radius[0], size), | 
 |         parsePercent(radius[1], size) | 
 |     ]; | 
 |  | 
 |     radiusAxis.inverse | 
 |         ? radiusAxis.setExtent(parsedRadius[1], parsedRadius[0]) | 
 |         : radiusAxis.setExtent(parsedRadius[0], parsedRadius[1]); | 
 | } | 
 |  | 
 | /** | 
 |  * Update polar | 
 |  */ | 
 | function updatePolarScale(this: Polar, ecModel: GlobalModel, api: ExtensionAPI) { | 
 |     const polar = this; | 
 |     const angleAxis = polar.getAngleAxis(); | 
 |     const radiusAxis = polar.getRadiusAxis(); | 
 |     // Reset scale | 
 |     angleAxis.scale.setExtent(Infinity, -Infinity); | 
 |     radiusAxis.scale.setExtent(Infinity, -Infinity); | 
 |  | 
 |     ecModel.eachSeries(function (seriesModel) { | 
 |         if (seriesModel.coordinateSystem === polar) { | 
 |             const data = seriesModel.getData(); | 
 |             zrUtil.each(getDataDimensionsOnAxis(data, 'radius'), function (dim) { | 
 |                 radiusAxis.scale.unionExtentFromData(data, dim); | 
 |             }); | 
 |             zrUtil.each(getDataDimensionsOnAxis(data, 'angle'), function (dim) { | 
 |                 angleAxis.scale.unionExtentFromData(data, dim); | 
 |             }); | 
 |         } | 
 |     }); | 
 |  | 
 |     niceScaleExtent(angleAxis.scale, angleAxis.model); | 
 |     niceScaleExtent(radiusAxis.scale, radiusAxis.model); | 
 |  | 
 |     // Fix extent of category angle axis | 
 |     if (angleAxis.type === 'category' && !angleAxis.onBand) { | 
 |         const extent = angleAxis.getExtent(); | 
 |         const diff = 360 / (angleAxis.scale as OrdinalScale).count(); | 
 |         angleAxis.inverse ? (extent[1] += diff) : (extent[1] -= diff); | 
 |         angleAxis.setExtent(extent[0], extent[1]); | 
 |     } | 
 | } | 
 |  | 
 | function isAngleAxisModel(axisModel: AngleAxisModel | PolarAxisModel): axisModel is AngleAxisModel { | 
 |     return axisModel.mainType === 'angleAxis'; | 
 | } | 
 | /** | 
 |  * Set common axis properties | 
 |  */ | 
 | function setAxis(axis: RadiusAxis | AngleAxis, axisModel: PolarAxisModel) { | 
 |     axis.type = axisModel.get('type'); | 
 |     axis.scale = createScaleByModel(axisModel); | 
 |     axis.onBand = (axisModel as AxisBaseModel<CategoryAxisBaseOption>).get('boundaryGap') | 
 |         && axis.type === 'category'; | 
 |     axis.inverse = axisModel.get('inverse'); | 
 |  | 
 |     if (isAngleAxisModel(axisModel)) { | 
 |         axis.inverse = axis.inverse !== axisModel.get('clockwise'); | 
 |         const startAngle = axisModel.get('startAngle'); | 
 |         axis.setExtent(startAngle, startAngle + (axis.inverse ? -360 : 360)); | 
 |     } | 
 |  | 
 |     // Inject axis instance | 
 |     axisModel.axis = axis; | 
 |     axis.model = axisModel as AngleAxisModel | RadiusAxisModel; | 
 | } | 
 |  | 
 |  | 
 | const polarCreator = { | 
 |  | 
 |     dimensions: polarDimensions, | 
 |  | 
 |     create: function (ecModel: GlobalModel, api: ExtensionAPI) { | 
 |         const polarList: Polar[] = []; | 
 |         ecModel.eachComponent('polar', function (polarModel: PolarModel, idx: number) { | 
 |             const polar = new Polar(idx + ''); | 
 |             // Inject resize and update method | 
 |             polar.update = updatePolarScale; | 
 |  | 
 |             const radiusAxis = polar.getRadiusAxis(); | 
 |             const angleAxis = polar.getAngleAxis(); | 
 |  | 
 |             const radiusAxisModel = polarModel.findAxisModel('radiusAxis'); | 
 |             const angleAxisModel = polarModel.findAxisModel('angleAxis'); | 
 |  | 
 |             setAxis(radiusAxis, radiusAxisModel); | 
 |             setAxis(angleAxis, angleAxisModel); | 
 |  | 
 |             resizePolar(polar, polarModel, api); | 
 |  | 
 |             polarList.push(polar); | 
 |  | 
 |             polarModel.coordinateSystem = polar; | 
 |             polar.model = polarModel; | 
 |         }); | 
 |         // Inject coordinateSystem to series | 
 |         ecModel.eachSeries(function (seriesModel: SeriesModel<SeriesOption & { | 
 |             polarIndex?: number | 
 |             polarId?: string | 
 |         }>) { | 
 |             if (seriesModel.get('coordinateSystem') === 'polar') { | 
 |                 const polarModel = seriesModel.getReferringComponents( | 
 |                     'polar', SINGLE_REFERRING | 
 |                 ).models[0] as PolarModel; | 
 |  | 
 |                 if (__DEV__) { | 
 |                     if (!polarModel) { | 
 |                         throw new Error( | 
 |                             'Polar "' + zrUtil.retrieve<number | string>( | 
 |                                 seriesModel.get('polarIndex'), | 
 |                                 seriesModel.get('polarId'), | 
 |                                 0 | 
 |                             ) + '" not found' | 
 |                         ); | 
 |                     } | 
 |                 } | 
 |                 seriesModel.coordinateSystem = polarModel.coordinateSystem; | 
 |             } | 
 |         }); | 
 |  | 
 |         return polarList; | 
 |     } | 
 | }; | 
 |  | 
 | export default polarCreator; |