| /* | |
| * 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 (zrUtil.isNumber(autoCurvenessParmas)) { | |
| 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; | |
| }; | |
| /** | |
| * 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 (!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]; | |
| } | |
| } |