echarts dataStackHelper 源码

  • 2022-10-20
  • 浏览 (553)

echarts dataStackHelper 代码

文件路径:/src/data/helper/dataStackHelper.ts

/*
* 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 {each, isString} from 'zrender/src/core/util';
import SeriesDimensionDefine from '../SeriesDimensionDefine';
import SeriesModel from '../../model/Series';
import SeriesData, { DataCalculationInfo } from '../SeriesData';
import type { SeriesOption, SeriesStackOptionMixin, DimensionName } from '../../util/types';
import { isSeriesDataSchema, SeriesDataSchema } from './SeriesDataSchema';
import DataStore from '../DataStore';

type EnableDataStackDimensionsInput = {
    schema: SeriesDataSchema;
    // If given, stack dimension will be ensured on this store.
    // Otherwise, stack dimesnion will be appended at the tail, and should not
    // be used on a shared store, but should create a brand new stroage later.
    store?: DataStore;
};
type EnableDataStackDimensionsInputLegacy = (SeriesDimensionDefine | string)[];

/**
 * Note that it is too complicated to support 3d stack by value
 * (have to create two-dimension inverted index), so in 3d case
 * we just support that stacked by index.
 *
 * @param seriesModel
 * @param dimensionsInput The same as the input of <module:echarts/data/SeriesData>.
 *        The input will be modified.
 * @param opt
 * @param opt.stackedCoordDimension Specify a coord dimension if needed.
 * @param opt.byIndex=false
 * @return calculationInfo
 * {
 *     stackedDimension: string
 *     stackedByDimension: string
 *     isStackedByIndex: boolean
 *     stackedOverDimension: string
 *     stackResultDimension: string
 * }
 */
export function enableDataStack(
    seriesModel: SeriesModel<SeriesOption & SeriesStackOptionMixin>,
    dimensionsInput: EnableDataStackDimensionsInput | EnableDataStackDimensionsInputLegacy,
    opt?: {
        // Backward compat
        stackedCoordDimension?: string
        byIndex?: boolean
    }
): Pick<
    DataCalculationInfo<unknown>,
    'stackedDimension'
    | 'stackedByDimension'
    | 'isStackedByIndex'
    | 'stackedOverDimension'
    | 'stackResultDimension'
