| /* | |
| * 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 createSeriesDataSimply from '../helper/createSeriesDataSimply'; | |
| import {defaultEmphasis} from '../../util/model'; | |
| import {makeSeriesEncodeForNameBased} from '../../data/helper/sourceHelper'; | |
| import LegendVisualProvider from '../../visual/LegendVisualProvider'; | |
| import SeriesModel from '../../model/Series'; | |
| import { | |
| SeriesOption, | |
| BoxLayoutOptionMixin, | |
| HorizontalAlign, | |
| LabelOption, | |
| LabelLineOption, | |
| ItemStyleOption, | |
| OptionDataValueNumeric, | |
| StatesOptionMixin, | |
| OptionDataItemObject, | |
| LayoutOrient, | |
| VerticalAlign, | |
| SeriesLabelOption, | |
| SeriesEncodeOptionMixin, | |
| DefaultStatesMixinEmphasis, | |
| CallbackDataParams | |
| } from '../../util/types'; | |
| import GlobalModel from '../../model/Global'; | |
| import SeriesData from '../../data/SeriesData'; | |
| type FunnelLabelOption = Omit<SeriesLabelOption, 'position'> & { | |
| position?: LabelOption['position'] | |
| | 'outer' | 'inner' | 'center' | 'rightTop' | 'rightBottom' | 'leftTop' | 'leftBottom' | |
| }; | |
| interface FunnelStatesMixin { | |
| emphasis?: DefaultStatesMixinEmphasis | |
| } | |
| export interface FunnelCallbackDataParams extends CallbackDataParams { | |
| percent: number | |
| } | |
| export interface FunnelStateOption<TCbParams = never> { | |
| itemStyle?: ItemStyleOption<TCbParams> | |
| label?: FunnelLabelOption | |
| labelLine?: LabelLineOption | |
| } | |
| export interface FunnelDataItemOption | |
| extends FunnelStateOption, StatesOptionMixin<FunnelStateOption, FunnelStatesMixin>, | |
| OptionDataItemObject<OptionDataValueNumeric> { | |
| itemStyle?: ItemStyleOption & { | |
| width?: number | string | |
| height?: number | string | |
| } | |
| } | |
| export interface FunnelSeriesOption | |
| extends SeriesOption<FunnelStateOption<FunnelCallbackDataParams>, FunnelStatesMixin>, | |
| FunnelStateOption<FunnelCallbackDataParams>, | |
| BoxLayoutOptionMixin, SeriesEncodeOptionMixin { | |
| type?: 'funnel' | |
| min?: number | |
| max?: number | |
| /** | |
| * Absolute number or percent string | |
| */ | |
| minSize?: number | string | |
| maxSize?: number | string | |
| sort?: 'ascending' | 'descending' | 'none' | |
| orient?: LayoutOrient | |
| gap?: number | |
| funnelAlign?: HorizontalAlign | VerticalAlign | |
| data?: (OptionDataValueNumeric | OptionDataValueNumeric[] | FunnelDataItemOption)[] | |
| } | |
| class FunnelSeriesModel extends SeriesModel<FunnelSeriesOption> { | |
| static type = 'series.funnel' as const; | |
| type = FunnelSeriesModel.type; | |
| init(option: FunnelSeriesOption) { | |
| super.init.apply(this, arguments as any); | |
| // Enable legend selection for each data item | |
| // Use a function instead of direct access because data reference may changed | |
| this.legendVisualProvider = new LegendVisualProvider( | |
| zrUtil.bind(this.getData, this), zrUtil.bind(this.getRawData, this) | |
| ); | |
| // Extend labelLine emphasis | |
| this._defaultLabelLine(option); | |
| } | |
| getInitialData(this: FunnelSeriesModel, option: FunnelSeriesOption, ecModel: GlobalModel): SeriesData { | |
| return createSeriesDataSimply(this, { | |
| coordDimensions: ['value'], | |
| encodeDefaulter: zrUtil.curry(makeSeriesEncodeForNameBased, this) | |
| }); | |
| } | |
| _defaultLabelLine(option: FunnelSeriesOption) { | |
| // Extend labelLine emphasis | |
| defaultEmphasis(option, 'labelLine', ['show']); | |
| const labelLineNormalOpt = option.labelLine; | |
| const labelLineEmphasisOpt = option.emphasis.labelLine; | |
| // Not show label line if `label.normal.show = false` | |
| labelLineNormalOpt.show = labelLineNormalOpt.show | |
| && option.label.show; | |
| labelLineEmphasisOpt.show = labelLineEmphasisOpt.show | |
| && option.emphasis.label.show; | |
| } | |
| // Overwrite | |
| getDataParams(dataIndex: number): FunnelCallbackDataParams { | |
| const data = this.getData(); | |
| const params = super.getDataParams(dataIndex) as FunnelCallbackDataParams; | |
| const valueDim = data.mapDimension('value'); | |
| const sum = data.getSum(valueDim); | |
| // Percent is 0 if sum is 0 | |
| params.percent = !sum ? 0 : +(data.get(valueDim, dataIndex) as number / sum * 100).toFixed(2); | |
| params.$vars.push('percent'); | |
| return params; | |
| } | |
| static defaultOption: FunnelSeriesOption = { | |
| // zlevel: 0, // 一级层叠 | |
| z: 2, // 二级层叠 | |
| legendHoverLink: true, | |
| colorBy: 'data', | |
| left: 80, | |
| top: 60, | |
| right: 80, | |
| bottom: 60, | |
| // width: {totalWidth} - left - right, | |
| // height: {totalHeight} - top - bottom, | |
| // 默认取数据最小最大值 | |
| // min: 0, | |
| // max: 100, | |
| minSize: '0%', | |
| maxSize: '100%', | |
| sort: 'descending', // 'ascending', 'descending' | |
| orient: 'vertical', | |
| gap: 0, | |
| funnelAlign: 'center', | |
| label: { | |
| show: true, | |
| position: 'outer' | |
| // formatter: 标签文本格式器,同Tooltip.formatter,不支持异步回调 | |
| }, | |
| labelLine: { | |
| show: true, | |
| length: 20, | |
| lineStyle: { | |
| // color: 各异, | |
| width: 1 | |
| } | |
| }, | |
| itemStyle: { | |
| // color: 各异, | |
| borderColor: '#fff', | |
| borderWidth: 1 | |
| }, | |
| emphasis: { | |
| label: { | |
| show: true | |
| } | |
| }, | |
| select: { | |
| itemStyle: { | |
| borderColor: '#212121' | |
| } | |
| } | |
| }; | |
| } | |
| export default FunnelSeriesModel; |