| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- /*
- * 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 { createHashMap } from 'zrender/lib/core/util.js';
- import { asc, isNullableNumberFinite } from '../util/number.js';
- import { parseSanitizationFilter, passesSanitizationFilter } from '../data/helper/dataValueHelper.js';
- import { tryEnsureTypedArray, Float64ArrayCtor } from '../util/vendor.js';
- import { eachSeriesDealForAxisStat, LINEAR_POSITIVE_MIN_GAP_NO_VALID_VALUE, LINEAR_POSITIVE_MIN_GAP_SINGLE_VALID_VALUE, registerMetricImpl } from './axisStatistics.js';
- export function registerMetricImplLiPosMinGap() {
- registerMetricImpl('liPosMinGap', metricLiPosMinGapImpl);
- }
- function metricLiPosMinGapImpl(ecModel, perKeyPerAxis, ecPreparePerKeyPerAxis) {
- var newSerUids = createHashMap();
- var ecPrepareSerUids = ecPreparePerKeyPerAxis.serUids;
- var ecPrepareLiPosMinGap = ecPreparePerKeyPerAxis.liPosMinGap;
- var ecPrepareCacheMiss;
- var axis = perKeyPerAxis.axis;
- var scale = axis.scale;
- // const linearValueExtent = initExtentForUnion();
- var needTransform = scale.needTransform();
- var filter = scale.getFilter ? scale.getFilter() : null;
- var filterParsed = parseSanitizationFilter(filter);
- // const timeRetrieve: number[] = []; // _EC_PERF_
- // const timeSort: number[] = []; // _EC_PERF_
- // const timeAll: number[] = []; // _EC_PERF_
- // timeAll[0] = Date.now(); // _EC_PERF_
- function eachSeries(cb) {
- eachSeriesDealForAxisStat(ecModel, perKeyPerAxis.sers, function (seriesModel) {
- var rawData = seriesModel.getRawData();
- // NOTE: Currently there is no series that a "base axis" can map to multiple dimensions.
- var dimStoreIdx = rawData.getDimensionIndex(rawData.mapDimension(axis.dim));
- if (dimStoreIdx >= 0) {
- cb(dimStoreIdx, seriesModel, rawData.getStore());
- }
- });
- }
- var bufferCapacity = 0;
- eachSeries(function (dimStoreIdx, seriesModel, rawDataStore) {
- newSerUids.set(seriesModel.uid, 1);
- if (!ecPrepareSerUids || !ecPrepareSerUids.hasKey(seriesModel.uid)) {
- ecPrepareCacheMiss = true;
- }
- bufferCapacity += rawDataStore.count();
- });
- if (!ecPrepareSerUids || ecPrepareSerUids.keys().length !== newSerUids.keys().length) {
- ecPrepareCacheMiss = true;
- }
- if (!ecPrepareCacheMiss && ecPrepareLiPosMinGap != null) {
- // Consider the fact in practice:
- // - Series data can only be changed in EC_PREPARE.
- // - The relationship between series and axes can only be changed in EC_PREPARE and
- // SERIES_FILTER.
- // (See EC_CYCLE for more info)
- // Therefore, some statistics results can be cached in `GlobalModelCachePerECPrepare` to avoid
- // repeated time-consuming calculation for large data (e.g., over 1e5 data items).
- perKeyPerAxis.liPosMinGap = ecPrepareLiPosMinGap;
- return;
- }
- tryEnsureTypedArray(tmpValueBuffer, bufferCapacity);
- // timeRetrieve[0] = Date.now(); // _EC_PERF_
- var writeIdx = 0;
- eachSeries(function (dimStoreIdx, seriesModel, store) {
- // NOTE: It appears to be optimized by traveling only in a specific window (e.g., the current window)
- // instead of the entire data, but that would likely generate inconsistent result and bring
- // jitter when dataZoom roaming.
- for (var i = 0, cnt = store.count(); i < cnt; ++i) {
- // Manually inline some code for performance, since no other optimization
- // (such as, progressive) can be applied here.
- var val = store.get(dimStoreIdx, i);
- // NOTE: in most cases, filter does not exist.
- if (isFinite(val) && (!filter || passesSanitizationFilter(filterParsed, val))) {
- if (needTransform) {
- // PENDING: time-consuming if axis break is applied.
- val = scale.transformIn(val, null);
- }
- tmpValueBuffer.arr[writeIdx++] = val;
- // val < linearValueExtent[0] && (linearValueExtent[0] = val);
- // val > linearValueExtent[1] && (linearValueExtent[1] = val);
- }
- }
- });
- // Indicatively, retrieving values above costs 40ms for 1e6 values in a certain platform.
- // timeRetrieve[1] = Date.now(); // _EC_PERF_
- var tmpValueBufferView = tmpValueBuffer.typed ? tmpValueBuffer.arr.subarray(0, writeIdx) : (tmpValueBuffer.arr.length = writeIdx, tmpValueBuffer.arr);
- // timeSort[0] = Date.now(); // _EC_PERF_
- // Sort axis values into ascending order to calculate gaps.
- if (tmpValueBuffer.typed) {
- // Indicatively, 5ms for 1e6 values in a certain platform.
- tmpValueBufferView.sort();
- } else {
- asc(tmpValueBufferView);
- }
- // timeAll[1] = timeSort[1] = Date.now(); // _EC_PERF_
- // console.log('axisStatistics_minGap_retrieve', timeRetrieve[1] - timeRetrieve[0]); // _EC_PERF_
- // console.log('axisStatistics_minGap_sort', timeSort[1] - timeSort[0]); // _EC_PERF_
- // console.log('axisStatistics_minGap_all', timeAll[1] - timeAll[0]); // _EC_PERF_
- var min = Infinity;
- for (var j = 1; j < writeIdx; ++j) {
- var delta = tmpValueBufferView[j] - tmpValueBufferView[j - 1];
- if (
- // - Different series normally have the same values (e.g., barA, barB, barC),
- // which should be ignored.
- // - A single series with multiple same values is often not meaningful to
- // create `bandWidth`, so it is also ignored.
- delta > 0 && delta < min) {
- min = delta;
- }
- }
- ecPreparePerKeyPerAxis.liPosMinGap = perKeyPerAxis.liPosMinGap = isNullableNumberFinite(min) ? min : writeIdx > 0 ? LINEAR_POSITIVE_MIN_GAP_SINGLE_VALID_VALUE : LINEAR_POSITIVE_MIN_GAP_NO_VALID_VALUE;
- ecPreparePerKeyPerAxis.serUids = newSerUids;
- }
- // For performance optimization.
- var tmpValueBuffer = tryEnsureTypedArray({
- ctor: Float64ArrayCtor
- }, 50 // An arbitrary initial capability.
- );
|