> {
    opt = opt || {};
    let byIndex = opt.byIndex;
    const stackedCoordDimension = opt.stackedCoordDimension;

    let dimensionDefineList: EnableDataStackDimensionsInputLegacy;
    let schema: SeriesDataSchema;
    let store: DataStore;

    if (isLegacyDimensionsInput(dimensionsInput)) {
        dimensionDefineList = dimensionsInput;
    }
    else {
        schema = dimensionsInput.schema;
        dimensionDefineList = schema.dimensions;
        store = dimensionsInput.store;
    }

    // Compatibal: when `stack` is set as '', do not stack.
    const mayStack = !!(seriesModel && seriesModel.get('stack'));
    let stackedByDimInfo: SeriesDimensionDefine;
    let stackedDimInfo: SeriesDimensionDefine;
    let stackResultDimension: string;
    let stackedOverDimension: string;

    each(dimensionDefineList, function (dimensionInfo, index) {
        if (isString(dimensionInfo)) {
            dimensionDefineList[index] = dimensionInfo = {
                name: dimensionInfo as string
            } as SeriesDimensionDefine;
        }

        if (mayStack && !dimensionInfo.isExtraCoord) {
            // Find the first ordinal dimension as the stackedByDimInfo.
            if (!byIndex && !stackedByDimInfo && dimensionInfo.ordinalMeta) {
                stackedByDimInfo = dimensionInfo;
            }
            // Find the first stackable dimension as the stackedDimInfo.
            if (!stackedDimInfo
                && dimensionInfo.type !== 'ordinal'
                && dimensionInfo.type !== 'time'
                && (!stackedCoordDimension || stackedCoordDimension === dimensionInfo.coordDim)
            ) {
                stackedDimInfo = dimensionInfo;
            }
        }
    });

    if (stackedDimInfo && !byIndex && !stackedByDimInfo) {
        // Compatible with previous design, value axis (time axis) only stack by index.
        // It may make sense if the user provides elaborately constructed data.
        byIndex = true;
    }

    // Add stack dimension, they can be both calculated by coordinate system in `unionExtent`.
    // That put stack logic in List is for using conveniently in echarts extensions, but it
    // might not be a good way.
    if (stackedDimInfo) {
        // Use a weird name that not duplicated with other names.
        // Also need to use seriesModel.id as postfix because different
        // series may share same data store. The stack dimension needs to be distinguished.
        stackResultDimension = '__\0ecstackresult_' + seriesModel.id;
        stackedOverDimension = '__\0ecstackedover_' + seriesModel.id;

        // Create inverted index to fast query index by value.
        if (stackedByDimInfo) {
            stackedByDimInfo.createInvertedIndices = true;
        }

        const stackedDimCoordDim = stackedDimInfo.coordDim;
        const stackedDimType = stackedDimInfo.type;
        let stackedDimCoordIndex = 0;

        each(dimensionDefineList, function (dimensionInfo: SeriesDimensionDefine) {
            if (dimensionInfo.coordDim === stackedDimCoordDim) {
                stackedDimCoordIndex++;
            }
        });

        const stackedOverDimensionDefine: SeriesDimensionDefine = {
            name: stackResultDimension,
            coordDim: stackedDimCoordDim,
            coordDimIndex: stackedDimCoordIndex,
            type: stackedDimType,
            isExtraCoord: true,
            isCalculationCoord: true,
            storeDimIndex: dimensionDefineList.length
        };

        const stackResultDimensionDefine: SeriesDimensionDefine = {
            name: stackedOverDimension,
            // This dimension contains stack base (generally, 0), so do not set it as
            // `stackedDimCoordDim` to avoid extent calculation, consider log scale.
            coordDim: stackedOverDimension,
            coordDimIndex: stackedDimCoordIndex + 1,
            type: stackedDimType,
            isExtraCoord: true,
            isCalculationCoord: true,
            storeDimIndex: dimensionDefineList.length + 1
        };

        if (schema) {
            if (store) {
                stackedOverDimensionDefine.storeDimIndex =
                    store.ensureCalculationDimension(stackedOverDimension, stackedDimType);
                stackResultDimensionDefine.storeDimIndex =
                    store.ensureCalculationDimension(stackResultDimension, stackedDimType);
            }

            schema.appendCalculationDimension(stackedOverDimensionDefine);
            schema.appendCalculationDimension(stackResultDimensionDefine);
        }
        else {
            dimensionDefineList.push(stackedOverDimensionDefine);
            dimensionDefineList.push(stackResultDimensionDefine);
        }
    }

    return {
        stackedDimension: stackedDimInfo && stackedDimInfo.name,
        stackedByDimension: stackedByDimInfo && stackedByDimInfo.name,
        isStackedByIndex: byIndex,
        stackedOverDimension: stackedOverDimension,
        stackResultDimension: stackResultDimension
    };
}

function isLegacyDimensionsInput(
    dimensionsInput: Parameters<typeof enableDataStack>[1]
): dimensionsInput is EnableDataStackDimensionsInputLegacy {
    return !isSeriesDataSchema((dimensionsInput as EnableDataStackDimensionsInput).schema);
}

export function isDimensionStacked(data: SeriesData, stackedDim: string): boolean {
    // Each single series only maps to one pair of axis. So we do not need to
    // check stackByDim, whatever stacked by a dimension or stacked by index.
    return !!stackedDim && stackedDim === data.getCalculationInfo('stackedDimension');
}

export function getStackedDimension(data: SeriesData, targetDim: string): DimensionName {
    return isDimensionStacked(data, targetDim)
        ? data.getCalculationInfo('stackResultDimension')
        : targetDim;
}

相关信息

echarts 源码目录

相关文章

echarts SeriesDataSchema 源码

echarts createDimensions 源码

echarts dataProvider 源码

echarts dataValueHelper 源码

echarts dimensionHelper 源码

echarts linkList 源码

echarts linkSeriesData 源码

echarts sourceHelper 源码

echarts sourceManager 源码

echarts transform 源码

0  赞