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. | |
| */ | |
| import ComponentModel from '../../model/Component'; | |
| import SeriesData from '../../data/SeriesData'; | |
| import { | |
| ComponentOption, | |
| BoxLayoutOptionMixin, | |
| LayoutOrient, | |
| SymbolOptionMixin, | |
| LineStyleOption, | |
| ItemStyleOption, | |
| LabelOption, | |
| OptionDataValue, | |
| ZRColor, | |
| ColorString, | |
| CommonTooltipOption, | |
| CallbackDataParams, | |
| ZREasing | |
| } from '../../util/types'; | |
| import Model from '../../model/Model'; | |
| import GlobalModel, { GlobalModelSetOptionOpts } from '../../model/Global'; | |
| import { each, isObject, clone } from 'zrender/src/core/util'; | |
| import { convertOptionIdName, getDataItemValue } from '../../util/model'; | |
| export interface TimelineControlStyle extends ItemStyleOption { | |
| show?: boolean | |
| showPlayBtn?: boolean | |
| showPrevBtn?: boolean | |
| showNextBtn?: boolean | |
| itemSize?: number | |
| itemGap?: number | |
| position?: 'left' | 'right' | 'top' | 'bottom' | |
| playIcon?: string | |
| stopIcon?: string | |
| prevIcon?: string | |
| nextIcon?: string | |
| // Can be a percent value relative to itemSize | |
| playBtnSize?: number | string | |
| stopBtnSize?: number | string | |
| nextBtnSize?: number | string | |
| prevBtnSize?: number | string | |
| } | |
| export interface TimelineCheckpointStyle extends ItemStyleOption, | |
| SymbolOptionMixin { | |
| animation?: boolean | |
| animationDuration?: number | |
| animationEasing?: ZREasing | |
| } | |
| interface TimelineLineStyleOption extends LineStyleOption { | |
| show?: boolean | |
| } | |
| interface TimelineLabelOption extends Omit<LabelOption, 'position'> { | |
| show?: boolean | |
| // number can be distance to the timeline axis. sign will determine the side. | |
| position?: 'auto' | 'left' | 'right' | 'top' | 'bottom' | number | |
| interval?: 'auto' | number | |
| formatter?: string | ((value: string | number, index: number) => string) | |
| } | |
| export interface TimelineDataItemOption extends SymbolOptionMixin { | |
| value?: OptionDataValue | |
| itemStyle?: ItemStyleOption | |
| label?: TimelineLabelOption | |
| checkpointStyle?: TimelineCheckpointStyle | |
| emphasis?: { | |
| itemStyle?: ItemStyleOption | |
| label?: TimelineLabelOption | |
| checkpointStyle?: TimelineCheckpointStyle | |
| } | |
| // Style in progress | |
| progress?: { | |
| lineStyle?: TimelineLineStyleOption | |
| itemStyle?: ItemStyleOption | |
| label?: TimelineLabelOption | |
| } | |
| tooltip?: boolean | |
| } | |
| export interface TimelineOption extends ComponentOption, BoxLayoutOptionMixin, SymbolOptionMixin { | |
| mainType?: 'timeline' | |
| backgroundColor?: ZRColor | |
| borderColor?: ColorString | |
| borderWidth?: number | |
| tooltip?: CommonTooltipOption<CallbackDataParams> & { | |
| trigger?: 'item' | |
| } | |
| show?: boolean | |
| axisType?: 'category' | 'time' | 'value' | |
| currentIndex?: number | |
| autoPlay?: boolean | |
| rewind?: boolean | |
| loop?: boolean | |
| playInterval?: number | |
| realtime?: boolean | |
| controlPosition?: 'left' | 'right' | 'top' | 'bottom' | |
| padding?: number | number[] | |
| orient?: LayoutOrient | |
| inverse?: boolean | |
| // If not specified, options will be changed by "normalMerge". | |
| // If specified, options will be changed by "replaceMerge". | |
| replaceMerge?: GlobalModelSetOptionOpts['replaceMerge'] | |
| lineStyle?: TimelineLineStyleOption | |
| itemStyle?: ItemStyleOption | |
| checkpointStyle?: TimelineCheckpointStyle | |
| controlStyle?: TimelineControlStyle | |
| label?: TimelineLabelOption | |
| emphasis?: { | |
| lineStyle?: TimelineLineStyleOption | |
| itemStyle?: ItemStyleOption | |
| checkpointStyle?: TimelineCheckpointStyle | |
| controlStyle?: TimelineControlStyle | |
| label?: TimelineLabelOption | |
| } | |
| // Style in progress | |
| progress?: { | |
| lineStyle?: TimelineLineStyleOption | |
| itemStyle?: ItemStyleOption | |
| label?: TimelineLabelOption | |
| } | |
| data?: (OptionDataValue | TimelineDataItemOption)[] | |
| } | |
| class TimelineModel extends ComponentModel<TimelineOption> { | |
| static type = 'timeline'; | |
| type = TimelineModel.type; | |
| layoutMode = 'box'; | |
| private _data: SeriesData<TimelineModel>; | |
| private _names: string[]; | |
| /** | |
| * @override | |
| */ | |
| init(option: TimelineOption, parentModel: Model, ecModel: GlobalModel) { | |
| this.mergeDefaultAndTheme(option, ecModel); | |
| this._initData(); | |
| } | |
| /** | |
| * @override | |
| */ | |
| mergeOption(option: TimelineOption) { | |
| super.mergeOption.apply(this, arguments as any); | |
| this._initData(); | |
| } | |
| setCurrentIndex(currentIndex: number) { | |
| if (currentIndex == null) { | |
| currentIndex = this.option.currentIndex; | |
| } | |
| const count = this._data.count(); | |
| if (this.option.loop) { | |
| currentIndex = (currentIndex % count + count) % count; | |
| } | |
| else { | |
| currentIndex >= count && (currentIndex = count - 1); | |
| currentIndex < 0 && (currentIndex = 0); | |
| } | |
| this.option.currentIndex = currentIndex; | |
| } | |
| /** | |
| * @return {number} currentIndex | |
| */ | |
| getCurrentIndex() { | |
| return this.option.currentIndex; | |
| } | |
| /** | |
| * @return {boolean} | |
| */ | |
| isIndexMax() { | |
| return this.getCurrentIndex() >= this._data.count() - 1; | |
| } | |
| /** | |
| * @param {boolean} state true: play, false: stop | |
| */ | |
| setPlayState(state: boolean) { | |
| this.option.autoPlay = !!state; | |
| } | |
| /** | |
| * @return {boolean} true: play, false: stop | |
| */ | |
| getPlayState() { | |
| return !!this.option.autoPlay; | |
| } | |
| /** | |
| * @private | |
| */ | |
| _initData() { | |
| const thisOption = this.option; | |
| const dataArr = thisOption.data || []; | |
| const axisType = thisOption.axisType; | |
| const names: string[] = this._names = []; | |
| let processedDataArr: TimelineOption['data']; | |
| if (axisType === 'category') { | |
| processedDataArr = []; | |
| each(dataArr, function (item, index) { | |
| const value = convertOptionIdName(getDataItemValue(item), ''); | |
| let newItem; | |
| if (isObject(item)) { | |
| newItem = clone(item); | |
| (newItem as TimelineDataItemOption).value = index; | |
| } | |
| else { | |
| newItem = index; | |
| } | |
| processedDataArr.push(newItem); | |
| names.push(value); | |
| }); | |
| } | |
| else { | |
| processedDataArr = dataArr; | |
| } | |
| const dimType = ({ | |
| category: 'ordinal', | |
| time: 'time', | |
| value: 'number' | |
| })[axisType] || 'number'; | |
| const data = this._data = new SeriesData([{ | |
| name: 'value', type: dimType | |
| }], this); | |
| data.initData(processedDataArr, names); | |
| } | |
| getData() { | |
| return this._data; | |
| } | |
| /** | |
| * @public | |
| * @return {Array.<string>} categoreis | |
| */ | |
| getCategories() { | |
| if (this.get('axisType') === 'category') { | |
| return this._names.slice(); | |
| } | |
| } | |
| /** | |
| * @protected | |
| */ | |
| static defaultOption: TimelineOption = { | |
| // zlevel: 0, // 一级层叠 | |
| z: 4, // 二级层叠 | |
| show: true, | |
| axisType: 'time', // 模式是时间类型,支持 value, category | |
| realtime: true, | |
| left: '20%', | |
| top: null, | |
| right: '20%', | |
| bottom: 0, | |
| width: null, | |
| height: 40, | |
| padding: 5, | |
| controlPosition: 'left', // 'left' 'right' 'top' 'bottom' 'none' | |
| autoPlay: false, | |
| rewind: false, // 反向播放 | |
| loop: true, | |
| playInterval: 2000, // 播放时间间隔,单位ms | |
| currentIndex: 0, | |
| itemStyle: {}, | |
| label: { | |
| color: '#000' | |
| }, | |
| data: [] | |
| }; | |
| } | |
| export default TimelineModel; |