逐步完成前后端服务器

This commit is contained in:
2025-09-09 15:00:30 +08:00
parent fcb09432e9
commit c7dfa1e9fc
2937 changed files with 1477567 additions and 0 deletions

View File

@ -0,0 +1,230 @@
/*
* 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 { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import * as graphic from '../../util/graphic.js';
import { toggleHoverEmphasis, SPECIAL_STATES, DISPLAY_STATES } from '../../util/states.js';
import { createTextStyle } from '../../label/labelStyle.js';
import { getECData } from '../../util/innerStore.js';
import { getSectorCornerRadius } from '../helper/sectorHelper.js';
import { createOrUpdatePatternFromDecal } from '../../util/decal.js';
import { saveOldStyle } from '../../animation/basicTransition.js';
import { normalizeRadian } from 'zrender/lib/contain/util.js';
import { isRadianAroundZero } from '../../util/number.js';
var DEFAULT_SECTOR_Z = 2;
var DEFAULT_TEXT_Z = 4;
/**
* Sunburstce of Sunburst including Sector, Label, LabelLine
*/
var SunburstPiece = /** @class */function (_super) {
__extends(SunburstPiece, _super);
function SunburstPiece(node, seriesModel, ecModel, api) {
var _this = _super.call(this) || this;
_this.z2 = DEFAULT_SECTOR_Z;
_this.textConfig = {
inside: true
};
getECData(_this).seriesIndex = seriesModel.seriesIndex;
var text = new graphic.Text({
z2: DEFAULT_TEXT_Z,
silent: node.getModel().get(['label', 'silent'])
});
_this.setTextContent(text);
_this.updateData(true, node, seriesModel, ecModel, api);
return _this;
}
SunburstPiece.prototype.updateData = function (firstCreate, node,
// state: 'emphasis' | 'normal' | 'highlight' | 'downplay',
seriesModel, ecModel, api) {
this.node = node;
node.piece = this;
seriesModel = seriesModel || this._seriesModel;
ecModel = ecModel || this._ecModel;
var sector = this;
getECData(sector).dataIndex = node.dataIndex;
var itemModel = node.getModel();
var emphasisModel = itemModel.getModel('emphasis');
var layout = node.getLayout();
var sectorShape = zrUtil.extend({}, layout);
sectorShape.label = null;
var normalStyle = node.getVisual('style');
normalStyle.lineJoin = 'bevel';
var decal = node.getVisual('decal');
if (decal) {
normalStyle.decal = createOrUpdatePatternFromDecal(decal, api);
}
var cornerRadius = getSectorCornerRadius(itemModel.getModel('itemStyle'), sectorShape, true);
zrUtil.extend(sectorShape, cornerRadius);
zrUtil.each(SPECIAL_STATES, function (stateName) {
var state = sector.ensureState(stateName);
var itemStyleModel = itemModel.getModel([stateName, 'itemStyle']);
state.style = itemStyleModel.getItemStyle();
// border radius
var cornerRadius = getSectorCornerRadius(itemStyleModel, sectorShape);
if (cornerRadius) {
state.shape = cornerRadius;
}
});
if (firstCreate) {
sector.setShape(sectorShape);
sector.shape.r = layout.r0;
graphic.initProps(sector, {
shape: {
r: layout.r
}
}, seriesModel, node.dataIndex);
} else {
// Disable animation for gradient since no interpolation method
// is supported for gradient
graphic.updateProps(sector, {
shape: sectorShape
}, seriesModel);
saveOldStyle(sector);
}
sector.useStyle(normalStyle);
this._updateLabel(seriesModel);
var cursorStyle = itemModel.getShallow('cursor');
cursorStyle && sector.attr('cursor', cursorStyle);
this._seriesModel = seriesModel || this._seriesModel;
this._ecModel = ecModel || this._ecModel;
var focus = emphasisModel.get('focus');
var focusOrIndices = focus === 'relative' ? zrUtil.concatArray(node.getAncestorsIndices(), node.getDescendantIndices()) : focus === 'ancestor' ? node.getAncestorsIndices() : focus === 'descendant' ? node.getDescendantIndices() : focus;
toggleHoverEmphasis(this, focusOrIndices, emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
};
SunburstPiece.prototype._updateLabel = function (seriesModel) {
var _this = this;
var itemModel = this.node.getModel();
var normalLabelModel = itemModel.getModel('label');
var layout = this.node.getLayout();
var angle = layout.endAngle - layout.startAngle;
var midAngle = (layout.startAngle + layout.endAngle) / 2;
var dx = Math.cos(midAngle);
var dy = Math.sin(midAngle);
var sector = this;
var label = sector.getTextContent();
var dataIndex = this.node.dataIndex;
var labelMinAngle = normalLabelModel.get('minAngle') / 180 * Math.PI;
var isNormalShown = normalLabelModel.get('show') && !(labelMinAngle != null && Math.abs(angle) < labelMinAngle);
label.ignore = !isNormalShown;
// TODO use setLabelStyle
zrUtil.each(DISPLAY_STATES, function (stateName) {
var labelStateModel = stateName === 'normal' ? itemModel.getModel('label') : itemModel.getModel([stateName, 'label']);
var isNormal = stateName === 'normal';
var state = isNormal ? label : label.ensureState(stateName);
var text = seriesModel.getFormattedLabel(dataIndex, stateName);
if (isNormal) {
text = text || _this.node.name;
}
state.style = createTextStyle(labelStateModel, {}, null, stateName !== 'normal', true);
if (text) {
state.style.text = text;
}
// Not displaying text when angle is too small
var isShown = labelStateModel.get('show');
if (isShown != null && !isNormal) {
state.ignore = !isShown;
}
var labelPosition = getLabelAttr(labelStateModel, 'position');
var sectorState = isNormal ? sector : sector.states[stateName];
var labelColor = sectorState.style.fill;
sectorState.textConfig = {
outsideFill: labelStateModel.get('color') === 'inherit' ? labelColor : null,
inside: labelPosition !== 'outside'
};
var r;
var labelPadding = getLabelAttr(labelStateModel, 'distance') || 0;
var textAlign = getLabelAttr(labelStateModel, 'align');
var rotateType = getLabelAttr(labelStateModel, 'rotate');
var flipStartAngle = Math.PI * 0.5;
var flipEndAngle = Math.PI * 1.5;
var midAngleNormal = normalizeRadian(rotateType === 'tangential' ? Math.PI / 2 - midAngle : midAngle);
// For text that is up-side down, rotate 180 degrees to make sure
// it's readable
var needsFlip = midAngleNormal > flipStartAngle && !isRadianAroundZero(midAngleNormal - flipStartAngle) && midAngleNormal < flipEndAngle;
if (labelPosition === 'outside') {
r = layout.r + labelPadding;
textAlign = needsFlip ? 'right' : 'left';
} else {
if (!textAlign || textAlign === 'center') {
// Put label in the center if it's a circle
if (angle === 2 * Math.PI && layout.r0 === 0) {
r = 0;
} else {
r = (layout.r + layout.r0) / 2;
}
textAlign = 'center';
} else if (textAlign === 'left') {
r = layout.r0 + labelPadding;
textAlign = needsFlip ? 'right' : 'left';
} else if (textAlign === 'right') {
r = layout.r - labelPadding;
textAlign = needsFlip ? 'left' : 'right';
}
}
state.style.align = textAlign;
state.style.verticalAlign = getLabelAttr(labelStateModel, 'verticalAlign') || 'middle';
state.x = r * dx + layout.cx;
state.y = r * dy + layout.cy;
var rotate = 0;
if (rotateType === 'radial') {
rotate = normalizeRadian(-midAngle) + (needsFlip ? Math.PI : 0);
} else if (rotateType === 'tangential') {
rotate = normalizeRadian(Math.PI / 2 - midAngle) + (needsFlip ? Math.PI : 0);
} else if (zrUtil.isNumber(rotateType)) {
rotate = rotateType * Math.PI / 180;
}
state.rotation = normalizeRadian(rotate);
});
function getLabelAttr(model, name) {
var stateAttr = model.get(name);
if (stateAttr == null) {
return normalLabelModel.get(name);
}
return stateAttr;
}
label.dirtyStyle();
};
return SunburstPiece;
}(graphic.Sector);
export default SunburstPiece;

View File

@ -0,0 +1,206 @@
/*
* 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 { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import SeriesModel from '../../model/Series.js';
import Tree from '../../data/Tree.js';
import { wrapTreePathInfo } from '../helper/treeHelper.js';
import Model from '../../model/Model.js';
import enableAriaDecalForTree from '../helper/enableAriaDecalForTree.js';
var SunburstSeriesModel = /** @class */function (_super) {
__extends(SunburstSeriesModel, _super);
function SunburstSeriesModel() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = SunburstSeriesModel.type;
_this.ignoreStyleOnData = true;
return _this;
}
SunburstSeriesModel.prototype.getInitialData = function (option, ecModel) {
// Create a virtual root.
var root = {
name: option.name,
children: option.data
};
completeTreeValue(root);
var levelModels = this._levelModels = zrUtil.map(option.levels || [], function (levelDefine) {
return new Model(levelDefine, this, ecModel);
}, this);
// Make sure always a new tree is created when setOption,
// in TreemapView, we check whether oldTree === newTree
// to choose mappings approach among old shapes and new shapes.
var tree = Tree.createTree(root, this, beforeLink);
function beforeLink(nodeData) {
nodeData.wrapMethod('getItemModel', function (model, idx) {
var node = tree.getNodeByDataIndex(idx);
var levelModel = levelModels[node.depth];
levelModel && (model.parentModel = levelModel);
return model;
});
}
return tree.data;
};
SunburstSeriesModel.prototype.optionUpdated = function () {
this.resetViewRoot();
};
/*
* @override
*/
SunburstSeriesModel.prototype.getDataParams = function (dataIndex) {
var params = _super.prototype.getDataParams.apply(this, arguments);
var node = this.getData().tree.getNodeByDataIndex(dataIndex);
params.treePathInfo = wrapTreePathInfo(node, this);
return params;
};
SunburstSeriesModel.prototype.getLevelModel = function (node) {
return this._levelModels && this._levelModels[node.depth];
};
SunburstSeriesModel.prototype.getViewRoot = function () {
return this._viewRoot;
};
SunburstSeriesModel.prototype.resetViewRoot = function (viewRoot) {
viewRoot ? this._viewRoot = viewRoot : viewRoot = this._viewRoot;
var root = this.getRawData().tree.root;
if (!viewRoot || viewRoot !== root && !root.contains(viewRoot)) {
this._viewRoot = root;
}
};
SunburstSeriesModel.prototype.enableAriaDecal = function () {
enableAriaDecalForTree(this);
};
SunburstSeriesModel.type = 'series.sunburst';
SunburstSeriesModel.defaultOption = {
// zlevel: 0,
z: 2,
// 默认全局居中
center: ['50%', '50%'],
radius: [0, '75%'],
// 默认顺时针
clockwise: true,
startAngle: 90,
// 最小角度改为0
minAngle: 0,
// If still show when all data zero.
stillShowZeroSum: true,
// 'rootToNode', 'link', or false
nodeClick: 'rootToNode',
renderLabelForZeroData: false,
label: {
// could be: 'radial', 'tangential', or 'none'
rotate: 'radial',
show: true,
opacity: 1,
// 'left' is for inner side of inside, and 'right' is for outer
// side for inside
align: 'center',
position: 'inside',
distance: 5,
silent: true
},
itemStyle: {
borderWidth: 1,
borderColor: 'white',
borderType: 'solid',
shadowBlur: 0,
shadowColor: 'rgba(0, 0, 0, 0.2)',
shadowOffsetX: 0,
shadowOffsetY: 0,
opacity: 1
},
emphasis: {
focus: 'descendant'
},
blur: {
itemStyle: {
opacity: 0.2
},
label: {
opacity: 0.1
}
},
// Animation type can be expansion, scale.
animationType: 'expansion',
animationDuration: 1000,
animationDurationUpdate: 500,
data: [],
/**
* Sort order.
*
* Valid values: 'desc', 'asc', null, or callback function.
* 'desc' and 'asc' for descend and ascendant order;
* null for not sorting;
* example of callback function:
* function(nodeA, nodeB) {
* return nodeA.getValue() - nodeB.getValue();
* }
*/
sort: 'desc'
};
return SunburstSeriesModel;
}(SeriesModel);
function completeTreeValue(dataNode) {
// Postorder travel tree.
// If value of none-leaf node is not set,
// calculate it by suming up the value of all children.
var sum = 0;
zrUtil.each(dataNode.children, function (child) {
completeTreeValue(child);
var childValue = child.value;
// TODO First value of array must be a number
zrUtil.isArray(childValue) && (childValue = childValue[0]);
sum += childValue;
});
var thisValue = dataNode.value;
if (zrUtil.isArray(thisValue)) {
thisValue = thisValue[0];
}
if (thisValue == null || isNaN(thisValue)) {
thisValue = sum;
}
// Value should not less than 0.
if (thisValue < 0) {
thisValue = 0;
}
zrUtil.isArray(dataNode.value) ? dataNode.value[0] = thisValue : dataNode.value = thisValue;
}
export default SunburstSeriesModel;

