| /* |
| * 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 List from '../../data/List'; |
| 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: List<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 List([{ |
| 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; |