first commit
This commit is contained in:
+166
@@ -0,0 +1,166 @@
|
||||
|
||||
/*
|
||||
* 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 { extend, isString } from 'zrender/lib/core/util.js';
|
||||
import * as graphic from '../../util/graphic.js';
|
||||
import { getSectorCornerRadius } from '../helper/sectorHelper.js';
|
||||
import { saveOldStyle } from '../../animation/basicTransition.js';
|
||||
import { setStatesStylesFromModel, toggleHoverEmphasis } from '../../util/states.js';
|
||||
import { getECData } from '../../util/innerStore.js';
|
||||
var ChordPathShape = /** @class */function () {
|
||||
function ChordPathShape() {
|
||||
// Souce node, two points forming an arc
|
||||
this.s1 = [0, 0];
|
||||
this.s2 = [0, 0];
|
||||
this.sStartAngle = 0;
|
||||
this.sEndAngle = 0;
|
||||
// Target node, two points forming an arc
|
||||
this.t1 = [0, 0];
|
||||
this.t2 = [0, 0];
|
||||
this.tStartAngle = 0;
|
||||
this.tEndAngle = 0;
|
||||
this.cx = 0;
|
||||
this.cy = 0;
|
||||
// series.r0 of ChordSeries
|
||||
this.r = 0;
|
||||
this.clockwise = true;
|
||||
}
|
||||
return ChordPathShape;
|
||||
}();
|
||||
export { ChordPathShape };
|
||||
var ChordEdge = /** @class */function (_super) {
|
||||
__extends(ChordEdge, _super);
|
||||
function ChordEdge(nodeData, edgeData, edgeIdx, startAngle) {
|
||||
var _this = _super.call(this) || this;
|
||||
getECData(_this).dataType = 'edge';
|
||||
_this.updateData(nodeData, edgeData, edgeIdx, startAngle, true);
|
||||
return _this;
|
||||
}
|
||||
ChordEdge.prototype.buildPath = function (ctx, shape) {
|
||||
// Start from n11
|
||||
ctx.moveTo(shape.s1[0], shape.s1[1]);
|
||||
var ratio = 0.7;
|
||||
var clockwise = shape.clockwise;
|
||||
// Draw the arc from n11 to n12
|
||||
ctx.arc(shape.cx, shape.cy, shape.r, shape.sStartAngle, shape.sEndAngle, !clockwise);
|
||||
// Bezier curve to cp1 and then to n21
|
||||
ctx.bezierCurveTo((shape.cx - shape.s2[0]) * ratio + shape.s2[0], (shape.cy - shape.s2[1]) * ratio + shape.s2[1], (shape.cx - shape.t1[0]) * ratio + shape.t1[0], (shape.cy - shape.t1[1]) * ratio + shape.t1[1], shape.t1[0], shape.t1[1]);
|
||||
// Draw the arc from n21 to n22
|
||||
ctx.arc(shape.cx, shape.cy, shape.r, shape.tStartAngle, shape.tEndAngle, !clockwise);
|
||||
// Bezier curve back to cp2 and then to n11
|
||||
ctx.bezierCurveTo((shape.cx - shape.t2[0]) * ratio + shape.t2[0], (shape.cy - shape.t2[1]) * ratio + shape.t2[1], (shape.cx - shape.s1[0]) * ratio + shape.s1[0], (shape.cy - shape.s1[1]) * ratio + shape.s1[1], shape.s1[0], shape.s1[1]);
|
||||
ctx.closePath();
|
||||
};
|
||||
ChordEdge.prototype.updateData = function (nodeData, edgeData, edgeIdx, startAngle, firstCreate) {
|
||||
var seriesModel = nodeData.hostModel;
|
||||
var edge = edgeData.graph.getEdgeByIndex(edgeIdx);
|
||||
var layout = edge.getLayout();
|
||||
var itemModel = edge.node1.getModel();
|
||||
var edgeModel = edgeData.getItemModel(edge.dataIndex);
|
||||
var lineStyle = edgeModel.getModel('lineStyle');
|
||||
var emphasisModel = edgeModel.getModel('emphasis');
|
||||
var focus = emphasisModel.get('focus');
|
||||
var shape = extend(getSectorCornerRadius(itemModel.getModel('itemStyle'), layout, true), layout);
|
||||
var el = this;
|
||||
// Ignore NaN data.
|
||||
if (isNaN(shape.sStartAngle) || isNaN(shape.tStartAngle)) {
|
||||
// Use NaN shape to avoid drawing shape.
|
||||
el.setShape(shape);
|
||||
return;
|
||||
}
|
||||
if (firstCreate) {
|
||||
el.setShape(shape);
|
||||
applyEdgeFill(el, edge, nodeData, lineStyle);
|
||||
} else {
|
||||
saveOldStyle(el);
|
||||
applyEdgeFill(el, edge, nodeData, lineStyle);
|
||||
graphic.updateProps(el, {
|
||||
shape: shape
|
||||
}, seriesModel, edgeIdx);
|
||||
}
|
||||
toggleHoverEmphasis(this, focus === 'adjacency' ? edge.getAdjacentDataIndices() : focus, emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
|
||||
setStatesStylesFromModel(el, edgeModel, 'lineStyle');
|
||||
edgeData.setItemGraphicEl(edge.dataIndex, el);
|
||||
};
|
||||
return ChordEdge;
|
||||
}(graphic.Path);
|
||||
export { ChordEdge };
|
||||
function applyEdgeFill(edgeShape, edge, nodeData, lineStyleModel) {
|
||||
var node1 = edge.node1;
|
||||
var node2 = edge.node2;
|
||||
var edgeStyle = edgeShape.style;
|
||||
edgeShape.setStyle(lineStyleModel.getLineStyle());
|
||||
var color = lineStyleModel.get('color');
|
||||
switch (color) {
|
||||
case 'source':
|
||||
// TODO: use visual and node1.getVisual('color');
|
||||
edgeStyle.fill = nodeData.getItemVisual(node1.dataIndex, 'style').fill;
|
||||
edgeStyle.decal = node1.getVisual('style').decal;
|
||||
break;
|
||||
case 'target':
|
||||
edgeStyle.fill = nodeData.getItemVisual(node2.dataIndex, 'style').fill;
|
||||
edgeStyle.decal = node2.getVisual('style').decal;
|
||||
break;
|
||||
case 'gradient':
|
||||
var sourceColor = nodeData.getItemVisual(node1.dataIndex, 'style').fill;
|
||||
var targetColor = nodeData.getItemVisual(node2.dataIndex, 'style').fill;
|
||||
if (isString(sourceColor) && isString(targetColor)) {
|
||||
// Gradient direction is perpendicular to the mid-angles
|
||||
// of source and target nodes.
|
||||
var shape = edgeShape.shape;
|
||||
var sMidX = (shape.s1[0] + shape.s2[0]) / 2;
|
||||
var sMidY = (shape.s1[1] + shape.s2[1]) / 2;
|
||||
var tMidX = (shape.t1[0] + shape.t2[0]) / 2;
|
||||
var tMidY = (shape.t1[1] + shape.t2[1]) / 2;
|
||||
edgeStyle.fill = new graphic.LinearGradient(sMidX, sMidY, tMidX, tMidY, [{
|
||||
offset: 0,
|
||||
color: sourceColor
|
||||
}, {
|
||||
offset: 1,
|
||||
color: targetColor
|
||||
}], true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
|
||||
/*
|
||||
* 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 { extend, retrieve3 } from 'zrender/lib/core/util.js';
|
||||
import * as graphic from '../../util/graphic.js';
|
||||
import { getSectorCornerRadius } from '../helper/sectorHelper.js';
|
||||
import { getLabelStatesModels, setLabelStyle } from '../../label/labelStyle.js';
|
||||
import { setStatesStylesFromModel, toggleHoverEmphasis } from '../../util/states.js';
|
||||
import { getECData } from '../../util/innerStore.js';
|
||||
var ChordPiece = /** @class */function (_super) {
|
||||
__extends(ChordPiece, _super);
|
||||
function ChordPiece(data, idx, startAngle) {
|
||||
var _this = _super.call(this) || this;
|
||||
getECData(_this).dataType = 'node';
|
||||
_this.z2 = 2;
|
||||
var text = new graphic.Text();
|
||||
_this.setTextContent(text);
|
||||
_this.updateData(data, idx, startAngle, true);
|
||||
return _this;
|
||||
}
|
||||
ChordPiece.prototype.updateData = function (data, idx, startAngle, firstCreate) {
|
||||
var sector = this;
|
||||
var node = data.graph.getNodeByIndex(idx);
|
||||
var seriesModel = data.hostModel;
|
||||
var itemModel = node.getModel();
|
||||
var emphasisModel = itemModel.getModel('emphasis');
|
||||
// layout position is the center of the sector
|
||||
var layout = data.getItemLayout(idx);
|
||||
var shape = extend(getSectorCornerRadius(itemModel.getModel('itemStyle'), layout, true), layout);
|
||||
var el = this;
|
||||
// Ignore NaN data.
|
||||
if (isNaN(shape.startAngle)) {
|
||||
// Use NaN shape to avoid drawing shape.
|
||||
el.setShape(shape);
|
||||
return;
|
||||
}
|
||||
if (firstCreate) {
|
||||
el.setShape(shape);
|
||||
} else {
|
||||
graphic.updateProps(el, {
|
||||
shape: shape
|
||||
}, seriesModel, idx);
|
||||
}
|
||||
var sectorShape = extend(getSectorCornerRadius(itemModel.getModel('itemStyle'), layout, true), layout);
|
||||
sector.setShape(sectorShape);
|
||||
sector.useStyle(data.getItemVisual(idx, 'style'));
|
||||
setStatesStylesFromModel(sector, itemModel);
|
||||
this._updateLabel(seriesModel, itemModel, node);
|
||||
data.setItemGraphicEl(idx, el);
|
||||
setStatesStylesFromModel(el, itemModel, 'itemStyle');
|
||||
// Add focus/blur states handling
|
||||
var focus = emphasisModel.get('focus');
|
||||
toggleHoverEmphasis(this, focus === 'adjacency' ? node.getAdjacentDataIndices() : focus, emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
|
||||
};
|
||||
ChordPiece.prototype._updateLabel = function (seriesModel, itemModel, node) {
|
||||
var label = this.getTextContent();
|
||||
var layout = node.getLayout();
|
||||
var midAngle = (layout.startAngle + layout.endAngle) / 2;
|
||||
var dx = Math.cos(midAngle);
|
||||
var dy = Math.sin(midAngle);
|
||||
var normalLabelModel = itemModel.getModel('label');
|
||||
label.ignore = !normalLabelModel.get('show');
|
||||
// Set label style
|
||||
var labelStateModels = getLabelStatesModels(itemModel);
|
||||
var style = node.getVisual('style');
|
||||
setLabelStyle(label, labelStateModels, {
|
||||
labelFetcher: {
|
||||
getFormattedLabel: function (dataIndex, stateName, dataType, labelDimIndex, formatter, extendParams) {
|
||||
return seriesModel.getFormattedLabel(dataIndex, stateName, 'node', labelDimIndex,
|
||||
// ensure edgeLabel formatter is provided
|
||||
// to prevent the inheritance from `label.formatter` of the series
|
||||
retrieve3(formatter, labelStateModels.normal && labelStateModels.normal.get('formatter'), itemModel.get('name')), extendParams);
|
||||
}
|
||||
},
|
||||
labelDataIndex: node.dataIndex,
|
||||
defaultText: node.dataIndex + '',
|
||||
inheritColor: style.fill,
|
||||
defaultOpacity: style.opacity,
|
||||
defaultOutsidePosition: 'startArc'
|
||||
});
|
||||
// Set label position
|
||||
var labelPosition = normalLabelModel.get('position') || 'outside';
|
||||
var labelPadding = normalLabelModel.get('distance') || 0;
|
||||
var r;
|
||||
if (labelPosition === 'outside') {
|
||||
r = layout.r + labelPadding;
|
||||
} else {
|
||||
r = (layout.r + layout.r0) / 2;
|
||||
}
|
||||
this.textConfig = {
|
||||
inside: labelPosition !== 'outside'
|
||||
};
|
||||
var align = labelPosition !== 'outside' ? normalLabelModel.get('align') || 'center' : dx > 0 ? 'left' : 'right';
|
||||
var verticalAlign = labelPosition !== 'outside' ? normalLabelModel.get('verticalAlign') || 'middle' : dy > 0 ? 'top' : 'bottom';
|
||||
label.attr({
|
||||
x: dx * r + layout.cx,
|
||||
y: dy * r + layout.cy,
|
||||
rotation: 0,
|
||||
style: {
|
||||
align: align,
|
||||
verticalAlign: verticalAlign
|
||||
}
|
||||
});
|
||||
};
|
||||
return ChordPiece;
|
||||
}(graphic.Sector);
|
||||
export default ChordPiece;
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
|
||||
/*
|
||||
* 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 Model from '../../model/Model.js';
|
||||
import SeriesModel from '../../model/Series.js';
|
||||
import createGraphFromNodeEdge from '../helper/createGraphFromNodeEdge.js';
|
||||
import { createTooltipMarkup } from '../../component/tooltip/tooltipMarkup.js';
|
||||
import LegendVisualProvider from '../../visual/LegendVisualProvider.js';
|
||||
import * as zrUtil from 'zrender/lib/core/util.js';
|
||||
var ChordSeriesModel = /** @class */function (_super) {
|
||||
__extends(ChordSeriesModel, _super);
|
||||
function ChordSeriesModel() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.type = ChordSeriesModel.type;
|
||||
return _this;
|
||||
}
|
||||
ChordSeriesModel.prototype.init = function (option) {
|
||||
_super.prototype.init.apply(this, arguments);
|
||||
this.fillDataTextStyle(option.edges || option.links);
|
||||
// Enable legend selection for each data item
|
||||
this.legendVisualProvider = new LegendVisualProvider(zrUtil.bind(this.getData, this), zrUtil.bind(this.getRawData, this));
|
||||
};
|
||||
ChordSeriesModel.prototype.mergeOption = function (option) {
|
||||
_super.prototype.mergeOption.apply(this, arguments);
|
||||
this.fillDataTextStyle(option.edges || option.links);
|
||||
};
|
||||
ChordSeriesModel.prototype.getInitialData = function (option, ecModel) {
|
||||
var edges = option.edges || option.links || [];
|
||||
var nodes = option.data || option.nodes || [];
|
||||
if (nodes && edges) {
|
||||
var graph = createGraphFromNodeEdge(nodes, edges, this, true, beforeLink);
|
||||
return graph.data;
|
||||
}
|
||||
function beforeLink(nodeData, edgeData) {
|
||||
// TODO Inherit resolveParentPath by default in Model#getModel?
|
||||
var oldGetModel = Model.prototype.getModel;
|
||||
function newGetModel(path, parentModel) {
|
||||
var model = oldGetModel.call(this, path, parentModel);
|
||||
model.resolveParentPath = resolveParentPath;
|
||||
return model;
|
||||
}
|
||||
edgeData.wrapMethod('getItemModel', function (model) {
|
||||
model.resolveParentPath = resolveParentPath;
|
||||
model.getModel = newGetModel;
|
||||
return model;
|
||||
});
|
||||
function resolveParentPath(pathArr) {
|
||||
if (pathArr && (pathArr[0] === 'label' || pathArr[1] === 'label')) {
|
||||
var newPathArr = pathArr.slice();
|
||||
if (pathArr[0] === 'label') {
|
||||
newPathArr[0] = 'edgeLabel';
|
||||
} else if (pathArr[1] === 'label') {
|
||||
newPathArr[1] = 'edgeLabel';
|
||||
}
|
||||
return newPathArr;
|
||||
}
|
||||
return pathArr;
|
||||
}
|
||||
}
|
||||
};
|
||||
ChordSeriesModel.prototype.getGraph = function () {
|
||||
return this.getData().graph;
|
||||
};
|
||||
ChordSeriesModel.prototype.getEdgeData = function () {
|
||||
return this.getGraph().edgeData;
|
||||
};
|
||||
ChordSeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
|
||||
var params = this.getDataParams(dataIndex, dataType);
|
||||
if (dataType === 'edge') {
|
||||
var nodeData = this.getData();
|
||||
var edge = nodeData.graph.getEdgeByIndex(dataIndex);
|
||||
var sourceName = nodeData.getName(edge.node1.dataIndex);
|
||||
var targetName = nodeData.getName(edge.node2.dataIndex);
|
||||
var nameArr = [];
|
||||
sourceName != null && nameArr.push(sourceName);
|
||||
targetName != null && nameArr.push(targetName);
|
||||
return createTooltipMarkup('nameValue', {
|
||||
name: nameArr.join(' > '),
|
||||
value: params.value,
|
||||
noValue: params.value == null
|
||||
});
|
||||
}
|
||||
// dataType === 'node' or empty
|
||||
return createTooltipMarkup('nameValue', {
|
||||
name: params.name,
|
||||
value: params.value,
|
||||
noValue: params.value == null
|
||||
});
|
||||
};
|
||||
ChordSeriesModel.prototype.getDataParams = function (dataIndex, dataType) {
|
||||
var params = _super.prototype.getDataParams.call(this, dataIndex, dataType);
|
||||
if (dataType === 'node') {
|
||||
var nodeData = this.getData();
|
||||
var node = this.getGraph().getNodeByIndex(dataIndex);
|
||||
// Set name if not already set
|
||||
if (params.name == null) {
|
||||
params.name = nodeData.getName(dataIndex);
|
||||
}
|
||||
// Set value if not already set
|
||||
if (params.value == null) {
|
||||
var nodeValue = node.getLayout().value;
|
||||
params.value = nodeValue;
|
||||
}
|
||||
}
|
||||
return params;
|
||||
};
|
||||
ChordSeriesModel.type = 'series.chord';
|
||||
ChordSeriesModel.defaultOption = {
|
||||
// zlevel: 0,
|
||||
z: 2,
|
||||
coordinateSystem: 'none',
|
||||
legendHoverLink: true,
|
||||
colorBy: 'data',
|
||||
left: 0,
|
||||
top: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
width: null,
|
||||
height: null,
|
||||
center: ['50%', '50%'],
|
||||
radius: ['70%', '80%'],
|
||||
clockwise: true,
|
||||
startAngle: 90,
|
||||
endAngle: 'auto',
|
||||
minAngle: 0,
|
||||
padAngle: 3,
|
||||
itemStyle: {
|
||||
borderRadius: [0, 0, 5, 5]
|
||||
},
|
||||
lineStyle: {
|
||||
width: 0,
|
||||
color: 'source',
|
||||
opacity: 0.2
|
||||
},
|
||||
label: {
|
||||
show: true,
|
||||
position: 'outside',
|
||||
distance: 5
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'adjacency',
|
||||
lineStyle: {
|
||||
opacity: 0.5
|
||||
}
|
||||
}
|
||||
};
|
||||
return ChordSeriesModel;
|
||||
}(SeriesModel);
|
||||
export default ChordSeriesModel;
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
|
||||
/*
|
||||
* 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 graphic from '../../util/graphic.js';
|
||||
import ChartView from '../../view/Chart.js';
|
||||
import ChordPiece from './ChordPiece.js';
|
||||
import { ChordEdge } from './ChordEdge.js';
|
||||
import { parsePercent } from '../../util/number.js';
|
||||
import { getECData } from '../../util/innerStore.js';
|
||||
var RADIAN = Math.PI / 180;
|
||||
var ChordView = /** @class */function (_super) {
|
||||
__extends(ChordView, _super);
|
||||
function ChordView() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.type = ChordView.type;
|
||||
return _this;
|
||||
}
|
||||
ChordView.prototype.init = function (ecModel, api) {};
|
||||
ChordView.prototype.render = function (seriesModel, ecModel, api) {
|
||||
var data = seriesModel.getData();
|
||||
var oldData = this._data;
|
||||
var group = this.group;
|
||||
var startAngle = -seriesModel.get('startAngle') * RADIAN;
|
||||
data.diff(oldData).add(function (newIdx) {
|
||||
/* Consider the case when there are only two nodes A and B,
|
||||
* and there is a link between A and B.
|
||||
* At first, they are both disselected from legend. And then
|
||||
* when A is selected, A will go into `add` method. But since
|
||||
* there are no edges to be displayed, A should not be added.
|
||||
* So we should only add A when layout is defined.
|
||||
*/
|
||||
var layout = data.getItemLayout(newIdx);
|
||||
if (layout) {
|
||||
var el = new ChordPiece(data, newIdx, startAngle);
|
||||
getECData(el).dataIndex = newIdx;
|
||||
group.add(el);
|
||||
}
|
||||
}).update(function (newIdx, oldIdx) {
|
||||
var el = oldData.getItemGraphicEl(oldIdx);
|
||||
var layout = data.getItemLayout(newIdx);
|
||||
/* Consider the case when there are only two nodes A and B,
|
||||
* and there is a link between A and B.
|
||||
* and when A is disselected from legend, there should be
|
||||
* nothing to display. But in the `data.diff` method, B will go
|
||||
* into `update` method and having no layout.
|
||||
* In this case, we need to remove B.
|
||||
*/
|
||||
if (!layout) {
|
||||
el && graphic.removeElementWithFadeOut(el, seriesModel, oldIdx);
|
||||
return;
|
||||
}
|
||||
if (!el) {
|
||||
el = new ChordPiece(data, newIdx, startAngle);
|
||||
} else {
|
||||
el.updateData(data, newIdx, startAngle);
|
||||
}
|
||||
group.add(el);
|
||||
}).remove(function (oldIdx) {
|
||||
var el = oldData.getItemGraphicEl(oldIdx);
|
||||
el && graphic.removeElementWithFadeOut(el, seriesModel, oldIdx);
|
||||
}).execute();
|
||||
if (!oldData) {
|
||||
var center = seriesModel.get('center');
|
||||
this.group.scaleX = 0.01;
|
||||
this.group.scaleY = 0.01;
|
||||
this.group.originX = parsePercent(center[0], api.getWidth());
|
||||
this.group.originY = parsePercent(center[1], api.getHeight());
|
||||
graphic.initProps(this.group, {
|
||||
scaleX: 1,
|
||||
scaleY: 1
|
||||
}, seriesModel);
|
||||
}
|
||||
this._data = data;
|
||||
this.renderEdges(seriesModel, startAngle);
|
||||
};
|
||||
ChordView.prototype.renderEdges = function (seriesModel, startAngle) {
|
||||
var nodeData = seriesModel.getData();
|
||||
var edgeData = seriesModel.getEdgeData();
|
||||
var oldData = this._edgeData;
|
||||
var group = this.group;
|
||||
edgeData.diff(oldData).add(function (newIdx) {
|
||||
var el = new ChordEdge(nodeData, edgeData, newIdx, startAngle);
|
||||
getECData(el).dataIndex = newIdx;
|
||||
group.add(el);
|
||||
}).update(function (newIdx, oldIdx) {
|
||||
var el = oldData.getItemGraphicEl(oldIdx);
|
||||
el.updateData(nodeData, edgeData, newIdx, startAngle);
|
||||
group.add(el);
|
||||
}).remove(function (oldIdx) {
|
||||
var el = oldData.getItemGraphicEl(oldIdx);
|
||||
el && graphic.removeElementWithFadeOut(el, seriesModel, oldIdx);
|
||||
}).execute();
|
||||
this._edgeData = edgeData;
|
||||
};
|
||||
ChordView.prototype.dispose = function () {};
|
||||
ChordView.type = 'chord';
|
||||
return ChordView;
|
||||
}(ChartView);
|
||||
export default ChordView;
|
||||
+247
@@ -0,0 +1,247 @@
|
||||
|
||||
/*
|
||||
* 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 { normalizeArcAngles } from 'zrender/lib/core/PathProxy.js';
|
||||
import { getCircleLayout } from '../../util/layout.js';
|
||||
var RADIAN = Math.PI / 180;
|
||||
export default function chordCircularLayout(ecModel, api) {
|
||||
ecModel.eachSeriesByType('chord', function (seriesModel) {
|
||||
chordLayout(seriesModel, api);
|
||||
});
|
||||
}
|
||||
function chordLayout(seriesModel, api) {
|
||||
var nodeData = seriesModel.getData();
|
||||
var nodeGraph = nodeData.graph;
|
||||
var edgeData = seriesModel.getEdgeData();
|
||||
var edgeCount = edgeData.count();
|
||||
if (!edgeCount) {
|
||||
return;
|
||||
}
|
||||
var _a = getCircleLayout(seriesModel, api),
|
||||
cx = _a.cx,
|
||||
cy = _a.cy,
|
||||
r = _a.r,
|
||||
r0 = _a.r0;
|
||||
var padAngle = Math.max((seriesModel.get('padAngle') || 0) * RADIAN, 0);
|
||||
var minAngle = Math.max((seriesModel.get('minAngle') || 0) * RADIAN, 0);
|
||||
var startAngle = -seriesModel.get('startAngle') * RADIAN;
|
||||
var endAngle = startAngle + Math.PI * 2;
|
||||
var clockwise = seriesModel.get('clockwise');
|
||||
var dir = clockwise ? 1 : -1;
|
||||
// Normalize angles
|
||||
var angles = [startAngle, endAngle];
|
||||
normalizeArcAngles(angles, !clockwise);
|
||||
var normalizedStartAngle = angles[0],
|
||||
normalizedEndAngle = angles[1];
|
||||
var totalAngle = normalizedEndAngle - normalizedStartAngle;
|
||||
var allZero = nodeData.getSum('value') === 0 && edgeData.getSum('value') === 0;
|
||||
// Sum of each node's edge values
|
||||
var nodeValues = [];
|
||||
var renderedNodeCount = 0;
|
||||
nodeGraph.eachEdge(function (edge) {
|
||||
// All links use the same value 1 when allZero is true
|
||||
var value = allZero ? 1 : edge.getValue('value');
|
||||
if (allZero && (value > 0 || minAngle)) {
|
||||
// When allZero is true, angle is in direct proportion to number
|
||||
// of links both in and out of the node.
|
||||
renderedNodeCount += 2;
|
||||
}
|
||||
var node1Index = edge.node1.dataIndex;
|
||||
var node2Index = edge.node2.dataIndex;
|
||||
nodeValues[node1Index] = (nodeValues[node1Index] || 0) + value;
|
||||
nodeValues[node2Index] = (nodeValues[node2Index] || 0) + value;
|
||||
});
|
||||
// Update nodeValues with data.value if exists
|
||||
var nodeValueSum = 0;
|
||||
nodeGraph.eachNode(function (node) {
|
||||
var dataValue = node.getValue('value');
|
||||
if (!isNaN(dataValue)) {
|
||||
nodeValues[node.dataIndex] = Math.max(dataValue, nodeValues[node.dataIndex] || 0);
|
||||
}
|
||||
if (!allZero && (nodeValues[node.dataIndex] > 0 || minAngle)) {
|
||||
// When allZero is false, angle is in direct proportion to node's
|
||||
// value
|
||||
renderedNodeCount++;
|
||||
}
|
||||
nodeValueSum += nodeValues[node.dataIndex] || 0;
|
||||
});
|
||||
if (renderedNodeCount === 0 || nodeValueSum === 0) {
|
||||
return;
|
||||
}
|
||||
if (padAngle * renderedNodeCount >= Math.abs(totalAngle)) {
|
||||
// Not enough angle to render the pad, minAngle has higher priority, and padAngle takes the rest
|
||||
padAngle = Math.max(0, (Math.abs(totalAngle) - minAngle * renderedNodeCount) / renderedNodeCount);
|
||||
}
|
||||
if ((padAngle + minAngle) * renderedNodeCount >= Math.abs(totalAngle)) {
|
||||
// Not enough angle to render the minAngle, so ignore the minAngle
|
||||
minAngle = (Math.abs(totalAngle) - padAngle * renderedNodeCount) / renderedNodeCount;
|
||||
}
|
||||
var unitAngle = (totalAngle - padAngle * renderedNodeCount * dir) / nodeValueSum;
|
||||
var totalDeficit = 0; // sum of deficits of nodes with span < minAngle
|
||||
var totalSurplus = 0; // sum of (spans - minAngle) of nodes with span > minAngle
|
||||
var totalSurplusSpan = 0; // sum of spans of nodes with span > minAngle
|
||||
var minSurplus = Infinity; // min of (spans - minAngle) of nodes with span > minAngle
|
||||
nodeGraph.eachNode(function (node) {
|
||||
var value = nodeValues[node.dataIndex] || 0;
|
||||
var spanAngle = unitAngle * (nodeValueSum ? value : 1) * dir;
|
||||
if (Math.abs(spanAngle) < minAngle) {
|
||||
totalDeficit += minAngle - Math.abs(spanAngle);
|
||||
} else {
|
||||
minSurplus = Math.min(minSurplus, Math.abs(spanAngle) - minAngle);
|
||||
totalSurplus += Math.abs(spanAngle) - minAngle;
|
||||
totalSurplusSpan += Math.abs(spanAngle);
|
||||
}
|
||||
node.setLayout({
|
||||
angle: spanAngle,
|
||||
value: value
|
||||
});
|
||||
});
|
||||
var surplusAsMuchAsPossible = false;
|
||||
if (totalDeficit > totalSurplus) {
|
||||
// Not enough angle to spread the nodes, scale all
|
||||
var scale_1 = totalDeficit / totalSurplus;
|
||||
nodeGraph.eachNode(function (node) {
|
||||
var spanAngle = node.getLayout().angle;
|
||||
if (Math.abs(spanAngle) >= minAngle) {
|
||||
node.setLayout({
|
||||
angle: spanAngle * scale_1,
|
||||
ratio: scale_1
|
||||
}, true);
|
||||
} else {
|
||||
node.setLayout({
|
||||
angle: minAngle,
|
||||
ratio: minAngle === 0 ? 1 : spanAngle / minAngle
|
||||
}, true);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// For example, if totalDeficit is 60 degrees and totalSurplus is 70
|
||||
// degrees but one of the sector can only reduced by 1 degree,
|
||||
// if we decrease it with the ratio of value to other surplused nodes,
|
||||
// it will have smaller angle than minAngle itself.
|
||||
// So we need to borrow some angle from other nodes.
|
||||
nodeGraph.eachNode(function (node) {
|
||||
if (surplusAsMuchAsPossible) {
|
||||
return;
|
||||
}
|
||||
var spanAngle = node.getLayout().angle;
|
||||
var borrowRatio = Math.min(spanAngle / totalSurplusSpan, 1);
|
||||
var borrowAngle = borrowRatio * totalDeficit;
|
||||
if (spanAngle - borrowAngle < minAngle) {
|
||||
// It will have less than minAngle after borrowing
|
||||
surplusAsMuchAsPossible = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
var restDeficit = totalDeficit;
|
||||
nodeGraph.eachNode(function (node) {
|
||||
if (restDeficit <= 0) {
|
||||
return;
|
||||
}
|
||||
var spanAngle = node.getLayout().angle;
|
||||
if (spanAngle > minAngle && minAngle > 0) {
|
||||
var borrowRatio = surplusAsMuchAsPossible ? 1 : Math.min(spanAngle / totalSurplusSpan, 1);
|
||||
var maxBorrowAngle = spanAngle - minAngle;
|
||||
var borrowAngle = Math.min(maxBorrowAngle, Math.min(restDeficit, totalDeficit * borrowRatio));
|
||||
restDeficit -= borrowAngle;
|
||||
node.setLayout({
|
||||
angle: spanAngle - borrowAngle,
|
||||
ratio: (spanAngle - borrowAngle) / spanAngle
|
||||
}, true);
|
||||
} else if (minAngle > 0) {
|
||||
node.setLayout({
|
||||
angle: minAngle,
|
||||
ratio: spanAngle === 0 ? 1 : minAngle / spanAngle
|
||||
}, true);
|
||||
}
|
||||
});
|
||||
var angle = normalizedStartAngle;
|
||||
var edgeAccAngle = [];
|
||||
nodeGraph.eachNode(function (node) {
|
||||
var spanAngle = Math.max(node.getLayout().angle, minAngle);
|
||||
node.setLayout({
|
||||
cx: cx,
|
||||
cy: cy,
|
||||
r0: r0,
|
||||
r: r,
|
||||
startAngle: angle,
|
||||
endAngle: angle + spanAngle * dir,
|
||||
clockwise: clockwise
|
||||
}, true);
|
||||
edgeAccAngle[node.dataIndex] = angle;
|
||||
angle += (spanAngle + padAngle) * dir;
|
||||
});
|
||||
nodeGraph.eachEdge(function (edge) {
|
||||
var value = allZero ? 1 : edge.getValue('value');
|
||||
var spanAngle = unitAngle * (nodeValueSum ? value : 1) * dir;
|
||||
var node1Index = edge.node1.dataIndex;
|
||||
var sStartAngle = edgeAccAngle[node1Index] || 0;
|
||||
var sSpan = Math.abs((edge.node1.getLayout().ratio || 1) * spanAngle);
|
||||
var sEndAngle = sStartAngle + sSpan * dir;
|
||||
var s1 = [cx + r0 * Math.cos(sStartAngle), cy + r0 * Math.sin(sStartAngle)];
|
||||
var s2 = [cx + r0 * Math.cos(sEndAngle), cy + r0 * Math.sin(sEndAngle)];
|
||||
var node2Index = edge.node2.dataIndex;
|
||||
var tStartAngle = edgeAccAngle[node2Index] || 0;
|
||||
var tSpan = Math.abs((edge.node2.getLayout().ratio || 1) * spanAngle);
|
||||
var tEndAngle = tStartAngle + tSpan * dir;
|
||||
var t1 = [cx + r0 * Math.cos(tStartAngle), cy + r0 * Math.sin(tStartAngle)];
|
||||
var t2 = [cx + r0 * Math.cos(tEndAngle), cy + r0 * Math.sin(tEndAngle)];
|
||||
edge.setLayout({
|
||||
s1: s1,
|
||||
s2: s2,
|
||||
sStartAngle: sStartAngle,
|
||||
sEndAngle: sEndAngle,
|
||||
t1: t1,
|
||||
t2: t2,
|
||||
tStartAngle: tStartAngle,
|
||||
tEndAngle: tEndAngle,
|
||||
cx: cx,
|
||||
cy: cy,
|
||||
r: r0,
|
||||
value: value,
|
||||
clockwise: clockwise
|
||||
});
|
||||
edgeAccAngle[node1Index] = sEndAngle;
|
||||
edgeAccAngle[node2Index] = tEndAngle;
|
||||
});
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
|
||||
/*
|
||||
* 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 ChordView from './ChordView.js';
|
||||
import ChordSeriesModel from './ChordSeries.js';
|
||||
import chordLayout from './chordLayout.js';
|
||||
import dataFilter from '../../processor/dataFilter.js';
|
||||
export function install(registers) {
|
||||
registers.registerChartView(ChordView);
|
||||
registers.registerSeriesModel(ChordSeriesModel);
|
||||
registers.registerLayout(registers.PRIORITY.VISUAL.POST_CHART_LAYOUT, chordLayout);
|
||||
// Add data filter processor
|
||||
registers.registerProcessor(dataFilter('chord'));
|
||||
}
|
||||
Reference in New Issue
Block a user