project/node_modules/echarts/lib/core/task.js

345 lines
12 KiB
JavaScript
Raw Permalink Normal View History

2024-07-14 15:48:34 +08:00
/*
* 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.
*/
/**
* AUTO-GENERATED FILE. DO NOT MODIFY.
*/
/*
* 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 { assert, isArray } from 'zrender/lib/core/util.js';
;
/**
* @param {Object} define
* @return See the return of `createTask`.
*/
export function createTask(define) {
return new Task(define);
}
var Task = /** @class */function () {
function Task(define) {
define = define || {};
this._reset = define.reset;
this._plan = define.plan;
this._count = define.count;
this._onDirty = define.onDirty;
this._dirty = true;
}
/**
* @param step Specified step.
* @param skip Skip customer perform call.
* @param modBy Sampling window size.
* @param modDataCount Sampling count.
* @return whether unfinished.
*/
Task.prototype.perform = function (performArgs) {
var upTask = this._upstream;
var skip = performArgs && performArgs.skip;
// TODO some refactor.
// Pull data. Must pull data each time, because context.data
// may be updated by Series.setData.
if (this._dirty && upTask) {
var context = this.context;
context.data = context.outputData = upTask.context.outputData;
}
if (this.__pipeline) {
this.__pipeline.currentTask = this;
}
var planResult;
if (this._plan && !skip) {
planResult = this._plan(this.context);
}
// Support sharding by mod, which changes the render sequence and makes the rendered graphic
// elements uniformed distributed when progress, especially when moving or zooming.
var lastModBy = normalizeModBy(this._modBy);
var lastModDataCount = this._modDataCount || 0;
var modBy = normalizeModBy(performArgs && performArgs.modBy);
var modDataCount = performArgs && performArgs.modDataCount || 0;
if (lastModBy !== modBy || lastModDataCount !== modDataCount) {
planResult = 'reset';
}
function normalizeModBy(val) {
!(val >= 1) && (val = 1); // jshint ignore:line
return val;
}
var forceFirstProgress;
if (this._dirty || planResult === 'reset') {
this._dirty = false;
forceFirstProgress = this._doReset(skip);
}
this._modBy = modBy;
this._modDataCount = modDataCount;
var step = performArgs && performArgs.step;
if (upTask) {
if (process.env.NODE_ENV !== 'production') {
assert(upTask._outputDueEnd != null);
}
this._dueEnd = upTask._outputDueEnd;
}
// DataTask or overallTask
else {
if (process.env.NODE_ENV !== 'production') {
assert(!this._progress || this._count);
}
this._dueEnd = this._count ? this._count(this.context) : Infinity;
}
// Note: Stubs, that its host overall task let it has progress, has progress.
// If no progress, pass index from upstream to downstream each time plan called.
if (this._progress) {
var start = this._dueIndex;
var end = Math.min(step != null ? this._dueIndex + step : Infinity, this._dueEnd);
if (!skip && (forceFirstProgress || start < end)) {
var progress = this._progress;
if (isArray(progress)) {
for (var i = 0; i < progress.length; i++) {
this._doProgress(progress[i], start, end, modBy, modDataCount);
}
} else {
this._doProgress(progress, start, end, modBy, modDataCount);
}
}
this._dueIndex = end;
// If no `outputDueEnd`, assume that output data and
// input data is the same, so use `dueIndex` as `outputDueEnd`.
var outputDueEnd = this._settedOutputEnd != null ? this._settedOutputEnd : end;
if (process.env.NODE_ENV !== 'production') {
// ??? Can not rollback.
assert(outputDueEnd >= this._outputDueEnd);
}
this._outputDueEnd = outputDueEnd;
} else {
// (1) Some overall task has no progress.
// (2) Stubs, that its host overall task do not let it has progress, has no progress.
// This should always be performed so it can be passed to downstream.
this._dueIndex = this._outputDueEnd = this._settedOutputEnd != null ? this._settedOutputEnd : this._dueEnd;
}
return this.unfinished();
};
Task.prototype.dirty = function () {
this._dirty = true;
this._onDirty && this._onDirty(this.context);
};
Task.prototype._doProgress = function (progress, start, end, modBy, modDataCount) {
iterator.reset(start, end, modBy, modDataCount);
this._callingProgress = progress;
this._callingProgress({
start: start,
end: end,
count: end - start,
next: iterator.next
}, this.context);
};
Task.prototype._doReset = function (skip) {
this._dueIndex = this._outputDueEnd = this._dueEnd = 0;
this._settedOutputEnd = null;
var progress;
var forceFirstProgress;
if (!skip && this._reset) {
progress = this._reset(this.context);
if (progress && progress.progress) {
forceFirstProgress = progress.forceFirstProgress;
progress = progress.progress;
}
// To simplify no progress checking, array must has item.
if (isArray(progress) && !progress.length) {
progress = null;
}
}
this._progress = progress;
this._modBy = this._modDataCount = null;
var downstream = this._downstream;
downstream && downstream.dirty();
return forceFirstProgress;
};
Task.prototype.unfinished = function () {
return this._progress && this._dueIndex < this._dueEnd;
};
/**
* @param downTask The downstream task.
* @return The downstream task.
*/
Task.prototype.pipe = function (downTask) {
if (process.env.NODE_ENV !== 'production') {
assert(downTask && !downTask._disposed && downTask !== this);
}
// If already downstream, do not dirty downTask.
if (this._downstream !== downTask || this._dirty) {
this._downstream = downTask;
downTask._upstream = this;
downTask.dirty();
}
};
Task.prototype.dispose = function () {
if (this._disposed) {
return;
}
this._upstream && (this._upstream._downstream = null);
this._downstream && (this._downstream._upstream = null);
this._dirty = false;
this._disposed = true;
};
Task.prototype.getUpstream = function () {
return this._upstream;
};
Task.prototype.getDownstream = function () {
return this._downstream;
};
Task.prototype.setOutputEnd = function (end) {
// This only happens in dataTask, dataZoom, map, currently.
// where dataZoom do not set end each time, but only set
// when reset. So we should record the set end, in case
// that the stub of dataZoom perform again and earse the
// set end by upstream.
this._outputDueEnd = this._settedOutputEnd = end;
};
return Task;
}();
export { Task };
var iterator = function () {
var end;
var current;
var modBy;
var modDataCount;
var winCount;
var it = {
reset: function (s, e, sStep, sCount) {
current = s;
end = e;
modBy = sStep;
modDataCount = sCount;
winCount = Math.ceil(modDataCount / modBy);
it.next = modBy > 1 && modDataCount > 0 ? modNext : sequentialNext;
}
};
return it;
function sequentialNext() {
return current < end ? current++ : null;
}
function modNext() {
var dataIndex = current % winCount * modBy + Math.ceil(current / winCount);
var result = current >= end ? null : dataIndex < modDataCount ? dataIndex
// If modDataCount is smaller than data.count() (consider `appendData` case),
// Use normal linear rendering mode.
: current;
current++;
return result;
}
}();
// -----------------------------------------------------------------------------
// For stream debug (Should be commented out after used!)
// @usage: printTask(this, 'begin');
// @usage: printTask(this, null, {someExtraProp});
// @usage: Use `__idxInPipeline` as conditional breakpiont.
//
// window.printTask = function (task: any, prefix: string, extra: { [key: string]: unknown }): void {
// window.ecTaskUID == null && (window.ecTaskUID = 0);
// task.uidDebug == null && (task.uidDebug = `task_${window.ecTaskUID++}`);
// task.agent && task.agent.uidDebug == null && (task.agent.uidDebug = `task_${window.ecTaskUID++}`);
// let props = [];
// if (task.__pipeline) {
// let val = `${task.__idxInPipeline}/${task.__pipeline.tail.__idxInPipeline} ${task.agent ? '(stub)' : ''}`;
// props.push({text: '__idxInPipeline/total', value: val});
// } else {
// let stubCount = 0;
// task.agentStubMap.each(() => stubCount++);
// props.push({text: 'idx', value: `overall (stubs: ${stubCount})`});
// }
// props.push({text: 'uid', value: task.uidDebug});
// if (task.__pipeline) {
// props.push({text: 'pipelineId', value: task.__pipeline.id});
// task.agent && props.push(
// {text: 'stubFor', value: task.agent.uidDebug}
// );
// }
// props.push(
// {text: 'dirty', value: task._dirty},
// {text: 'dueIndex', value: task._dueIndex},
// {text: 'dueEnd', value: task._dueEnd},
// {text: 'outputDueEnd', value: task._outputDueEnd}
// );
// if (extra) {
// Object.keys(extra).forEach(key => {
// props.push({text: key, value: extra[key]});
// });
// }
// let args = ['color: blue'];
// let msg = `%c[${prefix || 'T'}] %c` + props.map(item => (
// args.push('color: green', 'color: red'),
// `${item.text}: %c${item.value}`
// )).join('%c, ');
// console.log.apply(console, [msg].concat(args));
// // console.log(this);
// };
// window.printPipeline = function (task: any, prefix: string) {
// const pipeline = task.__pipeline;
// let currTask = pipeline.head;
// while (currTask) {
// window.printTask(currTask, prefix);
// currTask = currTask._downstream;
// }
// };
// window.showChain = function (chainHeadTask) {
// var chain = [];
// var task = chainHeadTask;
// while (task) {
// chain.push({
// task: task,
// up: task._upstream,
// down: task._downstream,
// idxInPipeline: task.__idxInPipeline
// });
// task = task._downstream;
// }
// return chain;
// };
// window.findTaskInChain = function (task, chainHeadTask) {
// let chain = window.showChain(chainHeadTask);
// let result = [];
// for (let i = 0; i < chain.length; i++) {
// let chainItem = chain[i];
// if (chainItem.task === task) {
// result.push(i);
// }
// }
// return result;
// };
// window.printChainAEachInChainB = function (chainHeadTaskA, chainHeadTaskB) {
// let chainA = window.showChain(chainHeadTaskA);
// for (let i = 0; i < chainA.length; i++) {
// console.log('chainAIdx:', i, 'inChainB:', window.findTaskInChain(chainA[i].task, chainHeadTaskB));
// }
// };