提交 7b7a7470 编写于 作者: P pissang

perf(line): optimize performance of time series data on line.

上级 9b991a41
......@@ -43,7 +43,6 @@ import { CoordinateSystemClipArea } from '../../coord/CoordinateSystem';
import { setStatesStylesFromModel, setStatesFlag, enableHoverEmphasis } from '../../util/states';
import { getECData } from '../../util/ecData';
import { createFloat32Array } from '../../util/vendor';
import { createSymbol } from '../../util/symbol';
type PolarArea = ReturnType<Polar['getArea']>;
......@@ -433,7 +432,7 @@ class LineView extends ChartView {
const valueOrigin = areaStyleModel.get('origin');
const dataCoordInfo = prepareDataCoordInfo(coordSys, data, valueOrigin);
let stackedOnPoints = getStackedOnPoints(coordSys, data, dataCoordInfo);
let stackedOnPoints = isAreaChart && getStackedOnPoints(coordSys, data, dataCoordInfo);
const showSymbol = seriesModel.get('showSymbol');
......@@ -490,7 +489,10 @@ class LineView extends ChartView {
if (step) {
// TODO If stacked series is not step
points = turnPointsIntoStep(points, coordSys, step);
stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
if (stackedOnPoints) {
stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
}
}
polyline = this._newPolyline(points);
......@@ -548,7 +550,9 @@ class LineView extends ChartView {
if (step) {
// TODO If stacked series is not step
points = turnPointsIntoStep(points, coordSys, step);
stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
if (stackedOnPoints) {
stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
}
}
polyline.setShape({
......
......@@ -25,9 +25,16 @@ import Axis2D from './Axis2D';
import { CoordinateSystem } from '../CoordinateSystem';
import GridModel from './GridModel';
import Grid from './Grid';
import Scale from '../../scale/Scale';
import { invert } from 'zrender/src/core/matrix';
import { applyTransform } from 'zrender/src/core/vector';
export const cartesian2DDimensions = ['x', 'y'];
function canCalculateAffineTransform(scale: Scale) {
return scale.type === 'interval' || scale.type === 'time';
}
class Cartesian2D extends Cartesian<Axis2D> implements CoordinateSystem {
readonly type = 'cartesian2d';
......@@ -38,6 +45,45 @@ class Cartesian2D extends Cartesian<Axis2D> implements CoordinateSystem {
master: Grid;
private _transform: number[];
private _invTransform: number[];
/**
* Calculate an affine transform matrix if two axes are time or value.
* It's mainly for accelartion on the large time series data.
*/
calcAffineTransform() {
this._transform = this._invTransform = null;
const xAxisScale = this.getAxis('x').scale;
const yAxisScale = this.getAxis('y').scale;
if (!canCalculateAffineTransform(xAxisScale) || !canCalculateAffineTransform(yAxisScale)) {
return;
}
const xScaleExtent = xAxisScale.getExtent();
const yScaleExtent = yAxisScale.getExtent();
const start = this.dataToPoint([xScaleExtent[0], yScaleExtent[0]]);
const end = this.dataToPoint([xScaleExtent[1], yScaleExtent[1]]);
const xScaleSpan = xScaleExtent[1] - xScaleExtent[0];
const yScaleSpan = yScaleExtent[1] - yScaleExtent[0];
if (!xScaleSpan || !yScaleSpan) {
return;
}
// Accelerate data to point calculation on the special large time series data.
const scaleX = (end[0] - start[0]) / xScaleSpan;
const scaleY = (end[1] - start[1]) / yScaleSpan;
const translateX = start[0] - xScaleExtent[0] * scaleX;
const translateY = start[1] - yScaleExtent[0] * scaleY;
const m = this._transform = [scaleX, 0, 0, scaleY, translateX, translateY];
this._invTransform = invert([], m);
}
/**
* Base axis will be used on stacking.
*/
......@@ -60,6 +106,9 @@ class Cartesian2D extends Cartesian<Axis2D> implements CoordinateSystem {
}
dataToPoint(data: ScaleDataValue[], reserved?: unknown, out?: number[]): number[] {
if (this._transform) {
return applyTransform(out || [], data as number[], this._transform);
}
const xAxis = this.getAxis('x');
const yAxis = this.getAxis('y');
out = out || [];
......@@ -89,6 +138,9 @@ class Cartesian2D extends Cartesian<Axis2D> implements CoordinateSystem {
}
pointToData(point: number[], out?: number[]): number[] {
if (this._invTransform) {
return applyTransform(out, point, this._invTransform);
}
const xAxis = this.getAxis('x');
const yAxis = this.getAxis('y');
out = out || [];
......
......@@ -152,6 +152,12 @@ class Grid implements CoordinateSystemMaster {
adjustAxes();
}
each(this._coordsList, function (coord) {
// Calculate affine matrix to accelerate the data to point transform.
// If all the axes scales are time or value.
coord.calcAffineTransform();
});
function adjustAxes() {
each(axesList, function (axis) {
const isHorizontal = axis.isHorizontal();
......@@ -407,10 +413,6 @@ class Grid implements CoordinateSystemMaster {
* Update cartesian properties from series.
*/
private _updateScale(ecModel: GlobalModel, gridModel: GridModel): void {
const sortedDataValue: number[] = [];
const sortedDataIndex: number[] = [];
let hasCategoryIndices = false;
// Reset scale
each(this._axesList, function (axis) {
axis.scale.setExtent(Infinity, -Infinity);
......
......@@ -97,6 +97,8 @@ abstract class Scale {
/**
* Get extent
*
* Extent is always in increase order.
*/
getExtent(): [number, number] {
return this._extent.slice() as [number, number];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册