| /* |
| * 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. |
| */ |
| |
| // @ts-nocheck |
| import * as zrUtil from 'zrender/src/core/util'; |
| |
| const KEY_DELIMITER = '-->'; |
| /** |
| * params handler |
| * @param {module:echarts/model/SeriesModel} seriesModel |
| * @returns {*} |
| */ |
| const getAutoCurvenessParams = function (seriesModel) { |
| return seriesModel.get('autoCurveness') || null; |
| }; |
| |
| /** |
| * Generate a list of edge curvatures, 20 is the default |
| * @param {module:echarts/model/SeriesModel} seriesModel |
| * @param {number} appendLength |
| * @return 20 => [0, -0.2, 0.2, -0.4, 0.4, -0.6, 0.6, -0.8, 0.8, -1, 1, -1.2, 1.2, -1.4, 1.4, -1.6, 1.6, -1.8, 1.8, -2] |
| */ |
| const createCurveness = function (seriesModel, appendLength) { |
| const autoCurvenessParmas = getAutoCurvenessParams(seriesModel); |
| let length = 20; |
| let curvenessList = []; |
| |
| // handler the function set |
| if (typeof autoCurvenessParmas === 'number') { |
| length = autoCurvenessParmas; |
| } |
| else if (zrUtil.isArray(autoCurvenessParmas)) { |
| seriesModel.__curvenessList = autoCurvenessParmas; |
| return; |
| } |
| |
| // append length |
| if (appendLength > length) { |
| length = appendLength; |
| } |
| |
| // make sure the length is even |
| const len = length % 2 ? length + 2 : length + 3; |
| curvenessList = []; |
| |
| for (let i = 0; i < len; i++) { |
| curvenessList.push((i % 2 ? i + 1 : i) / 10 * (i % 2 ? -1 : 1)); |
| } |
| seriesModel.__curvenessList = curvenessList; |
| }; |
| |
| /** |
| * Create different cache key data in the positive and negative directions, in order to set the curvature later |
| * @param {number|string|module:echarts/data/Graph.Node} n1 |
| * @param {number|string|module:echarts/data/Graph.Node} n2 |
| * @param {module:echarts/model/SeriesModel} seriesModel |
| * @returns {string} key |
| */ |
| const getKeyOfEdges = function (n1, n2, seriesModel) { |
| const source = [n1.id, n1.dataIndex].join('.'); |
| const target = [n2.id, n2.dataIndex].join('.'); |
| return [seriesModel.uid, source, target].join(KEY_DELIMITER); |
| }; |
| |
| /** |
| * get opposite key |
| * @param {string} key |
| * @returns {string} |
| */ |
| const getOppositeKey = function (key) { |
| const keys = key.split(KEY_DELIMITER); |
| return [keys[0], keys[2], keys[1]].join(KEY_DELIMITER); |
| }; |
| |
| /** |
| * get edgeMap with key |
| * @param edge |
| * @param {module:echarts/model/SeriesModel} seriesModel |
| */ |
| const getEdgeFromMap = function (edge, seriesModel) { |
| const key = getKeyOfEdges(edge.node1, edge.node2, seriesModel); |
| return seriesModel.__edgeMap[key]; |
| }; |
| |
| /** |
| * calculate all cases total length |
| * @param edge |
| * @param seriesModel |
| * @returns {number} |
| */ |
| const getTotalLengthBetweenNodes = function (edge, seriesModel) { |
| const len = getEdgeMapLengthWithKey(getKeyOfEdges(edge.node1, edge.node2, seriesModel), seriesModel); |
| const lenV = getEdgeMapLengthWithKey(getKeyOfEdges(edge.node2, edge.node1, seriesModel), seriesModel); |
| |
| return len + lenV; |
| }; |
| |
| /** |
| * |
| * @param key |
| */ |
| const getEdgeMapLengthWithKey = function (key, seriesModel) { |
| const edgeMap = seriesModel.__edgeMap; |
| return edgeMap[key] ? edgeMap[key].length : 0; |
| }; |
| /** |
| * |
| * @param edge |
| */ |
| const isLoopEdge = function (edge) { |
| return edge.node1 === edge.node2; |
| }; |
| |
| /** |
| * Count the number of edges between the same two points, used to obtain the curvature table and the parity of the edge |
| * @see /graph/GraphSeries.js@getInitialData |
| * @param {module:echarts/model/SeriesModel} seriesModel |
| */ |
| export function initCurvenessList(seriesModel) { |
| if (!getAutoCurvenessParams(seriesModel)) { |
| return; |
| } |
| |
| seriesModel.__curvenessList = []; |
| seriesModel.__edgeMap = {}; |
| // calc the array of curveness List |
| createCurveness(seriesModel); |
| } |
| |
| /** |
| * set edgeMap with key |
| * @param {number|string|module:echarts/data/Graph.Node} n1 |
| * @param {number|string|module:echarts/data/Graph.Node} n2 |
| * @param {module:echarts/model/SeriesModel} seriesModel |
| * @param {number} index |
| */ |
| export function createEdgeMapForCurveness(n1, n2, seriesModel, index) { |
| if (!getAutoCurvenessParams(seriesModel)) { |
| return; |
| } |
| |
| const key = getKeyOfEdges(n1, n2, seriesModel); |
| const edgeMap = seriesModel.__edgeMap; |
| const oppositeEdges = edgeMap[getOppositeKey(key)]; |
| // set direction |
| if (edgeMap[key] && !oppositeEdges) { |
| edgeMap[key].isForward = true; |
| } |
| else if (oppositeEdges && edgeMap[key]) { |
| oppositeEdges.isForward = true; |
| edgeMap[key].isForward = false; |
| } |
| |
| edgeMap[key] = edgeMap[key] || []; |
| edgeMap[key].push(index); |
| } |
| |
| /** |
| * get curvature for edge |
| * @param edge |
| * @param {module:echarts/model/SeriesModel} seriesModel |
| * @param index |
| */ |
| export function getCurvenessForEdge(edge, seriesModel, index, needReverse?: boolean) { |
| const autoCurvenessParams = getAutoCurvenessParams(seriesModel); |
| const isArrayParam = zrUtil.isArray(autoCurvenessParams); |
| if (!autoCurvenessParams) { |
| return null; |
| } |
| |
| const edgeArray = getEdgeFromMap(edge, seriesModel); |
| if (!edgeArray) { |
| return null; |
| } |
| |
| let edgeIndex = -1; |
| for (let i = 0; i < edgeArray.length; i++) { |
| if (edgeArray[i] === index) { |
| edgeIndex = i; |
| break; |
| } |
| } |
| // if totalLen is Longer createCurveness |
| const totalLen = getTotalLengthBetweenNodes(edge, seriesModel); |
| createCurveness(seriesModel, totalLen); |
| |
| edge.lineStyle = edge.lineStyle || {}; |
| // if is opposite edge, must set curvenss to opposite number |
| const curKey = getKeyOfEdges(edge.node1, edge.node2, seriesModel); |
| const curvenessList = seriesModel.__curvenessList; |
| // if pass array no need parity |
| const parityCorrection = isArrayParam ? 0 : totalLen % 2 ? 0 : 1; |
| if (isLoopEdge(edge)) { |
| // PENDING: this strategy is not applicable in self-loop edges yet. |
| const curveness = zrUtil.filter(curvenessList, num => num > 0); |
| return curveness[edgeIndex]; |
| } |
| else if (!edgeArray.isForward) { |
| // the opposite edge show outside |
| const oppositeKey = getOppositeKey(curKey); |
| const len = getEdgeMapLengthWithKey(oppositeKey, seriesModel); |
| const resValue = curvenessList[edgeIndex + len + parityCorrection]; |
| // isNeedReverse, simple, force type need reverse the curveness in the junction of the forword and the opposite |
| if (needReverse) { |
| // set as array may make the parity handle with the len of opposite |
| if (isArrayParam) { |
| if (autoCurvenessParams && autoCurvenessParams[0] === 0) { |
| return (len + parityCorrection) % 2 ? resValue : -resValue; |
| } |
| else { |
| return ((len % 2 ? 0 : 1) + parityCorrection) % 2 ? resValue : -resValue; |
| } |
| } |
| else { |
| return (len + parityCorrection) % 2 ? resValue : -resValue; |
| } |
| } |
| else { |
| return curvenessList[edgeIndex + len + parityCorrection]; |
| } |
| } |
| else { |
| return curvenessList[parityCorrection + edgeIndex]; |
| } |
| } |