blob: e3721af3b871a64f5caf8e205c97ca2cd5df5cae [file] [log] [blame]
/*
* 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<BrushOption> {
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;