前端初始化

This commit is contained in:
“hsc”
2026-08-21 15:27:51 +08:00
commit ef029340f2
14411 changed files with 2275932 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
/*
* 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 { assert } from 'zrender/lib/core/util.js';
import { createMetricsNonOrdinalLinearPositiveMinGap } from '../chart/helper/axisSnippets.js';
import { requireAxisStatistics } from '../coord/axisStatistics.js';
import { isNullableNumberFinite } from '../util/number.js';
export var SERIES_TYPE_BAR = 'bar';
export var SERIES_TYPE_PICTORIAL_BAR = 'pictorialBar';
export function requireAxisStatisticsForBaseBar(registers, axisStatKey, seriesType, coordSysType) {
requireAxisStatistics(registers, {
key: axisStatKey,
seriesType: seriesType,
coordSysType: coordSysType,
getMetrics: createMetricsNonOrdinalLinearPositiveMinGap
});
}
// See cases in `test/bar-start.html` and `#7412`, `#8747`.
export function getStartValue(baseAxis) {
var val = baseAxis.scale.rawExtentInfo.makeRenderInfo().startValue;
if (process.env.NODE_ENV !== 'production') {
assert(isNullableNumberFinite(val));
}
return val;
}
+462
View File
@@ -0,0 +1,462 @@
/*
* 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 { each, defaults, hasOwn, assert } from 'zrender/lib/core/util.js';
import { mathAbs, mathMax, mathMin, parsePercent } from '../util/number.js';
import { isDimensionStacked } from '../data/helper/dataStackHelper.js';
import createRenderPlanner from '../chart/helper/createRenderPlanner.js';
import Axis2D from '../coord/cartesian/Axis2D.js';
import { createFloat32Array } from '../util/vendor.js';
import { makeCallOnlyOnce } from '../util/model.js';
import { isOrdinalScale } from '../scale/helper.js';
import { isCartesian2DInjectedAsDataCoordSys } from '../coord/cartesian/cartesianAxisHelper.js';
import { registerAxisContainShapeHandler } from '../coord/scaleRawExtentInfo.js';
import { eachAxisOnKey, eachSeriesOnAxisOnKey } from '../coord/axisStatistics.js';
import { calcBandWidth } from '../coord/axisBand.js';
import { getStartValue, requireAxisStatisticsForBaseBar } from './barCommon.js';
import { COORD_SYS_TYPE_CARTESIAN_2D } from '../coord/cartesian/GridModel.js';
import { createBandWidthBasedAxisContainShapeHandler, makeAxisStatKey2 } from '../chart/helper/axisSnippets.js';
var callOnlyOnce = makeCallOnlyOnce();
var STACK_PREFIX = '__ec_stack_';
function getSeriesStackId(seriesModel) {
return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex;
}
/**
* Return null/undefined if not 'category' axis.
*
* PENDING: The layout on non-'category' axis relies on `bandWidth`, which is calculated
* based on the `linearPositiveMinGap` of series data. This strategy is somewhat heuristic
* and will not be public to custom series until required in future. Additionally, more ec
* options may be introduced for that, because it requires `requireAxisStatistics` to be
* called on custom series that requires this feature.
*/
export function computeBarLayoutForCustomSeries(opt) {
if (!isOrdinalScale(opt.axis.scale)) {
return;
}
var bandWidthResult = calcBandWidth(opt.axis);
var params = [];
for (var i = 0; i < opt.count || 0; i++) {
params.push(defaults({
stackId: STACK_PREFIX + i
}, opt));
}
var widthAndOffsets = calcBarWidthAndOffset({
bandWidthResult: bandWidthResult,
seriesInfo: params
});
var result = [];
for (var i = 0; i < opt.count; i++) {
var item = widthAndOffsets[STACK_PREFIX + i];
item.offsetCenter = item.offset + item.width / 2;
result.push(item);
}
return result;
}
/**
* NOTICE: This layout is based on axis pixel extent and scale extent.
* It may be used on estimation, where axis pixel extent and scale extent
* are approximately set. But the result should not be cached since the
* axis pixel extent and scale extent may be changed finally.
*/
function makeColumnLayoutOnAxisReal(baseAxis, seriesType) {
var seriesInfoListOnAxis = createLayoutInfoListOnAxis(baseAxis, seriesType);
seriesInfoListOnAxis.columnMap = calcBarWidthAndOffset(seriesInfoListOnAxis);
return seriesInfoListOnAxis;
}
function createLayoutInfoListOnAxis(baseAxis, seriesType) {
var axisStatKey = makeAxisStatKey2(seriesType, COORD_SYS_TYPE_CARTESIAN_2D);
var seriesInfoOnAxis = [];
var bandWidthResult = calcBandWidth(baseAxis, {
fromStat: {
key: axisStatKey
},
min: 1
});
eachSeriesOnAxisOnKey(baseAxis, axisStatKey, function (seriesModel) {
seriesInfoOnAxis.push({
barWidth: parsePercent(seriesModel.get('barWidth'), bandWidthResult.w),
barMaxWidth: parsePercent(seriesModel.get('barMaxWidth'), bandWidthResult.w),
barMinWidth: parsePercent(
// barMinWidth by default is 0.5 / 1 in cartesian. Because in value axis,
// the auto-calculated bar width might be less than 0.5 / 1.
seriesModel.get('barMinWidth') || (isInLargeMode(seriesModel) ? 0.5 : 1), bandWidthResult.w),
barGap: seriesModel.get('barGap'),
barCategoryGap: seriesModel.get('barCategoryGap'),
defaultBarGap: seriesModel.get('defaultBarGap'),
stackId: getSeriesStackId(seriesModel)
});
});
return {
bandWidthResult: bandWidthResult,
seriesInfo: seriesInfoOnAxis
};
}
/**
* CAUTION: When multiple series are laid out on one axis, relevant ec options effect all series.
* But for historical reason, these options are configured on each series option, which may
* introduce confliction. The legacy implementation uses some options (e.g., `defaultBarGap`)
* from the first declared series, and other options (e.g., `barGap`, `barCategoryGap`) from the last declared
* series. Nevertheless, We remain this design to avoid breaking change.
*/
function calcBarWidthAndOffset(seriesInfoOnAxis) {
var bandWidth = seriesInfoOnAxis.bandWidthResult.w;
var remainedWidth = bandWidth;
var autoWidthCount = 0;
var barCategoryGapOption;
var barGapOption;
var stackIdList = [];
var stackMap = {};
each(seriesInfoOnAxis.seriesInfo, function (seriesInfo, idx) {
if (!idx) {
barGapOption = seriesInfo.defaultBarGap || 0;
}
var stackId = seriesInfo.stackId;
if (!hasOwn(stackMap, stackId)) {
autoWidthCount++;
}
var stackItem = stackMap[stackId];
if (!stackItem) {
stackItem = stackMap[stackId] = {
width: 0,
maxWidth: 0
};
stackIdList.push(stackId);
}
var barWidth = seriesInfo.barWidth;
if (barWidth && !stackItem.width) {
// See #6312, do not restrict width.
stackItem.width = barWidth;
barWidth = mathMin(remainedWidth, barWidth);
remainedWidth -= barWidth;
}
var barMaxWidth = seriesInfo.barMaxWidth;
barMaxWidth && (stackItem.maxWidth = barMaxWidth);
var barMinWidth = seriesInfo.barMinWidth;
barMinWidth && (stackItem.minWidth = barMinWidth);
var barGap = seriesInfo.barGap;
barGap != null && (barGapOption = barGap);
var barCategoryGap = seriesInfo.barCategoryGap;
barCategoryGap != null && (barCategoryGapOption = barCategoryGap);
});
if (barCategoryGapOption == null) {
// More columns in one group
// the spaces between group is smaller. Or the column will be too thin.
barCategoryGapOption = mathMax(35 - stackIdList.length * 4, 15) + '%';
}
var barCategoryGapNum = parsePercent(barCategoryGapOption, bandWidth);
var barGapPercent = parsePercent(barGapOption, 1);
var autoWidth = (remainedWidth - barCategoryGapNum) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
autoWidth = mathMax(autoWidth, 0);
// Find if any auto calculated bar exceeded maxBarWidth
each(stackIdList, function (stackId) {
var column = stackMap[stackId];
var maxWidth = column.maxWidth;
var minWidth = column.minWidth;
if (!column.width) {
var finalWidth = autoWidth;
if (maxWidth && maxWidth < finalWidth) {
finalWidth = mathMin(maxWidth, remainedWidth);
}
// `minWidth` has higher priority. `minWidth` decide that whether the
// bar is able to be visible. So `minWidth` should not be restricted
// by `maxWidth` or `remainedWidth` (which is from `bandWidth`). In
// the extreme cases for `value` axis, bars are allowed to overlap
// with each other if `minWidth` specified.
if (minWidth && minWidth > finalWidth) {
finalWidth = minWidth;
}
if (finalWidth !== autoWidth) {
column.width = finalWidth;
remainedWidth -= finalWidth + barGapPercent * finalWidth;
autoWidthCount--;
}
} else {
// `barMinWidth/barMaxWidth` has higher priority than `barWidth`, as
// CSS does. Because barWidth can be a percent value, where
// `barMaxWidth` can be used to restrict the final width.
var finalWidth = column.width;
if (maxWidth) {
finalWidth = mathMin(finalWidth, maxWidth);
}
// `minWidth` has higher priority, as described above
if (minWidth) {
finalWidth = mathMax(finalWidth, minWidth);
}
column.width = finalWidth;
remainedWidth -= finalWidth + barGapPercent * finalWidth;
autoWidthCount--;
}
});
// Recalculate width again
autoWidth = (remainedWidth - barCategoryGapNum) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
autoWidth = mathMax(autoWidth, 0);
var widthSum = 0;
var lastColumn;
each(stackIdList, function (stackId) {
var column = stackMap[stackId];
if (!column.width) {
column.width = autoWidth;
}
lastColumn = column;
widthSum += column.width * (1 + barGapPercent);
});
if (lastColumn) {
widthSum -= lastColumn.width * barGapPercent;
}
var result = {};
var offset = -widthSum / 2;
each(stackIdList, function (stackId) {
var column = stackMap[stackId];
result[stackId] = result[stackId] || {
bandWidth: bandWidth,
offset: offset,
width: column.width
};
offset += column.width * (1 + barGapPercent);
});
return result;
}
export function createCrossSeriesLayoutHandler(seriesType) {
return {
seriesType: seriesType,
overallReset: function (ecModel) {
var axisStatKey = makeAxisStatKey2(seriesType, COORD_SYS_TYPE_CARTESIAN_2D);
eachAxisOnKey(ecModel, axisStatKey, function (axis) {
if (process.env.NODE_ENV !== 'production') {
assert(axis instanceof Axis2D);
}
var columnLayout = makeColumnLayoutOnAxisReal(axis, seriesType);
eachSeriesOnAxisOnKey(axis, axisStatKey, function (seriesModel) {
var columnLayoutInfo = columnLayout.columnMap[getSeriesStackId(seriesModel)];
seriesModel.getData().setLayout({
bandWidth: columnLayoutInfo.bandWidth,
offset: columnLayoutInfo.offset,
size: columnLayoutInfo.width
});
});
});
}
};
}
;
// TODO: Do not support stack in large mode yet.
export function createProgressiveLayout(seriesType) {
return {
seriesType: seriesType,
plan: createRenderPlanner(),
reset: function (seriesModel) {
if (!isCartesian2DInjectedAsDataCoordSys(seriesModel)) {
return;
}
var data = seriesModel.getData();
var cartesian = seriesModel.coordinateSystem;
var baseAxis = cartesian.getBaseAxis();
var valueAxis = cartesian.getOtherAxis(baseAxis);
var valueDimIdx = data.getDimensionIndex(data.mapDimension(valueAxis.dim));
var baseDimIdx = data.getDimensionIndex(data.mapDimension(baseAxis.dim));
var drawBackground = seriesModel.get('showBackground', true);
var valueDim = data.mapDimension(valueAxis.dim);
var stackResultDim = data.getCalculationInfo('stackResultDimension');
var stacked = isDimensionStacked(data, valueDim) && !!data.getCalculationInfo('stackedOnSeries');
var isValueAxisH = valueAxis.isHorizontal();
var valueAxisStart = valueAxis.toGlobalCoord(valueAxis.dataToCoord(getStartValue(valueAxis)));
var isLarge = isInLargeMode(seriesModel);
var barMinHeight = seriesModel.get('barMinHeight') || 0;
var stackedDimIdx = stackResultDim && data.getDimensionIndex(stackResultDim);
// Layout info.
var columnWidth = data.getLayout('size');
var columnOffset = data.getLayout('offset');
return {
progress: function (params, data) {
var count = params.count;
var largePoints = isLarge && createFloat32Array(count * 3);
var largeBackgroundPoints = isLarge && drawBackground && createFloat32Array(count * 3);
var largeDataIndices = isLarge && createFloat32Array(count);
var coordLayout = cartesian.master.getRect();
var bgSize = isValueAxisH ? coordLayout.width : coordLayout.height;
var dataIndex;
var store = data.getStore();
var idxOffset = 0;
while ((dataIndex = params.next()) != null) {
var value = store.get(stacked ? stackedDimIdx : valueDimIdx, dataIndex);
var baseValue = store.get(baseDimIdx, dataIndex);
var baseCoord = valueAxisStart;
var stackStartValue = void 0;
// Because of the barMinHeight, we can not use the value in
// stackResultDimension directly.
if (stacked) {
stackStartValue = +value - store.get(valueDimIdx, dataIndex);
}
var x = void 0;
var y = void 0;
var width = void 0;
var height = void 0;
if (isValueAxisH) {
var coord = cartesian.dataToPoint([value, baseValue]);
if (stacked) {
baseCoord = cartesian.dataToPoint([stackStartValue, baseValue])[0];
}
x = baseCoord;
y = coord[1] + columnOffset;
width = coord[0] - baseCoord;
height = columnWidth;
if (mathAbs(width) < barMinHeight) {
width = (width < 0 ? -1 : 1) * barMinHeight;
}
} else {
var coord = cartesian.dataToPoint([baseValue, value]);
if (stacked) {
baseCoord = cartesian.dataToPoint([baseValue, stackStartValue])[1];
}
x = coord[0] + columnOffset;
y = baseCoord;
width = columnWidth;
height = coord[1] - baseCoord;
if (mathAbs(height) < barMinHeight) {
// Include zero to has a positive bar
height = (height <= 0 ? -1 : 1) * barMinHeight;
}
}
if (!isLarge) {
data.setItemLayout(dataIndex, {
x: x,
y: y,
width: width,
height: height
});
} else {
largePoints[idxOffset] = x;
largePoints[idxOffset + 1] = y;
largePoints[idxOffset + 2] = isValueAxisH ? width : height;
if (largeBackgroundPoints) {
largeBackgroundPoints[idxOffset] = isValueAxisH ? coordLayout.x : x;
largeBackgroundPoints[idxOffset + 1] = isValueAxisH ? y : coordLayout.y;
largeBackgroundPoints[idxOffset + 2] = bgSize;
}
largeDataIndices[dataIndex] = dataIndex;
}
idxOffset += 3;
}
if (isLarge) {
data.setLayout({
largePoints: largePoints,
largeDataIndices: largeDataIndices,
largeBackgroundPoints: largeBackgroundPoints,
valueAxisHorizontal: isValueAxisH
});
}
}
};
}
};
}
function isInLargeMode(seriesModel) {
return seriesModel.pipelineContext && seriesModel.pipelineContext.large;
}
function barGridCreateAxisContainShapeHandler(seriesType) {
// See also #6728, #4862, `test/bar-overflow-time-plot.html` `test/bar-overflow-plot2.html`
// NOTE:
// Series shapes may overflow `bandWidth` when ec option is set like:
// - `barWidth` > 100%.
// - `barWidth` is set as absolute pixel values and `dataZoom` is used, since `bandWidth` is
// calculated on data space rather than pixel space.
// We originally used `calcShapeOverflowSupplement` to cover this case, but it still can not
// resolve pixel `barWidth` case perfectly. A thorough solution may introduce considerable complex,
// but may not necessary, since users can avoid it by proper ec option settings.
// Therefore, we use simply `createBandWidthBasedAxisContainShapeHandler` to calculate "containShape"
// only based on `bandWidth`.
return createBandWidthBasedAxisContainShapeHandler(makeAxisStatKey2(seriesType, COORD_SYS_TYPE_CARTESIAN_2D));
// return function (axis, scale, ecModel) {
// if (!countSeriesOnAxisOnKey(axis, makeAxisStatKey2(seriesType, COORD_SYS_TYPE_CARTESIAN_2D))) {
// return; // Quick path - in most cases there is no bar on non-ordinal axis.
// }
// const columnLayout = makeColumnLayoutOnAxisReal(axis, seriesType);
// return calcShapeOverflowSupplement(columnLayout);
// };
}
// /**
// * @see [AXIS_CONTAIN_SHAPE_COMMON_STRATEGY] for more details.
// */
// function calcShapeOverflowSupplement(
// columnLayout: BarGridColumnLayoutOnAxis | NullUndefined
// ): number[] | NullUndefined {
// if (columnLayout == null) {
// return;
// }
// const bandWidthResult = columnLayout.bandWidthResult;
// const invRatio = bandWidthResult.invRatio;
// if (!isNullableNumberFinite(invRatio)) {
// return; // No series data or no more than one distinct valid data values.
// }
// const barsBoundPx = initExtentForUnion();
// const bandWidth = bandWidthResult.w;
// // Union `-bandWidth / 2` and `bandWidth / 2` to provide extra space for visually preferred,
// // Otherwise the bars on the edges may overlap with axis line.
// // And it also includes `0`, which ensures `barsBoundPx[0] <= 0 <= barsBoundPx[1]`.
// unionExtentFromNumber(barsBoundPx, -bandWidth / 2);
// unionExtentFromNumber(barsBoundPx, bandWidth / 2);
// // Shapes may overflow the `bandWidth`. For example, that might happen in `pictorialBar`.
// // Therefore, we also involve shape size (mapped to data scale) in this expansion calculation.
// each(columnLayout.columnMap, function (item) {
// unionExtentFromNumber(barsBoundPx, item.offset);
// unionExtentFromNumber(barsBoundPx, item.offset + item.width);
// });
// if (extentHasValue(barsBoundPx)) {
// // Convert from pixel domain to data domain, since the `barsBoundPx` is calculated based on
// // `minGap` and extent on data domain.
// return [barsBoundPx[0] * invRatio, barsBoundPx[1] * invRatio];
// // If AXIS_BAND_WIDTH_KIND_SINGULAR, extent expansion is not needed.
// }
// }
export function registerBarGridAxisHandlers(registers) {
callOnlyOnce(registers, function () {
function register(seriesType) {
var axisStatKey = makeAxisStatKey2(seriesType, COORD_SYS_TYPE_CARTESIAN_2D);
requireAxisStatisticsForBaseBar(registers, axisStatKey, seriesType, COORD_SYS_TYPE_CARTESIAN_2D);
registerAxisContainShapeHandler(axisStatKey, barGridCreateAxisContainShapeHandler(seriesType));
}
register('bar');
register('pictorialBar');
});
}
+262
View File
@@ -0,0 +1,262 @@
/*
* 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 { mathAbs, mathMax, mathMin, mathPI, parsePercent } from '../util/number.js';
import { isDimensionStacked } from '../data/helper/dataStackHelper.js';
import AngleAxis from '../coord/polar/AngleAxis.js';
import RadiusAxis from '../coord/polar/RadiusAxis.js';
import { calcBandWidth } from '../coord/axisBand.js';
import { createBandWidthBasedAxisContainShapeHandler, makeAxisStatKey2 } from '../chart/helper/axisSnippets.js';
import { createSimpleOverallStageHandler, makeCallOnlyOnce } from '../util/model.js';
import { registerAxisContainShapeHandler } from '../coord/scaleRawExtentInfo.js';
import { getStartValue, requireAxisStatisticsForBaseBar, SERIES_TYPE_BAR } from './barCommon.js';
import { eachAxisOnKey, eachSeriesOnAxisOnKey } from '../coord/axisStatistics.js';
import { COORD_SYS_TYPE_POLAR } from '../coord/polar/PolarModel.js';
import { assert, each } from 'zrender/lib/core/util.js';
var callOnlyOnce = makeCallOnlyOnce();
function getSeriesStackId(seriesModel) {
return seriesModel.get('stack') || '__ec_stack_' + seriesModel.seriesIndex;
}
export var barLayoutPolarStageHandler = createSimpleOverallStageHandler(SERIES_TYPE_BAR, barLayoutPolar);
function barLayoutPolar(ecModel) {
var axisStatKey = makeAxisStatKey2(SERIES_TYPE_BAR, COORD_SYS_TYPE_POLAR);
eachAxisOnKey(ecModel, axisStatKey, function (axis) {
if (process.env.NODE_ENV !== 'production') {
assert(axis instanceof AngleAxis || axis instanceof RadiusAxis);
}
var barWidthAndOffset = calcRadialBar(axis, SERIES_TYPE_BAR);
var lastStackCoords = {};
eachSeriesOnAxisOnKey(axis, axisStatKey, function (seriesModel) {
layoutPerAxisPerSeries(axis, seriesModel, barWidthAndOffset, lastStackCoords);
});
});
}
function layoutPerAxisPerSeries(baseAxis, seriesModel, barWidthAndOffset, lastStackCoords) {
var data = seriesModel.getData();
var stackId = getSeriesStackId(seriesModel);
var columnLayoutInfo = barWidthAndOffset[stackId];
var columnOffset = columnLayoutInfo.offset;
var columnWidth = columnLayoutInfo.width;
var polar = seriesModel.coordinateSystem;
if (process.env.NODE_ENV !== 'production') {
assert(polar.type === COORD_SYS_TYPE_POLAR);
}
var valueAxis = polar.getOtherAxis(baseAxis);
var cx = polar.cx;
var cy = polar.cy;
var barMinHeight = seriesModel.get('barMinHeight') || 0;
var barMinAngle = seriesModel.get('barMinAngle') || 0;
lastStackCoords[stackId] = lastStackCoords[stackId] || [];
var valueDim = data.mapDimension(valueAxis.dim);
var baseDim = data.mapDimension(baseAxis.dim);
var stacked = isDimensionStacked(data, valueDim /* , baseDim */);
var clampLayout = baseAxis.dim !== 'radius' || !seriesModel.get('roundCap', true);
var valueAxisStart = valueAxis.dataToCoord(getStartValue(valueAxis));
for (var idx = 0, len = data.count(); idx < len; idx++) {
var value = data.get(valueDim, idx);
var baseValue = data.get(baseDim, idx);
var sign = value >= 0 ? 'p' : 'n';
var baseCoord = valueAxisStart;
// Because of the barMinHeight, we can not use the value in
// stackResultDimension directly.
if (stacked) {
// FIXME: follow the same logic in `barGrid.ts`:
// Use stackResultDimension, and lastStackCoords is not needed.
if (!lastStackCoords[stackId][baseValue]) {
lastStackCoords[stackId][baseValue] = {
p: valueAxisStart,
n: valueAxisStart // Negative stack
};
}
// Should also consider #4243
baseCoord = lastStackCoords[stackId][baseValue][sign];
}
var r0 = void 0;
var r = void 0;
var startAngle = void 0;
var endAngle = void 0;
// radial sector
if (valueAxis.dim === 'radius') {
var radiusSpan = valueAxis.dataToCoord(value) - valueAxisStart;
var angle = baseAxis.dataToCoord(baseValue);
if (mathAbs(radiusSpan) < barMinHeight) {
radiusSpan = (radiusSpan < 0 ? -1 : 1) * barMinHeight;
}
r0 = baseCoord;
r = baseCoord + radiusSpan;
startAngle = angle - columnOffset;
endAngle = startAngle - columnWidth;
stacked && (lastStackCoords[stackId][baseValue][sign] = r);
}
// tangential sector
else {
var angleSpan = valueAxis.dataToCoord(value, clampLayout) - valueAxisStart;
var radius = baseAxis.dataToCoord(baseValue);
if (mathAbs(angleSpan) < barMinAngle) {
angleSpan = (angleSpan < 0 ? -1 : 1) * barMinAngle;
}
r0 = radius + columnOffset;
r = r0 + columnWidth;
startAngle = baseCoord;
endAngle = baseCoord + angleSpan;
// if the previous stack is at the end of the ring,
// add a round to differentiate it from origin
// let extent = angleAxis.getExtent();
// let stackCoord = angle;
// if (stackCoord === extent[0] && value > 0) {
// stackCoord = extent[1];
// }
// else if (stackCoord === extent[1] && value < 0) {
// stackCoord = extent[0];
// }
stacked && (lastStackCoords[stackId][baseValue][sign] = endAngle);
}
data.setItemLayout(idx, {
cx: cx,
cy: cy,
r0: r0,
r: r,
// Consider that positive angle is anti-clockwise,
// while positive radian of sector is clockwise
startAngle: -startAngle * mathPI / 180,
endAngle: -endAngle * mathPI / 180,
/**
* Keep the same logic with bar in catesion: use end value to
* control direction. Notice that if clockwise is true (by
* default), the sector will always draw clockwisely, no matter
* whether endAngle is greater or less than startAngle.
*/
clockwise: startAngle >= endAngle
});
}
}
/**
* Calculate bar width and offset for radial bar charts
*/
function calcRadialBar(axis, seriesType) {
var axisStatKey = makeAxisStatKey2(seriesType, COORD_SYS_TYPE_POLAR);
var bandWidth = calcBandWidth(axis, {
fromStat: {
key: axisStatKey
},
min: 1
}).w;
var remainedWidth = bandWidth;
var autoWidthCount = 0;
var categoryGapOption = '20%';
var gapOption = '30%';
var stacks = {};
eachSeriesOnAxisOnKey(axis, axisStatKey, function (seriesModel) {
var stackId = getSeriesStackId(seriesModel);
if (!stacks[stackId]) {
autoWidthCount++;
}
stacks[stackId] = stacks[stackId] || {
width: 0,
maxWidth: 0
};
var barWidth = parsePercent(seriesModel.get('barWidth'), bandWidth);
var barMaxWidth = parsePercent(seriesModel.get('barMaxWidth'), bandWidth);
var barGapOption = seriesModel.get('barGap');
var barCategoryGapOption = seriesModel.get('barCategoryGap');
if (barWidth && !stacks[stackId].width) {
barWidth = mathMin(remainedWidth, barWidth);
stacks[stackId].width = barWidth;
remainedWidth -= barWidth;
}
barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth);
// For historical design, use the last series declared that.
barGapOption != null && (gapOption = barGapOption);
barCategoryGapOption != null && (categoryGapOption = barCategoryGapOption);
});
var result = {};
var categoryGap = parsePercent(categoryGapOption, bandWidth);
var barGapPercent = parsePercent(gapOption, 1);
var autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
autoWidth = mathMax(autoWidth, 0);
// Find if any auto calculated bar exceeded maxBarWidth
each(stacks, function (column, stack) {
var maxWidth = column.maxWidth;
if (maxWidth && maxWidth < autoWidth) {
maxWidth = mathMin(maxWidth, remainedWidth);
if (column.width) {
maxWidth = mathMin(maxWidth, column.width);
}
remainedWidth -= maxWidth;
column.width = maxWidth;
autoWidthCount--;
}
});
// Recalculate width again
autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
autoWidth = mathMax(autoWidth, 0);
var widthSum = 0;
var lastColumn;
each(stacks, function (column, idx) {
if (!column.width) {
column.width = autoWidth;
}
lastColumn = column;
widthSum += column.width * (1 + barGapPercent);
});
if (lastColumn) {
widthSum -= lastColumn.width * barGapPercent;
}
var offset = -widthSum / 2;
each(stacks, function (column, stackId) {
result[stackId] = result[stackId] || {
offset: offset,
width: column.width
};
offset += column.width * (1 + barGapPercent);
});
return result;
}
export function registerBarPolarAxisHandlers(registers, seriesType // Currently only 'bar' is supported.
) {
callOnlyOnce(registers, function () {
var axisStatKey = makeAxisStatKey2(seriesType, COORD_SYS_TYPE_POLAR);
requireAxisStatisticsForBaseBar(registers, axisStatKey, seriesType, COORD_SYS_TYPE_POLAR);
registerAxisContainShapeHandler(axisStatKey, createBandWidthBasedAxisContainShapeHandler(axisStatKey));
});
}
+111
View File
@@ -0,0 +1,111 @@
/*
* 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 { map } from 'zrender/lib/core/util.js';
import createRenderPlanner from '../chart/helper/createRenderPlanner.js';
import { isDimensionStacked } from '../data/helper/dataStackHelper.js';
import { createFloat32Array } from '../util/vendor.js';
export default function pointsLayout(seriesType, forceStoreInTypedArray) {
return {
seriesType: seriesType,
plan: createRenderPlanner(),
reset: function (seriesModel) {
var data = seriesModel.getData();
var coordSys = seriesModel.coordinateSystem;
var pipelineContext = seriesModel.pipelineContext;
var useTypedArray = forceStoreInTypedArray || pipelineContext.large;
if (!coordSys) {
return;
}
var dims = map(coordSys.dimensions, function (dim) {
return data.mapDimension(dim);
}).slice(0, 2);
var dimLen = dims.length;
var stackResultDim = data.getCalculationInfo('stackResultDimension');
if (isDimensionStacked(data, dims[0])) {
dims[0] = stackResultDim;
}
if (isDimensionStacked(data, dims[1])) {
dims[1] = stackResultDim;
}
var store = data.getStore();
var dimIdx0 = data.getDimensionIndex(dims[0]);
var dimIdx1 = data.getDimensionIndex(dims[1]);
return dimLen && {
progress: function (params, data) {
var segCount = params.end - params.start;
var points = useTypedArray && createFloat32Array(segCount * dimLen);
var tmpIn = [];
var tmpOut = [];
for (var i = params.start, offset = 0; i < params.end; i++) {
var point = void 0;
if (dimLen === 1) {
var x = store.get(dimIdx0, i);
// NOTE: Make sure the second parameter is null to use default strategy.
point = coordSys.dataToPoint(x, null, tmpOut);
} else {
tmpIn[0] = store.get(dimIdx0, i);
tmpIn[1] = store.get(dimIdx1, i);
// Let coordinate system to handle the NaN data.
point = coordSys.dataToPoint(tmpIn, null, tmpOut);
}
if (useTypedArray) {
points[offset++] = point[0];
points[offset++] = point[1];
} else {
data.setItemLayout(i, point.slice());
}
}
if (useTypedArray) {
data.setLayout('points', points);
data.setLayout('pointsRange', {
start: params.start,
end: params.end
});
}
}
};
}
};
}
;