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