View File

@ -0,0 +1,206 @@
/*
* 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 { __extends } from "tslib";
import * as zrUtil from 'zrender/lib/core/util.js';
import ChartView from '../../view/Chart.js';
import SunburstPiece from './SunburstPiece.js';
import DataDiffer from '../../data/DataDiffer.js';
import { ROOT_TO_NODE_ACTION } from './sunburstAction.js';
import { windowOpen } from '../../util/format.js';
var SunburstView = /** @class */function (_super) {
__extends(SunburstView, _super);
function SunburstView() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.type = SunburstView.type;
return _this;
}
SunburstView.prototype.render = function (seriesModel, ecModel, api,
// @ts-ignore
payload) {
var self = this;
this.seriesModel = seriesModel;
this.api = api;
this.ecModel = ecModel;
var data = seriesModel.getData();
var virtualRoot = data.tree.root;
var newRoot = seriesModel.getViewRoot();
var group = this.group;
var renderLabelForZeroData = seriesModel.get('renderLabelForZeroData');
var newChildren = [];
newRoot.eachNode(function (node) {
newChildren.push(node);
});
var oldChildren = this._oldChildren || [];
dualTravel(newChildren, oldChildren);
renderRollUp(virtualRoot, newRoot);
this._initEvents();
this._oldChildren = newChildren;
function dualTravel(newChildren, oldChildren) {
if (newChildren.length === 0 && oldChildren.length === 0) {
return;
}
new DataDiffer(oldChildren, newChildren, getKey, getKey).add(processNode).update(processNode).remove(zrUtil.curry(processNode, null)).execute();
function getKey(node) {
return node.getId();
}
function processNode(newIdx, oldIdx) {
var newNode = newIdx == null ? null : newChildren[newIdx];
var oldNode = oldIdx == null ? null : oldChildren[oldIdx];
doRenderNode(newNode, oldNode);
}
}
function doRenderNode(newNode, oldNode) {
if (!renderLabelForZeroData && newNode && !newNode.getValue()) {
// Not render data with value 0
newNode = null;
}
if (newNode !== virtualRoot && oldNode !== virtualRoot) {
if (oldNode && oldNode.piece) {
if (newNode) {
// Update
oldNode.piece.updateData(false, newNode, seriesModel, ecModel, api);
// For tooltip
data.setItemGraphicEl(newNode.dataIndex, oldNode.piece);
} else {
// Remove
removeNode(oldNode);
}
} else if (newNode) {
// Add
var piece = new SunburstPiece(newNode, seriesModel, ecModel, api);
group.add(piece);
// For tooltip
data.setItemGraphicEl(newNode.dataIndex, piece);
}
}
}
function removeNode(node) {
if (!node) {
return;
}
if (node.piece) {
group.remove(node.piece);
node.piece = null;
}
}
function renderRollUp(virtualRoot, viewRoot) {
if (viewRoot.depth > 0) {
// Render
if (self.virtualPiece) {
// Update
self.virtualPiece.updateData(false, virtualRoot, seriesModel, ecModel, api);
} else {
// Add
self.virtualPiece = new SunburstPiece(virtualRoot, seriesModel, ecModel, api);
group.add(self.virtualPiece);
}
// TODO event scope
viewRoot.piece.off('click');
self.virtualPiece.on('click', function (e) {
self._rootToNode(viewRoot.parentNode);
});
} else if (self.virtualPiece) {
// Remove
group.remove(self.virtualPiece);
self.virtualPiece = null;
}
}
};
/**
* @private
*/
SunburstView.prototype._initEvents = function () {
var _this = this;
this.group.off('click');
this.group.on('click', function (e) {
var targetFound = false;
var viewRoot = _this.seriesModel.getViewRoot();
viewRoot.eachNode(function (node) {
if (!targetFound && node.piece && node.piece === e.target) {
var nodeClick = node.getModel().get('nodeClick');
if (nodeClick === 'rootToNode') {
_this._rootToNode(node);
} else if (nodeClick === 'link') {
var itemModel = node.getModel();
var link = itemModel.get('link');
if (link) {
var linkTarget = itemModel.get('target', true) || '_blank';
windowOpen(link, linkTarget);
}
}
targetFound = true;
}
});
});
};
/**
* @private
*/
SunburstView.prototype._rootToNode = function (node) {
if (node !== this.seriesModel.getViewRoot()) {
this.api.dispatchAction({
type: ROOT_TO_NODE_ACTION,
from: this.uid,
seriesId: this.seriesModel.id,
targetNode: node
});
}
};
/**
* @implement
*/
SunburstView.prototype.containPoint = function (point, seriesModel) {
var treeRoot = seriesModel.getData();
var itemLayout = treeRoot.getItemLayout(0);
if (itemLayout) {
var dx = point[0] - itemLayout.cx;
var dy = point[1] - itemLayout.cy;
var radius = Math.sqrt(dx * dx + dy * dy);
return radius <= itemLayout.r && radius >= itemLayout.r0;
}
};
SunburstView.type = 'sunburst';
return SunburstView;
}(ChartView);
export default SunburstView;

