define(function (require) {
// var arrayDiff = require('zrender/core/arrayDiff');
// 'zrender/core/arrayDiff' has been used before, but it did
// not do well in performance when roam with fixed dataZoom window.
function sign(val) {
return val >= 0 ? 1 : -1;
}
function getStackedOnPoint(coordSys, data, idx) {
var baseAxis = coordSys.getBaseAxis();
var valueAxis = coordSys.getOtherAxis(baseAxis);
var valueStart = baseAxis.onZero
? 0 : valueAxis.scale.getExtent()[0];
var valueDim = valueAxis.dim;
var baseDataOffset = valueDim === 'x' || valueDim === 'radius' ? 1 : 0;
var stackedOnSameSign;
var stackedOn = data.stackedOn;
var val = data.get(valueDim, idx);
// Find first stacked value with same sign
while (stackedOn &&
sign(stackedOn.get(valueDim, idx)) === sign(val)
) {
stackedOnSameSign = stackedOn;
break;
}
var stackedData = [];
stackedData[baseDataOffset] = data.get(baseAxis.dim, idx);
stackedData[1 - baseDataOffset] = stackedOnSameSign
? stackedOnSameSign.get(valueDim, idx, true) : valueStart;
return coordSys.dataToPoint(stackedData);
}
// function convertToIntId(newIdList, oldIdList) {
// // Generate int id instead of string id.
// // Compare string maybe slow in score function of arrDiff
// // Assume id in idList are all unique
// var idIndicesMap = {};
// var idx = 0;
// for (var i = 0; i < newIdList.length; i++) {
// idIndicesMap[newIdList[i]] = idx;
// newIdList[i] = idx++;
// }
// for (var i = 0; i < oldIdList.length; i++) {
// var oldId = oldIdList[i];
// // Same with newIdList
// if (idIndicesMap[oldId]) {
// oldIdList[i] = idIndicesMap[oldId];
// }
// else {
// oldIdList[i] = idx++;
// }
// }
// }
function diffData(oldData, newData) {
var diffResult = [];
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;
}
return function (
oldData, newData,
oldStackedOnPoints, newStackedOnPoints,
oldCoordSys, newCoordSys
) {
var diff = diffData(oldData, newData);
// var newIdList = newData.mapArray(newData.getId);
// var oldIdList = oldData.mapArray(oldData.getId);
// convertToIntId(newIdList, oldIdList);
// // FIXME One data ?
// diff = arrayDiff(oldIdList, newIdList);
var currPoints = [];
var nextPoints = [];
// Points for stacking base line
var currStackedPoints = [];
var nextStackedPoints = [];
var status = [];
var sortedIndices = [];
var rawIndices = [];
var dims = newCoordSys.dimensions;
for (var i = 0; i < diff.length; i++) {
var diffItem = diff[i];
var pointAdded = true;
// 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 '=':
var currentPt = oldData.getItemLayout(diffItem.idx);
var nextPt = newData.getItemLayout(diffItem.idx1);
// If previous data is NaN, use next point directly
if (isNaN(currentPt[0]) || isNaN(currentPt[1])) {
currentPt = nextPt.slice();
}
currPoints.push(currentPt);
nextPoints.push(nextPt);
currStackedPoints.push(oldStackedOnPoints[diffItem.idx]);
nextStackedPoints.push(newStackedOnPoints[diffItem.idx1]);
rawIndices.push(newData.getRawIndex(diffItem.idx1));
break;
case '+':
var idx = diffItem.idx;
currPoints.push(
oldCoordSys.dataToPoint([
newData.get(dims[0], idx, true), newData.get(dims[1], idx, true)
])
);
nextPoints.push(newData.getItemLayout(idx).slice());
currStackedPoints.push(
getStackedOnPoint(oldCoordSys, newData, idx)
);
nextStackedPoints.push(newStackedOnPoints[idx]);
rawIndices.push(newData.getRawIndex(idx));
break;
case '-':
var idx = diffItem.idx;
var rawIndex = oldData.getRawIndex(idx);
// Data is replaced. In the case of dynamic data queue
// FIXME FIXME FIXME
if (rawIndex !== idx) {
currPoints.push(oldData.getItemLayout(idx));
nextPoints.push(newCoordSys.dataToPoint([
oldData.get(dims[0], idx, true), oldData.get(dims[1], idx, true)
]));
currStackedPoints.push(oldStackedOnPoints[idx]);
nextStackedPoints.push(
getStackedOnPoint(
newCoordSys, oldData, idx
)
);
rawIndices.push(rawIndex);
}
else {
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];
});
var sortedCurrPoints = [];
var sortedNextPoints = [];
var sortedCurrStackedPoints = [];
var sortedNextStackedPoints = [];
var sortedStatus = [];
for (var i = 0; i < sortedIndices.length; i++) {
var idx = sortedIndices[i];
sortedCurrPoints[i] = currPoints[idx];
sortedNextPoints[i] = nextPoints[idx];
sortedCurrStackedPoints[i] = currStackedPoints[idx];
sortedNextStackedPoints[i] = nextStackedPoints[idx];
sortedStatus[i] = status[idx];
}
return {
current: sortedCurrPoints,
next: sortedNextPoints,
stackedOnCurrent: sortedCurrStackedPoints,
stackedOnNext: sortedNextStackedPoints,
status: sortedStatus
};
};
});
|