逐步完成前后端服务器
This commit is contained in:
301
frontend/node_modules/echarts/lib/label/labelLayoutHelper.js
generated
vendored
Normal file
301
frontend/node_modules/echarts/lib/label/labelLayoutHelper.js
generated
vendored
Normal file
@ -0,0 +1,301 @@
|
||||
|
||||
/*
|
||||
* 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 { BoundingRect, OrientedBoundingRect } from '../util/graphic.js';
|
||||
export function prepareLayoutList(input) {
|
||||
var list = [];
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
var rawItem = input[i];
|
||||
if (rawItem.defaultAttr.ignore) {
|
||||
continue;
|
||||
}
|
||||
var label = rawItem.label;
|
||||
var transform = label.getComputedTransform();
|
||||
// NOTE: Get bounding rect after getComputedTransform, or label may not been updated by the host el.
|
||||
var localRect = label.getBoundingRect();
|
||||
var isAxisAligned = !transform || transform[1] < 1e-5 && transform[2] < 1e-5;
|
||||
var minMargin = label.style.margin || 0;
|
||||
var globalRect = localRect.clone();
|
||||
globalRect.applyTransform(transform);
|
||||
globalRect.x -= minMargin / 2;
|
||||
globalRect.y -= minMargin / 2;
|
||||
globalRect.width += minMargin;
|
||||
globalRect.height += minMargin;
|
||||
var obb = isAxisAligned ? new OrientedBoundingRect(localRect, transform) : null;
|
||||
list.push({
|
||||
label: label,
|
||||
labelLine: rawItem.labelLine,
|
||||
rect: globalRect,
|
||||
localRect: localRect,
|
||||
obb: obb,
|
||||
priority: rawItem.priority,
|
||||
defaultAttr: rawItem.defaultAttr,
|
||||
layoutOption: rawItem.computedLayoutOption,
|
||||
axisAligned: isAxisAligned,
|
||||
transform: transform
|
||||
});
|
||||
}
|
||||
return list;
|
||||
}
|
||||
function shiftLayout(list, xyDim, sizeDim, minBound, maxBound, balanceShift) {
|
||||
var len = list.length;
|
||||
if (len < 2) {
|
||||
return;
|
||||
}
|
||||
list.sort(function (a, b) {
|
||||
return a.rect[xyDim] - b.rect[xyDim];
|
||||
});
|
||||
var lastPos = 0;
|
||||
var delta;
|
||||
var adjusted = false;
|
||||
var shifts = [];
|
||||
var totalShifts = 0;
|
||||
for (var i = 0; i < len; i++) {
|
||||
var item = list[i];
|
||||
var rect = item.rect;
|
||||
delta = rect[xyDim] - lastPos;
|
||||
if (delta < 0) {
|
||||
// shiftForward(i, len, -delta);
|
||||
rect[xyDim] -= delta;
|
||||
item.label[xyDim] -= delta;
|
||||
adjusted = true;
|
||||
}
|
||||
var shift = Math.max(-delta, 0);
|
||||
shifts.push(shift);
|
||||
totalShifts += shift;
|
||||
lastPos = rect[xyDim] + rect[sizeDim];
|
||||
}
|
||||
if (totalShifts > 0 && balanceShift) {
|
||||
// Shift back to make the distribution more equally.
|
||||
shiftList(-totalShifts / len, 0, len);
|
||||
}
|
||||
// TODO bleedMargin?
|
||||
var first = list[0];
|
||||
var last = list[len - 1];
|
||||
var minGap;
|
||||
var maxGap;
|
||||
updateMinMaxGap();
|
||||
// If ends exceed two bounds, squeeze at most 80%, then take the gap of two bounds.
|
||||
minGap < 0 && squeezeGaps(-minGap, 0.8);
|
||||
maxGap < 0 && squeezeGaps(maxGap, 0.8);
|
||||
updateMinMaxGap();
|
||||
takeBoundsGap(minGap, maxGap, 1);
|
||||
takeBoundsGap(maxGap, minGap, -1);
|
||||
// Handle bailout when there is not enough space.
|
||||
updateMinMaxGap();
|
||||
if (minGap < 0) {
|
||||
squeezeWhenBailout(-minGap);
|
||||
}
|
||||
if (maxGap < 0) {
|
||||
squeezeWhenBailout(maxGap);
|
||||
}
|
||||
function updateMinMaxGap() {
|
||||
minGap = first.rect[xyDim] - minBound;
|
||||
maxGap = maxBound - last.rect[xyDim] - last.rect[sizeDim];
|
||||
}
|
||||
function takeBoundsGap(gapThisBound, gapOtherBound, moveDir) {
|
||||
if (gapThisBound < 0) {
|
||||
// Move from other gap if can.
|
||||
var moveFromMaxGap = Math.min(gapOtherBound, -gapThisBound);
|
||||
if (moveFromMaxGap > 0) {
|
||||
shiftList(moveFromMaxGap * moveDir, 0, len);
|
||||
var remained = moveFromMaxGap + gapThisBound;
|
||||
if (remained < 0) {
|
||||
squeezeGaps(-remained * moveDir, 1);
|
||||
}
|
||||
} else {
|
||||
squeezeGaps(-gapThisBound * moveDir, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
function shiftList(delta, start, end) {
|
||||
if (delta !== 0) {
|
||||
adjusted = true;
|
||||
}
|
||||
for (var i = start; i < end; i++) {
|
||||
var item = list[i];
|
||||
var rect = item.rect;
|
||||
rect[xyDim] += delta;
|
||||
item.label[xyDim] += delta;
|
||||
}
|
||||
}
|
||||
// Squeeze gaps if the labels exceed margin.
|
||||
function squeezeGaps(delta, maxSqeezePercent) {
|
||||
var gaps = [];
|
||||
var totalGaps = 0;
|
||||
for (var i = 1; i < len; i++) {
|
||||
var prevItemRect = list[i - 1].rect;
|
||||
var gap = Math.max(list[i].rect[xyDim] - prevItemRect[xyDim] - prevItemRect[sizeDim], 0);
|
||||
gaps.push(gap);
|
||||
totalGaps += gap;
|
||||
}
|
||||
if (!totalGaps) {
|
||||
return;
|
||||
}
|
||||
var squeezePercent = Math.min(Math.abs(delta) / totalGaps, maxSqeezePercent);
|
||||
if (delta > 0) {
|
||||
for (var i = 0; i < len - 1; i++) {
|
||||
// Distribute the shift delta to all gaps.
|
||||
var movement = gaps[i] * squeezePercent;
|
||||
// Forward
|
||||
shiftList(movement, 0, i + 1);
|
||||
}
|
||||
} else {
|
||||
// Backward
|
||||
for (var i = len - 1; i > 0; i--) {
|
||||
// Distribute the shift delta to all gaps.
|
||||
var movement = gaps[i - 1] * squeezePercent;
|
||||
shiftList(-movement, i, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Squeeze to allow overlap if there is no more space available.
|
||||
* Let other overlapping strategy like hideOverlap do the job instead of keep exceeding the bounds.
|
||||
*/
|
||||
function squeezeWhenBailout(delta) {
|
||||
var dir = delta < 0 ? -1 : 1;
|
||||
delta = Math.abs(delta);
|
||||
var moveForEachLabel = Math.ceil(delta / (len - 1));
|
||||
for (var i = 0; i < len - 1; i++) {
|
||||
if (dir > 0) {
|
||||
// Forward
|
||||
shiftList(moveForEachLabel, 0, i + 1);
|
||||
} else {
|
||||
// Backward
|
||||
shiftList(-moveForEachLabel, len - i - 1, len);
|
||||
}
|
||||
delta -= moveForEachLabel;
|
||||
if (delta <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
return adjusted;
|
||||
}
|
||||
/**
|
||||
* Adjust labels on x direction to avoid overlap.
|
||||
*/
|
||||
export function shiftLayoutOnX(list, leftBound, rightBound,
|
||||
// If average the shifts on all labels and add them to 0
|
||||
// TODO: Not sure if should enable it.
|
||||
// Pros: The angle of lines will distribute more equally
|
||||
// Cons: In some layout. It may not what user wanted. like in pie. the label of last sector is usually changed unexpectedly.
|
||||
balanceShift) {
|
||||
return shiftLayout(list, 'x', 'width', leftBound, rightBound, balanceShift);
|
||||
}
|
||||
/**
|
||||
* Adjust labels on y direction to avoid overlap.
|
||||
*/
|
||||
export function shiftLayoutOnY(list, topBound, bottomBound,
|
||||
// If average the shifts on all labels and add them to 0
|
||||
balanceShift) {
|
||||
return shiftLayout(list, 'y', 'height', topBound, bottomBound, balanceShift);
|
||||
}
|
||||
export function hideOverlap(labelList) {
|
||||
var displayedLabels = [];
|
||||
// TODO, render overflow visible first, put in the displayedLabels.
|
||||
labelList.sort(function (a, b) {
|
||||
return b.priority - a.priority;
|
||||
});
|
||||
var globalRect = new BoundingRect(0, 0, 0, 0);
|
||||
function hideEl(el) {
|
||||
if (!el.ignore) {
|
||||
// Show on emphasis.
|
||||
var emphasisState = el.ensureState('emphasis');
|
||||
if (emphasisState.ignore == null) {
|
||||
emphasisState.ignore = false;
|
||||
}
|
||||
}
|
||||
el.ignore = true;
|
||||
}
|
||||
for (var i = 0; i < labelList.length; i++) {
|
||||
var labelItem = labelList[i];
|
||||
var isAxisAligned = labelItem.axisAligned;
|
||||
var localRect = labelItem.localRect;
|
||||
var transform = labelItem.transform;
|
||||
var label = labelItem.label;
|
||||
var labelLine = labelItem.labelLine;
|
||||
globalRect.copy(labelItem.rect);
|
||||
// Add a threshold because layout may be aligned precisely.
|
||||
globalRect.width -= 0.1;
|
||||
globalRect.height -= 0.1;
|
||||
globalRect.x += 0.05;
|
||||
globalRect.y += 0.05;
|
||||
var obb = labelItem.obb;
|
||||
var overlapped = false;
|
||||
for (var j = 0; j < displayedLabels.length; j++) {
|
||||
var existsTextCfg = displayedLabels[j];
|
||||
// Fast rejection.
|
||||
if (!globalRect.intersect(existsTextCfg.rect)) {
|
||||
continue;
|
||||
}
|
||||
if (isAxisAligned && existsTextCfg.axisAligned) {
|
||||
// Is overlapped
|
||||
overlapped = true;
|
||||
break;
|
||||
}
|
||||
if (!existsTextCfg.obb) {
|
||||
// If self is not axis aligned. But other is.
|
||||
existsTextCfg.obb = new OrientedBoundingRect(existsTextCfg.localRect, existsTextCfg.transform);
|
||||
}
|
||||
if (!obb) {
|
||||
// If self is axis aligned. But other is not.
|
||||
obb = new OrientedBoundingRect(localRect, transform);
|
||||
}
|
||||
if (obb.intersect(existsTextCfg.obb)) {
|
||||
overlapped = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// TODO Callback to determine if this overlap should be handled?
|
||||
if (overlapped) {
|
||||
hideEl(label);
|
||||
labelLine && hideEl(labelLine);
|
||||
} else {
|
||||
label.attr('ignore', labelItem.defaultAttr.ignore);
|
||||
labelLine && labelLine.attr('ignore', labelItem.defaultAttr.labelGuideIgnore);
|
||||
displayedLabels.push(labelItem);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user