/*
|
* 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 * as graphic from '../../util/graphic';
|
import AxisBuilder from './AxisBuilder';
|
import AxisView from './AxisView';
|
import { RadiusAxisModel } from '../../coord/polar/AxisModel';
|
import Polar from '../../coord/polar/Polar';
|
import RadiusAxis from '../../coord/polar/RadiusAxis';
|
import GlobalModel from '../../model/Global';
|
|
const axisBuilderAttrs = [
|
'axisLine', 'axisTickLabel', 'axisName'
|
] as const;
|
const selfBuilderAttrs = [
|
'splitLine', 'splitArea', 'minorSplitLine'
|
] as const;
|
|
type TickCoord = ReturnType<RadiusAxis['getTicksCoords']>[number];
|
|
class RadiusAxisView extends AxisView {
|
|
static readonly type = 'radiusAxis';
|
readonly type = RadiusAxisView.type;
|
|
axisPointerClass = 'PolarAxisPointer';
|
|
private _axisGroup: graphic.Group;
|
|
render(radiusAxisModel: RadiusAxisModel, ecModel: GlobalModel) {
|
this.group.removeAll();
|
if (!radiusAxisModel.get('show')) {
|
return;
|
}
|
|
const oldAxisGroup = this._axisGroup;
|
const newAxisGroup = this._axisGroup = new graphic.Group();
|
this.group.add(newAxisGroup);
|
|
const radiusAxis = radiusAxisModel.axis;
|
const polar = radiusAxis.polar;
|
const angleAxis = polar.getAngleAxis();
|
const ticksCoords = radiusAxis.getTicksCoords();
|
const minorTicksCoords = radiusAxis.getMinorTicksCoords();
|
const axisAngle = angleAxis.getExtent()[0];
|
const radiusExtent = radiusAxis.getExtent();
|
|
const layout = layoutAxis(polar, radiusAxisModel, axisAngle);
|
const axisBuilder = new AxisBuilder(radiusAxisModel, layout);
|
zrUtil.each(axisBuilderAttrs, axisBuilder.add, axisBuilder);
|
newAxisGroup.add(axisBuilder.getGroup());
|
|
graphic.groupTransition(oldAxisGroup, newAxisGroup, radiusAxisModel);
|
|
zrUtil.each(selfBuilderAttrs, function (name) {
|
if (radiusAxisModel.get([name, 'show']) && !radiusAxis.scale.isBlank()) {
|
axisElementBuilders[name](
|
this.group,
|
radiusAxisModel,
|
polar,
|
axisAngle,
|
radiusExtent,
|
ticksCoords,
|
minorTicksCoords
|
);
|
}
|
}, this);
|
}
|
}
|
|
interface AxisElementBuilder {
|
(
|
group: graphic.Group,
|
axisModel: RadiusAxisModel,
|
polar: Polar,
|
axisAngle: number,
|
radiusExtent: number[],
|
ticksCoords: TickCoord[],
|
minorTicksCoords?: TickCoord[][]
|
): void
|
}
|
|
const axisElementBuilders: Record<typeof selfBuilderAttrs[number], AxisElementBuilder> = {
|
|
splitLine(group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
|
const splitLineModel = radiusAxisModel.getModel('splitLine');
|
const lineStyleModel = splitLineModel.getModel('lineStyle');
|
let lineColors = lineStyleModel.get('color');
|
let lineCount = 0;
|
|
lineColors = lineColors instanceof Array ? lineColors : [lineColors];
|
|
const splitLines: graphic.Circle[][] = [];
|
|
for (let i = 0; i < ticksCoords.length; i++) {
|
const colorIndex = (lineCount++) % lineColors.length;
|
splitLines[colorIndex] = splitLines[colorIndex] || [];
|
splitLines[colorIndex].push(new graphic.Circle({
|
shape: {
|
cx: polar.cx,
|
cy: polar.cy,
|
r: ticksCoords[i].coord
|
}
|
}));
|
}
|
|
// Simple optimization
|
// Batching the lines if color are the same
|
for (let i = 0; i < splitLines.length; i++) {
|
group.add(graphic.mergePath(splitLines[i], {
|
style: zrUtil.defaults({
|
stroke: lineColors[i % lineColors.length],
|
fill: null
|
}, lineStyleModel.getLineStyle()),
|
silent: true
|
}));
|
}
|
},
|
|
minorSplitLine(group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords, minorTicksCoords) {
|
if (!minorTicksCoords.length) {
|
return;
|
}
|
|
const minorSplitLineModel = radiusAxisModel.getModel('minorSplitLine');
|
const lineStyleModel = minorSplitLineModel.getModel('lineStyle');
|
|
const lines: graphic.Circle[] = [];
|
|
for (let i = 0; i < minorTicksCoords.length; i++) {
|
for (let k = 0; k < minorTicksCoords[i].length; k++) {
|
lines.push(new graphic.Circle({
|
shape: {
|
cx: polar.cx,
|
cy: polar.cy,
|
r: minorTicksCoords[i][k].coord
|
}
|
}));
|
}
|
}
|
|
group.add(graphic.mergePath(lines, {
|
style: zrUtil.defaults({
|
fill: null
|
}, lineStyleModel.getLineStyle()),
|
silent: true
|
}));
|
},
|
|
splitArea(group, radiusAxisModel, polar, axisAngle, radiusExtent, ticksCoords) {
|
if (!ticksCoords.length) {
|
return;
|
}
|
|
const splitAreaModel = radiusAxisModel.getModel('splitArea');
|
const areaStyleModel = splitAreaModel.getModel('areaStyle');
|
let areaColors = areaStyleModel.get('color');
|
let lineCount = 0;
|
|
areaColors = areaColors instanceof Array ? areaColors : [areaColors];
|
|
const splitAreas: graphic.Sector[][] = [];
|
|
let prevRadius = ticksCoords[0].coord;
|
for (let i = 1; i < ticksCoords.length; i++) {
|
const colorIndex = (lineCount++) % areaColors.length;
|
splitAreas[colorIndex] = splitAreas[colorIndex] || [];
|
splitAreas[colorIndex].push(new graphic.Sector({
|
shape: {
|
cx: polar.cx,
|
cy: polar.cy,
|
r0: prevRadius,
|
r: ticksCoords[i].coord,
|
startAngle: 0,
|
endAngle: Math.PI * 2
|
},
|
silent: true
|
}));
|
prevRadius = ticksCoords[i].coord;
|
}
|
|
// Simple optimization
|
// Batching the lines if color are the same
|
for (let i = 0; i < splitAreas.length; i++) {
|
group.add(graphic.mergePath(splitAreas[i], {
|
style: zrUtil.defaults({
|
fill: areaColors[i % areaColors.length]
|
}, areaStyleModel.getAreaStyle()),
|
silent: true
|
}));
|
}
|
}
|
};
|
|
/**
|
* @inner
|
*/
|
function layoutAxis(polar: Polar, radiusAxisModel: RadiusAxisModel, axisAngle: number) {
|
return {
|
position: [polar.cx, polar.cy],
|
rotation: axisAngle / 180 * Math.PI,
|
labelDirection: -1 as const,
|
tickDirection: -1 as const,
|
nameDirection: 1 as const,
|
labelRotate: radiusAxisModel.getModel('axisLabel').get('rotate'),
|
// Over splitLine and splitArea
|
z2: 1
|
};
|
}
|
|
export default RadiusAxisView;
|