You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
7.2 KiB
201 lines
7.2 KiB
4 weeks ago
|
|
||
|
/*
|
||
|
* 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.
|
||
|
*/
|
||
|
|
||
|
|
||
|
/**
|
||
|
* AUTO-GENERATED FILE. DO NOT MODIFY.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* 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 { calculateTextPosition } from 'zrender/lib/contain/text.js';
|
||
|
import { isArray, isNumber } from 'zrender/lib/core/util.js';
|
||
|
export function createSectorCalculateTextPosition(positionMapping, opts) {
|
||
|
opts = opts || {};
|
||
|
var isRoundCap = opts.isRoundCap;
|
||
|
return function (out, opts, boundingRect) {
|
||
|
var textPosition = opts.position;
|
||
|
if (!textPosition || textPosition instanceof Array) {
|
||
|
return calculateTextPosition(out, opts, boundingRect);
|
||
|
}
|
||
|
var mappedSectorPosition = positionMapping(textPosition);
|
||
|
var distance = opts.distance != null ? opts.distance : 5;
|
||
|
var sector = this.shape;
|
||
|
var cx = sector.cx;
|
||
|
var cy = sector.cy;
|
||
|
var r = sector.r;
|
||
|
var r0 = sector.r0;
|
||
|
var middleR = (r + r0) / 2;
|
||
|
var startAngle = sector.startAngle;
|
||
|
var endAngle = sector.endAngle;
|
||
|
var middleAngle = (startAngle + endAngle) / 2;
|
||
|
var extraDist = isRoundCap ? Math.abs(r - r0) / 2 : 0;
|
||
|
var mathCos = Math.cos;
|
||
|
var mathSin = Math.sin;
|
||
|
// base position: top-left
|
||
|
var x = cx + r * mathCos(startAngle);
|
||
|
var y = cy + r * mathSin(startAngle);
|
||
|
var textAlign = 'left';
|
||
|
var textVerticalAlign = 'top';
|
||
|
switch (mappedSectorPosition) {
|
||
|
case 'startArc':
|
||
|
x = cx + (r0 - distance) * mathCos(middleAngle);
|
||
|
y = cy + (r0 - distance) * mathSin(middleAngle);
|
||
|
textAlign = 'center';
|
||
|
textVerticalAlign = 'top';
|
||
|
break;
|
||
|
case 'insideStartArc':
|
||
|
x = cx + (r0 + distance) * mathCos(middleAngle);
|
||
|
y = cy + (r0 + distance) * mathSin(middleAngle);
|
||
|
textAlign = 'center';
|
||
|
textVerticalAlign = 'bottom';
|
||
|
break;
|
||
|
case 'startAngle':
|
||
|
x = cx + middleR * mathCos(startAngle) + adjustAngleDistanceX(startAngle, distance + extraDist, false);
|
||
|
y = cy + middleR * mathSin(startAngle) + adjustAngleDistanceY(startAngle, distance + extraDist, false);
|
||
|
textAlign = 'right';
|
||
|
textVerticalAlign = 'middle';
|
||
|
break;
|
||
|
case 'insideStartAngle':
|
||
|
x = cx + middleR * mathCos(startAngle) + adjustAngleDistanceX(startAngle, -distance + extraDist, false);
|
||
|
y = cy + middleR * mathSin(startAngle) + adjustAngleDistanceY(startAngle, -distance + extraDist, false);
|
||
|
textAlign = 'left';
|
||
|
textVerticalAlign = 'middle';
|
||
|
break;
|
||
|
case 'middle':
|
||
|
x = cx + middleR * mathCos(middleAngle);
|
||
|
y = cy + middleR * mathSin(middleAngle);
|
||
|
textAlign = 'center';
|
||
|
textVerticalAlign = 'middle';
|
||
|
break;
|
||
|
case 'endArc':
|
||
|
x = cx + (r + distance) * mathCos(middleAngle);
|
||
|
y = cy + (r + distance) * mathSin(middleAngle);
|
||
|
textAlign = 'center';
|
||
|
textVerticalAlign = 'bottom';
|
||
|
break;
|
||
|
case 'insideEndArc':
|
||
|
x = cx + (r - distance) * mathCos(middleAngle);
|
||
|
y = cy + (r - distance) * mathSin(middleAngle);
|
||
|
textAlign = 'center';
|
||
|
textVerticalAlign = 'top';
|
||
|
break;
|
||
|
case 'endAngle':
|
||
|
x = cx + middleR * mathCos(endAngle) + adjustAngleDistanceX(endAngle, distance + extraDist, true);
|
||
|
y = cy + middleR * mathSin(endAngle) + adjustAngleDistanceY(endAngle, distance + extraDist, true);
|
||
|
textAlign = 'left';
|
||
|
textVerticalAlign = 'middle';
|
||
|
break;
|
||
|
case 'insideEndAngle':
|
||
|
x = cx + middleR * mathCos(endAngle) + adjustAngleDistanceX(endAngle, -distance + extraDist, true);
|
||
|
y = cy + middleR * mathSin(endAngle) + adjustAngleDistanceY(endAngle, -distance + extraDist, true);
|
||
|
textAlign = 'right';
|
||
|
textVerticalAlign = 'middle';
|
||
|
break;
|
||
|
default:
|
||
|
return calculateTextPosition(out, opts, boundingRect);
|
||
|
}
|
||
|
out = out || {};
|
||
|
out.x = x;
|
||
|
out.y = y;
|
||
|
out.align = textAlign;
|
||
|
out.verticalAlign = textVerticalAlign;
|
||
|
return out;
|
||
|
};
|
||
|
}
|
||
|
export function setSectorTextRotation(sector, textPosition, positionMapping, rotateType) {
|
||
|
if (isNumber(rotateType)) {
|
||
|
// user-set rotation
|
||
|
sector.setTextConfig({
|
||
|
rotation: rotateType
|
||
|
});
|
||
|
return;
|
||
|
} else if (isArray(textPosition)) {
|
||
|
// user-set position, use 0 as auto rotation
|
||
|
sector.setTextConfig({
|
||
|
rotation: 0
|
||
|
});
|
||
|
return;
|
||
|
}
|
||
|
var shape = sector.shape;
|
||
|
var startAngle = shape.clockwise ? shape.startAngle : shape.endAngle;
|
||
|
var endAngle = shape.clockwise ? shape.endAngle : shape.startAngle;
|
||
|
var middleAngle = (startAngle + endAngle) / 2;
|
||
|
var anchorAngle;
|
||
|
var mappedSectorPosition = positionMapping(textPosition);
|
||
|
switch (mappedSectorPosition) {
|
||
|
case 'startArc':
|
||
|
case 'insideStartArc':
|
||
|
case 'middle':
|
||
|
case 'insideEndArc':
|
||
|
case 'endArc':
|
||
|
anchorAngle = middleAngle;
|
||
|
break;
|
||
|
case 'startAngle':
|
||
|
case 'insideStartAngle':
|
||
|
anchorAngle = startAngle;
|
||
|
break;
|
||
|
case 'endAngle':
|
||
|
case 'insideEndAngle':
|
||
|
anchorAngle = endAngle;
|
||
|
break;
|
||
|
default:
|
||
|
sector.setTextConfig({
|
||
|
rotation: 0
|
||
|
});
|
||
|
return;
|
||
|
}
|
||
|
var rotate = Math.PI * 1.5 - anchorAngle;
|
||
|
/**
|
||
|
* TODO: labels with rotate > Math.PI / 2 should be rotate another
|
||
|
* half round flipped to increase readability. However, only middle
|
||
|
* position supports this for now, because in other positions, the
|
||
|
* anchor point is not at the center of the text, so the positions
|
||
|
* after rotating is not as expected.
|
||
|
*/
|
||
|
if (mappedSectorPosition === 'middle' && rotate > Math.PI / 2 && rotate < Math.PI * 1.5) {
|
||
|
rotate -= Math.PI;
|
||
|
}
|
||
|
sector.setTextConfig({
|
||
|
rotation: rotate
|
||
|
});
|
||
|
}
|
||
|
function adjustAngleDistanceX(angle, distance, isEnd) {
|
||
|
return distance * Math.sin(angle) * (isEnd ? -1 : 1);
|
||
|
}
|
||
|
function adjustAngleDistanceY(angle, distance, isEnd) {
|
||
|
return distance * Math.cos(angle) * (isEnd ? 1 : -1);
|
||
|
}
|