Spaces:
Running
Running
| /* | |
| * 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. | |
| */ | |
| /** | |
| * @file Visual solution, for consistent option specification. | |
| */ | |
| import * as zrUtil from 'zrender/src/core/util'; | |
| import VisualMapping, { VisualMappingOption } from './VisualMapping'; | |
| import { Dictionary } from 'zrender/src/core/types'; | |
| import { | |
| BuiltinVisualProperty, | |
| ParsedValue, | |
| DimensionLoose, | |
| StageHandlerProgressExecutor, | |
| DimensionIndex | |
| } from '../util/types'; | |
| import SeriesData from '../data/SeriesData'; | |
| import { getItemVisualFromData, setItemVisualFromData } from './helper'; | |
| const each = zrUtil.each; | |
| type VisualMappingCollection<VisualState extends string> | |
| = { | |
| [key in VisualState]?: { | |
| [key in BuiltinVisualProperty]?: VisualMapping | |
| } & { | |
| __alphaForOpacity?: VisualMapping | |
| } | |
| }; | |
| function hasKeys(obj: Dictionary<any>) { | |
| if (obj) { | |
| for (const name in obj) { | |
| if (obj.hasOwnProperty(name)) { | |
| return true; | |
| } | |
| } | |
| } | |
| } | |
| type VisualOption = {[key in BuiltinVisualProperty]?: any}; | |
| export function createVisualMappings<VisualState extends string>( | |
| option: Partial<Record<VisualState, VisualOption>>, | |
| stateList: readonly VisualState[], | |
| supplementVisualOption: (mappingOption: VisualMappingOption, state: string) => void | |
| ) { | |
| const visualMappings: VisualMappingCollection<VisualState> = {}; | |
| each(stateList, function (state) { | |
| const mappings = visualMappings[state] = createMappings(); | |
| each(option[state], function (visualData: VisualOption, visualType: BuiltinVisualProperty) { | |
| if (!VisualMapping.isValidType(visualType)) { | |
| return; | |
| } | |
| let mappingOption = { | |
| type: visualType, | |
| visual: visualData | |
| }; | |
| supplementVisualOption && supplementVisualOption(mappingOption, state); | |
| mappings[visualType] = new VisualMapping(mappingOption); | |
| // Prepare a alpha for opacity, for some case that opacity | |
| // is not supported, such as rendering using gradient color. | |
| if (visualType === 'opacity') { | |
| mappingOption = zrUtil.clone(mappingOption); | |
| mappingOption.type = 'colorAlpha'; | |
| mappings.__hidden.__alphaForOpacity = new VisualMapping(mappingOption); | |
| } | |
| }); | |
| }); | |
| return visualMappings; | |
| function createMappings() { | |
| const Creater = function () {}; | |
| // Make sure hidden fields will not be visited by | |
| // object iteration (with hasOwnProperty checking). | |
| Creater.prototype.__hidden = Creater.prototype; | |
| const obj = new (Creater as any)(); | |
| return obj; | |
| } | |
| } | |
| export function replaceVisualOption<T extends string>( | |
| thisOption: Partial<Record<T, any>>, newOption: Partial<Record<T, any>>, keys: readonly T[] | |
| ) { | |
| // Visual attributes merge is not supported, otherwise it | |
| // brings overcomplicated merge logic. See #2853. So if | |
| // newOption has anyone of these keys, all of these keys | |
| // will be reset. Otherwise, all keys remain. | |
| let has; | |
| zrUtil.each(keys, function (key) { | |
| if (newOption.hasOwnProperty(key) && hasKeys(newOption[key])) { | |
| has = true; | |
| } | |
| }); | |
| has && zrUtil.each(keys, function (key) { | |
| if (newOption.hasOwnProperty(key) && hasKeys(newOption[key])) { | |
| thisOption[key] = zrUtil.clone(newOption[key]); | |
| } | |
| else { | |
| delete thisOption[key]; | |
| } | |
| }); | |
| } | |
| /** | |
| * @param stateList | |
| * @param visualMappings | |
| * @param list | |
| * @param getValueState param: valueOrIndex, return: state. | |
| * @param scope Scope for getValueState | |
| * @param dimension Concrete dimension, if used. | |
| */ | |
| // ???! handle brush? | |
| export function applyVisual<VisualState extends string, Scope>( | |
| stateList: readonly VisualState[], | |
| visualMappings: VisualMappingCollection<VisualState>, | |
| data: SeriesData, | |
| getValueState: (this: Scope, valueOrIndex: ParsedValue | number) => VisualState, | |
| scope?: Scope, | |
| dimension?: DimensionLoose | |
| ) { | |
| const visualTypesMap: Partial<Record<VisualState, BuiltinVisualProperty[]>> = {}; | |
| zrUtil.each(stateList, function (state) { | |
| const visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]); | |
| visualTypesMap[state] = visualTypes; | |
| }); | |
| let dataIndex: number; | |
| function getVisual(key: string) { | |
| return getItemVisualFromData(data, dataIndex, key) as string | number; | |
| } | |
| function setVisual(key: string, value: any) { | |
| setItemVisualFromData(data, dataIndex, key, value); | |
| } | |
| if (dimension == null) { | |
| data.each(eachItem); | |
| } | |
| else { | |
| data.each([dimension], eachItem); | |
| } | |
| function eachItem(valueOrIndex: ParsedValue | number, index?: number) { | |
| dataIndex = dimension == null | |
| ? valueOrIndex as number // First argument is index | |
| : index; | |
| const rawDataItem = data.getRawDataItem(dataIndex); | |
| // Consider performance | |
| // @ts-ignore | |
| if (rawDataItem && rawDataItem.visualMap === false) { | |
| return; | |
| } | |
| const valueState = getValueState.call(scope, valueOrIndex); | |
| const mappings = visualMappings[valueState]; | |
| const visualTypes = visualTypesMap[valueState]; | |
| for (let i = 0, len = visualTypes.length; i < len; i++) { | |
| const type = visualTypes[i]; | |
| mappings[type] && mappings[type].applyVisual( | |
| valueOrIndex, getVisual, setVisual | |
| ); | |
| } | |
| } | |
| } | |
| /** | |
| * @param data | |
| * @param stateList | |
| * @param visualMappings <state, Object.<visualType, module:echarts/visual/VisualMapping>> | |
| * @param getValueState param: valueOrIndex, return: state. | |
| * @param dim dimension or dimension index. | |
| */ | |
| export function incrementalApplyVisual<VisualState extends string>( | |
| stateList: readonly VisualState[], | |
| visualMappings: VisualMappingCollection<VisualState>, | |
| getValueState: (valueOrIndex: ParsedValue | number) => VisualState, | |
| dim?: DimensionLoose | |
| ): StageHandlerProgressExecutor { | |
| const visualTypesMap: Partial<Record<VisualState, BuiltinVisualProperty[]>> = {}; | |
| zrUtil.each(stateList, function (state) { | |
| const visualTypes = VisualMapping.prepareVisualTypes(visualMappings[state]); | |
| visualTypesMap[state] = visualTypes; | |
| }); | |
| return { | |
| progress: function progress(params, data) { | |
| let dimIndex: DimensionIndex; | |
| if (dim != null) { | |
| dimIndex = data.getDimensionIndex(dim); | |
| } | |
| function getVisual(key: string) { | |
| return getItemVisualFromData(data, dataIndex, key) as string | number; | |
| } | |
| function setVisual(key: string, value: any) { | |
| setItemVisualFromData(data, dataIndex, key, value); | |
| } | |
| let dataIndex: number; | |
| const store = data.getStore(); | |
| while ((dataIndex = params.next()) != null) { | |
| const rawDataItem = data.getRawDataItem(dataIndex); | |
| // Consider performance | |
| // @ts-ignore | |
| if (rawDataItem && rawDataItem.visualMap === false) { | |
| continue; | |
| } | |
| const value = dim != null | |
| ? store.get(dimIndex, dataIndex) | |
| : dataIndex; | |
| const valueState = getValueState(value); | |
| const mappings = visualMappings[valueState]; | |
| const visualTypes = visualTypesMap[valueState]; | |
| for (let i = 0, len = visualTypes.length; i < len; i++) { | |
| const type = visualTypes[i]; | |
| mappings[type] && mappings[type].applyVisual(value, getVisual, setVisual); | |
| } | |
| } | |
| } | |
| }; | |
| } | |