|  | /* | 
|  | * 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 {prepareDataCoordInfo, getStackedOnPoint} from './helper'; | 
|  | import SeriesData from '../../data/SeriesData'; | 
|  | import type Cartesian2D from '../../coord/cartesian/Cartesian2D'; | 
|  | import type Polar from '../../coord/polar/Polar'; | 
|  | import { LineSeriesOption } from './LineSeries'; | 
|  | import { createFloat32Array } from '../../util/vendor'; | 
|  |  | 
|  | interface DiffItem { | 
|  | cmd: '+' | '=' | '-' | 
|  | idx: number | 
|  | idx1?: number | 
|  | } | 
|  |  | 
|  | function diffData(oldData: SeriesData, newData: SeriesData) { | 
|  | const diffResult: DiffItem[] = []; | 
|  |  | 
|  | newData.diff(oldData) | 
|  | .add(function (idx) { | 
|  | diffResult.push({cmd: '+', idx: idx}); | 
|  | }) | 
|  | .update(function (newIdx, oldIdx) { | 
|  | diffResult.push({cmd: '=', idx: oldIdx, idx1: newIdx}); | 
|  | }) | 
|  | .remove(function (idx) { | 
|  | diffResult.push({cmd: '-', idx: idx}); | 
|  | }) | 
|  | .execute(); | 
|  |  | 
|  | return diffResult; | 
|  | } | 
|  |  | 
|  | export default function lineAnimationDiff( | 
|  | oldData: SeriesData, newData: SeriesData, | 
|  | oldStackedOnPoints: ArrayLike<number>, newStackedOnPoints: ArrayLike<number>, | 
|  | oldCoordSys: Cartesian2D | Polar, newCoordSys: Cartesian2D | Polar, | 
|  | oldValueOrigin: LineSeriesOption['areaStyle']['origin'], | 
|  | newValueOrigin: LineSeriesOption['areaStyle']['origin'] | 
|  | ) { | 
|  | const diff = diffData(oldData, newData); | 
|  |  | 
|  | // let newIdList = newData.mapArray(newData.getId); | 
|  | // let oldIdList = oldData.mapArray(oldData.getId); | 
|  |  | 
|  | // convertToIntId(newIdList, oldIdList); | 
|  |  | 
|  | // // FIXME One data ? | 
|  | // diff = arrayDiff(oldIdList, newIdList); | 
|  |  | 
|  | const currPoints: number[] = []; | 
|  | const nextPoints: number[] = []; | 
|  | // Points for stacking base line | 
|  | const currStackedPoints: number[] = []; | 
|  | const nextStackedPoints: number[] = []; | 
|  |  | 
|  | const status = []; | 
|  | const sortedIndices: number[] = []; | 
|  | const rawIndices: number[] = []; | 
|  |  | 
|  | const newDataOldCoordInfo = prepareDataCoordInfo(oldCoordSys, newData, oldValueOrigin); | 
|  | // const oldDataNewCoordInfo = prepareDataCoordInfo(newCoordSys, oldData, newValueOrigin); | 
|  |  | 
|  | const oldPoints = oldData.getLayout('points') as number[] || []; | 
|  | const newPoints = newData.getLayout('points') as number[] || []; | 
|  |  | 
|  | for (let i = 0; i < diff.length; i++) { | 
|  | const diffItem = diff[i]; | 
|  | let pointAdded = true; | 
|  |  | 
|  | let oldIdx2: number; | 
|  | let newIdx2: number; | 
|  |  | 
|  | // FIXME, animation is not so perfect when dataZoom window moves fast | 
|  | // Which is in case remvoing or add more than one data in the tail or head | 
|  | switch (diffItem.cmd) { | 
|  | case '=': | 
|  | oldIdx2 = diffItem.idx * 2; | 
|  | newIdx2 = diffItem.idx1 * 2; | 
|  | let currentX = oldPoints[oldIdx2]; | 
|  | let currentY = oldPoints[oldIdx2 + 1]; | 
|  | const nextX = newPoints[newIdx2]; | 
|  | const nextY = newPoints[newIdx2 + 1]; | 
|  |  | 
|  | // If previous data is NaN, use next point directly | 
|  | if (isNaN(currentX) || isNaN(currentY)) { | 
|  | currentX = nextX; | 
|  | currentY = nextY; | 
|  | } | 
|  | currPoints.push(currentX, currentY); | 
|  | nextPoints.push(nextX, nextY); | 
|  |  | 
|  | currStackedPoints.push(oldStackedOnPoints[oldIdx2], oldStackedOnPoints[oldIdx2 + 1]); | 
|  | nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]); | 
|  |  | 
|  | rawIndices.push(newData.getRawIndex(diffItem.idx1)); | 
|  | break; | 
|  | case '+': | 
|  | const newIdx = diffItem.idx; | 
|  | const newDataDimsForPoint = newDataOldCoordInfo.dataDimsForPoint; | 
|  | const oldPt = oldCoordSys.dataToPoint([ | 
|  | newData.get(newDataDimsForPoint[0], newIdx), | 
|  | newData.get(newDataDimsForPoint[1], newIdx) | 
|  | ]); | 
|  | newIdx2 = newIdx * 2; | 
|  | currPoints.push(oldPt[0], oldPt[1]); | 
|  |  | 
|  | nextPoints.push(newPoints[newIdx2], newPoints[newIdx2 + 1]); | 
|  |  | 
|  | const stackedOnPoint = getStackedOnPoint(newDataOldCoordInfo, oldCoordSys, newData, newIdx); | 
|  |  | 
|  | currStackedPoints.push(stackedOnPoint[0], stackedOnPoint[1]); | 
|  | nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]); | 
|  |  | 
|  | rawIndices.push(newData.getRawIndex(newIdx)); | 
|  | break; | 
|  | case '-': | 
|  | pointAdded = false; | 
|  | } | 
|  |  | 
|  | // Original indices | 
|  | if (pointAdded) { | 
|  | status.push(diffItem); | 
|  | sortedIndices.push(sortedIndices.length); | 
|  | } | 
|  | } | 
|  |  | 
|  | // Diff result may be crossed if all items are changed | 
|  | // Sort by data index | 
|  | sortedIndices.sort(function (a, b) { | 
|  | return rawIndices[a] - rawIndices[b]; | 
|  | }); | 
|  |  | 
|  | const len = currPoints.length; | 
|  | const sortedCurrPoints = createFloat32Array(len); | 
|  | const sortedNextPoints = createFloat32Array(len); | 
|  |  | 
|  | const sortedCurrStackedPoints = createFloat32Array(len); | 
|  | const sortedNextStackedPoints = createFloat32Array(len); | 
|  |  | 
|  | const sortedStatus = []; | 
|  | for (let i = 0; i < sortedIndices.length; i++) { | 
|  | const idx = sortedIndices[i]; | 
|  | const i2 = i * 2; | 
|  | const idx2 = idx * 2; | 
|  | sortedCurrPoints[i2] = currPoints[idx2]; | 
|  | sortedCurrPoints[i2 + 1] = currPoints[idx2 + 1]; | 
|  | sortedNextPoints[i2] = nextPoints[idx2]; | 
|  | sortedNextPoints[i2 + 1] = nextPoints[idx2 + 1]; | 
|  |  | 
|  | sortedCurrStackedPoints[i2] = currStackedPoints[idx2]; | 
|  | sortedCurrStackedPoints[i2 + 1] = currStackedPoints[idx2 + 1]; | 
|  | sortedNextStackedPoints[i2] = nextStackedPoints[idx2]; | 
|  | sortedNextStackedPoints[i2 + 1] = nextStackedPoints[idx2 + 1]; | 
|  |  | 
|  | sortedStatus[i] = status[idx]; | 
|  | } | 
|  |  | 
|  | return { | 
|  | current: sortedCurrPoints, | 
|  | next: sortedNextPoints, | 
|  |  | 
|  | stackedOnCurrent: sortedCurrStackedPoints, | 
|  | stackedOnNext: sortedNextStackedPoints, | 
|  |  | 
|  | status: sortedStatus | 
|  | }; | 
|  | } |