/* * 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 * as zrUtil from 'zrender/src/core/util'; import * as visualSolution from '../../visual/visualSolution'; import Model from '../../model/Model'; import { ComponentOption, ZRColor, VisualOptionFixed } from '../../util/types'; import ComponentModel from '../../model/Component'; import BrushTargetManager from '../helper/BrushTargetManager'; import { BrushCoverCreatorConfig, BrushMode, BrushCoverConfig, BrushDimensionMinMax, BrushAreaRange, BrushTypeUncertain, BrushType } from '../helper/BrushController'; import { ModelFinderObject } from '../../util/model'; const DEFAULT_OUT_OF_BRUSH_COLOR = '#ddd'; /** * The input to define brush areas. * (1) Can be created by user when calling dispatchAction. * (2) Can be created by `BrushController` * for brush behavior. area params are picked from `cover.__brushOptoin`. * In `BrushController`, "covers" are create or updated for each "area". */ export interface BrushAreaParam extends ModelFinderObject { brushType: BrushCoverConfig['brushType']; id?: BrushCoverConfig['id']; range?: BrushCoverConfig['range']; // `ModelFinderObject` and `panelId` are used to match "coord sys target" // for this area. See `BrushTargetManager['setInputRanges']`. // If panelId specified, use it to match panel firstly. // If not specified, use `ModelFinderObject` to match panel, // and then assign the panelId to the area. // If finally no panel matched, panelId keep null/undefined, // means global area. // PENDING: this feature should better belong to BrushController // rather than brush component? panelId?: BrushCoverConfig['panelId']; // Range in local coordinates of certain coordinate system. // When dispatchAction, if the area is the global area, // `range` is the input. if the area is not the global area, // `coordRange` is the input, and then convert to `range`. coordRange?: BrushAreaRange; // coord ranges, used in multiple cartesian in one grid. // Only for output to users. coordRanges?: BrushAreaRange[]; __rangeOffset?: { offset: BrushDimensionMinMax[] | BrushDimensionMinMax, xyMinMax: BrushDimensionMinMax[] } } /** * Generated by `brushModel.setAreas`, which merges * `area: BrushAreaParam` and `brushModel.option: BrushOption`. * See `generateBrushOption`. */ export interface BrushAreaParamInternal extends BrushAreaParam { brushMode: BrushMode; brushStyle: BrushCoverConfig['brushStyle']; transformable: BrushCoverConfig['transformable']; removeOnClick: BrushCoverConfig['removeOnClick']; z: BrushCoverConfig['z']; __rangeOffset?: { offset: BrushDimensionMinMax | BrushDimensionMinMax[]; xyMinMax: BrushDimensionMinMax[] }; } export type BrushToolboxIconType = BrushType | 'keep' | 'clear'; export interface BrushOption extends ComponentOption, ModelFinderObject { mainType?: 'brush'; // Default value see preprocessor. toolbox?: BrushToolboxIconType[]; // Series indices array, broadcast using dataIndex. // or 'all', which means all series. 'none'/null/undefined means no series. brushLink?: number[] | 'all' | 'none'; // Throttle in brushSelected event. 'fixRate' or 'debounce'. // If null, no throttle. Valid only in the first brush component throttleType?: 'fixRate' | 'debounce'; // Unit: ms, 0 means every event will be triggered. throttleDelay?: number; inBrush?: VisualOptionFixed; outOfBrush?: VisualOptionFixed; // --- Current painting brush options --- // Default type of brush brushType?: BrushTypeUncertain; brushStyle?: { borderWidth?: number; color?: ZRColor; borderColor?: ZRColor; }; transformable?: boolean; brushMode?: BrushMode; removeOnClick?: boolean; } class BrushModel extends ComponentModel { static type = 'brush' as const; type = BrushModel.type; static dependencies = ['geo', 'grid', 'xAxis', 'yAxis', 'parallel', 'series']; static defaultOption: BrushOption = { seriesIndex: 'all', brushType: 'rect', brushMode: 'single', transformable: true, brushStyle: { borderWidth: 1, color: 'rgba(210,219,238,0.3)', borderColor: '#D2DBEE' }, throttleType: 'fixRate', throttleDelay: 0, removeOnClick: true, z: 10000 }; /** * @readOnly */ areas: BrushAreaParamInternal[] = []; /** * Current activated brush type. * If null, brush is inactived. * see module:echarts/component/helper/BrushController * @readOnly */ brushType: BrushTypeUncertain; /** * Current brush painting area settings. * @readOnly */ brushOption: BrushCoverCreatorConfig = {} as BrushCoverCreatorConfig; // Inject brushTargetManager: BrushTargetManager; optionUpdated(newOption: BrushOption, isInit: boolean): void { const thisOption = this.option; !isInit && visualSolution.replaceVisualOption( thisOption, newOption, ['inBrush', 'outOfBrush'] ); const inBrush = thisOption.inBrush = thisOption.inBrush || {}; // Always give default visual, consider setOption at the second time. thisOption.outOfBrush = thisOption.outOfBrush || {color: DEFAULT_OUT_OF_BRUSH_COLOR}; if (!inBrush.hasOwnProperty('liftZ')) { // Bigger than the highlight z lift, otherwise it will // be effected by the highlight z when brush. inBrush.liftZ = 5; } } /** * If `areas` is null/undefined, range state remain. */ setAreas(areas?: BrushAreaParam[]): void { if (__DEV__) { zrUtil.assert(zrUtil.isArray(areas)); zrUtil.each(areas, function (area) { zrUtil.assert(area.brushType, 'Illegal areas'); }); } // If areas is null/undefined, range state remain. // This helps user to dispatchAction({type: 'brush'}) with no areas // set but just want to get the current brush select info from a `brush` event. if (!areas) { return; } this.areas = zrUtil.map(areas, function (area) { return generateBrushOption(this.option, area); }, this); } /** * Set the current painting brush option. */ setBrushOption(brushOption: BrushCoverCreatorConfig): void { this.brushOption = generateBrushOption(this.option, brushOption); this.brushType = this.brushOption.brushType; } } function generateBrushOption( option: BrushOption, brushOption: BrushAreaParam ): BrushAreaParamInternal; function generateBrushOption( option: BrushOption, brushOption: BrushCoverCreatorConfig ): BrushCoverCreatorConfig; function generateBrushOption( option: BrushOption, brushOption: BrushAreaParam | BrushCoverCreatorConfig ): BrushAreaParamInternal | BrushCoverCreatorConfig { return zrUtil.merge( { brushType: option.brushType, brushMode: option.brushMode, transformable: option.transformable, brushStyle: new Model(option.brushStyle).getItemStyle(), removeOnClick: option.removeOnClick, z: option.z }, brushOption, true ); } export default BrushModel;