View File

@ -0,0 +1,58 @@
/*
* 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 SunburstView from './SunburstView.js';
import SunburstSeriesModel from './SunburstSeries.js';
import sunburstLayout from './sunburstLayout.js';
import sunburstVisual from './sunburstVisual.js';
import dataFilter from '../../processor/dataFilter.js';
import { curry } from 'zrender/lib/core/util.js';
import { installSunburstAction } from './sunburstAction.js';
export function install(registers) {
registers.registerChartView(SunburstView);
registers.registerSeriesModel(SunburstSeriesModel);
registers.registerLayout(curry(sunburstLayout, 'sunburst'));
registers.registerProcessor(curry(dataFilter, 'sunburst'));
registers.registerVisual(sunburstVisual);
installSunburstAction(registers);
}

View File

@ -0,0 +1,108 @@
/*
* 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 { extend } from 'zrender/lib/core/util.js';
import { deprecateReplaceLog } from '../../util/log.js';
import { retrieveTargetInfo, aboveViewRoot } from '../helper/treeHelper.js';
export var ROOT_TO_NODE_ACTION = 'sunburstRootToNode';
var HIGHLIGHT_ACTION = 'sunburstHighlight';
var UNHIGHLIGHT_ACTION = 'sunburstUnhighlight';
export function installSunburstAction(registers) {
registers.registerAction({
type: ROOT_TO_NODE_ACTION,
update: 'updateView'
}, function (payload, ecModel) {
ecModel.eachComponent({
mainType: 'series',
subType: 'sunburst',
query: payload
}, handleRootToNode);
function handleRootToNode(model, index) {
var targetInfo = retrieveTargetInfo(payload, [ROOT_TO_NODE_ACTION], model);
if (targetInfo) {
var originViewRoot = model.getViewRoot();
if (originViewRoot) {
payload.direction = aboveViewRoot(originViewRoot, targetInfo.node) ? 'rollUp' : 'drillDown';
}
model.resetViewRoot(targetInfo.node);
}
}
});
registers.registerAction({
type: HIGHLIGHT_ACTION,
update: 'none'
}, function (payload, ecModel, api) {
// Clone
payload = extend({}, payload);
ecModel.eachComponent({
mainType: 'series',
subType: 'sunburst',
query: payload
}, handleHighlight);
function handleHighlight(model) {
var targetInfo = retrieveTargetInfo(payload, [HIGHLIGHT_ACTION], model);
if (targetInfo) {
payload.dataIndex = targetInfo.node.dataIndex;
}
}
if (process.env.NODE_ENV !== 'production') {
deprecateReplaceLog('sunburstHighlight', 'highlight');
}
// Fast forward action
api.dispatchAction(extend(payload, {
type: 'highlight'
}));
});
registers.registerAction({
type: UNHIGHLIGHT_ACTION,
update: 'updateView'
}, function (payload, ecModel, api) {
payload = extend({}, payload);
if (process.env.NODE_ENV !== 'production') {
deprecateReplaceLog('sunburstUnhighlight', 'downplay');
}
api.dispatchAction(extend(payload, {
type: 'downplay'
}));
});
}

View File

@ -0,0 +1,216 @@
/*
* 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 { parsePercent } from '../../util/number.js';
import * as zrUtil from 'zrender/lib/core/util.js';
// let PI2 = Math.PI * 2;
var RADIAN = Math.PI / 180;
export default function sunburstLayout(seriesType, ecModel, api) {
ecModel.eachSeriesByType(seriesType, function (seriesModel) {
var center = seriesModel.get('center');
var radius = seriesModel.get('radius');
if (!zrUtil.isArray(radius)) {
radius = [0, radius];
}
if (!zrUtil.isArray(center)) {
center = [center, center];
}
var width = api.getWidth();
var height = api.getHeight();
var size = Math.min(width, height);
var cx = parsePercent(center[0], width);
var cy = parsePercent(center[1], height);
var r0 = parsePercent(radius[0], size / 2);
var r = parsePercent(radius[1], size / 2);
var startAngle = -seriesModel.get('startAngle') * RADIAN;
var minAngle = seriesModel.get('minAngle') * RADIAN;
var virtualRoot = seriesModel.getData().tree.root;
var treeRoot = seriesModel.getViewRoot();
var rootDepth = treeRoot.depth;
var sort = seriesModel.get('sort');
if (sort != null) {
initChildren(treeRoot, sort);
}
var validDataCount = 0;
zrUtil.each(treeRoot.children, function (child) {
!isNaN(child.getValue()) && validDataCount++;
});
var sum = treeRoot.getValue();
// Sum may be 0
var unitRadian = Math.PI / (sum || validDataCount) * 2;
var renderRollupNode = treeRoot.depth > 0;
var levels = treeRoot.height - (renderRollupNode ? -1 : 1);
var rPerLevel = (r - r0) / (levels || 1);
var clockwise = seriesModel.get('clockwise');
var stillShowZeroSum = seriesModel.get('stillShowZeroSum');
// In the case some sector angle is smaller than minAngle
// let restAngle = PI2;
// let valueSumLargerThanMinAngle = 0;
var dir = clockwise ? 1 : -1;
/**
* Render a tree
* @return increased angle
*/
var renderNode = function (node, startAngle) {
if (!node) {
return;
}
var endAngle = startAngle;
// Render self
if (node !== virtualRoot) {
// Tree node is virtual, so it doesn't need to be drawn
var value = node.getValue();
var angle = sum === 0 && stillShowZeroSum ? unitRadian : value * unitRadian;
if (angle < minAngle) {
angle = minAngle;
// restAngle -= minAngle;
}
// else {
// valueSumLargerThanMinAngle += value;
// }
endAngle = startAngle + dir * angle;
var depth = node.depth - rootDepth - (renderRollupNode ? -1 : 1);
var rStart = r0 + rPerLevel * depth;
var rEnd = r0 + rPerLevel * (depth + 1);
var levelModel = seriesModel.getLevelModel(node);
if (levelModel) {
var r0_1 = levelModel.get('r0', true);
var r_1 = levelModel.get('r', true);
var radius_1 = levelModel.get('radius', true);
if (radius_1 != null) {
r0_1 = radius_1[0];
r_1 = radius_1[1];
}
r0_1 != null && (rStart = parsePercent(r0_1, size / 2));
r_1 != null && (rEnd = parsePercent(r_1, size / 2));
}
node.setLayout({
angle: angle,
startAngle: startAngle,
endAngle: endAngle,
clockwise: clockwise,
cx: cx,
cy: cy,
r0: rStart,
r: rEnd
});
}
// Render children
if (node.children && node.children.length) {
// currentAngle = startAngle;
var siblingAngle_1 = 0;
zrUtil.each(node.children, function (node) {
siblingAngle_1 += renderNode(node, startAngle + siblingAngle_1);
});
}
return endAngle - startAngle;
};
// Virtual root node for roll up
if (renderRollupNode) {
var rStart = r0;
var rEnd = r0 + rPerLevel;
var angle = Math.PI * 2;
virtualRoot.setLayout({
angle: angle,
startAngle: startAngle,
endAngle: startAngle + angle,
clockwise: clockwise,
cx: cx,
cy: cy,
r0: rStart,
r: rEnd
});
}
renderNode(treeRoot, startAngle);
});
}
/**
* Init node children by order and update visual
*/
function initChildren(node, sortOrder) {
var children = node.children || [];
node.children = sort(children, sortOrder);
// Init children recursively
if (children.length) {
zrUtil.each(node.children, function (child) {
initChildren(child, sortOrder);
});
}
}
/**
* Sort children nodes
*
* @param {TreeNode[]} children children of node to be sorted
* @param {string | function | null} sort sort method
* See SunburstSeries.js for details.
*/
function sort(children, sortOrder) {
if (zrUtil.isFunction(sortOrder)) {
var sortTargets = zrUtil.map(children, function (child, idx) {
var value = child.getValue();
return {
params: {
depth: child.depth,
height: child.height,
dataIndex: child.dataIndex,
getValue: function () {
return value;
}
},
index: idx
};
});
sortTargets.sort(function (a, b) {
return sortOrder(a.params, b.params);
});
return zrUtil.map(sortTargets, function (target) {
return children[target.index];
});
} else {
var isAsc_1 = sortOrder === 'asc';
return children.sort(function (a, b) {
var diff = (a.getValue() - b.getValue()) * (isAsc_1 ? 1 : -1);
return diff === 0 ? (a.dataIndex - b.dataIndex) * (isAsc_1 ? -1 : 1) : diff;
});
}
}

View File

@ -0,0 +1,75 @@
/*
* 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 { lift } from 'zrender/lib/tool/color.js';
import { extend, isString } from 'zrender/lib/core/util.js';
export default function sunburstVisual(ecModel) {
var paletteScope = {};
// Default color strategy
function pickColor(node, seriesModel, treeHeight) {
// Choose color from palette based on the first level.
var current = node;
while (current && current.depth > 1) {
current = current.parentNode;
}
var color = seriesModel.getColorFromPalette(current.name || current.dataIndex + '', paletteScope);
if (node.depth > 1 && isString(color)) {
// Lighter on the deeper level.
color = lift(color, (node.depth - 1) / (treeHeight - 1) * 0.5);
}
return color;
}
ecModel.eachSeriesByType('sunburst', function (seriesModel) {
var data = seriesModel.getData();
var tree = data.tree;
tree.eachNode(function (node) {
var model = node.getModel();
var style = model.getModel('itemStyle').getItemStyle();
if (!style.fill) {
style.fill = pickColor(node, seriesModel, tree.root.height);
}
var existsStyle = data.ensureUniqueItemVisual(node.dataIndex, 'style');
extend(existsStyle, style);
});
});
}