feat: indicator add onDataStausChange

This commit is contained in:
liihuu 2024-09-04 01:06:32 +08:00
parent 5be280359d
commit 5fe227fcc4
7 changed files with 56 additions and 30 deletions

View File

@ -22,7 +22,7 @@ import { UpdateLevel } from './common/Updater'
import { type Styles } from './common/Styles'
import type Crosshair from './common/Crosshair'
import { ActionType, type ActionCallback } from './common/Action'
import type LoadDataCallback from './common/LoadDataCallback'
import { type LoadDataCallback } from './common/LoadDataCallback'
import type Precision from './common/Precision'
import type VisibleRange from './common/VisibleRange'
import { type CustomApi, LayoutChildType, type Options } from './Options'
@ -669,7 +669,7 @@ export default class ChartImp implements Chart {
}
updateData (data: KLineData): void {
this._chartStore.addData(data)
this._chartStore.addData(data, LoadDataType.Update)
}
setLoadDataCallback (cb: LoadDataCallback): void {

View File

@ -17,7 +17,6 @@ import { isFunction } from './utils/typeChecks'
export type ActionCallback = (data?: any) => void
export enum ActionType {
OnDataReady = 'onDataReady',
OnZoom = 'onZoom',
OnScroll = 'onScroll',
OnVisibleRangeChange = 'onVisibleRangeChange',

View File

@ -15,20 +15,17 @@
import type Nullable from './Nullable'
import { type KLineData } from './Data'
enum LoadDataType {
export enum LoadDataType {
Init = 'init',
Forward = 'forward',
Backward = 'backward'
Backward = 'backward',
Update = 'update'
}
interface LoadDataParams {
export interface LoadDataParams {
type: LoadDataType
data: Nullable<KLineData>
callback: (dataList: KLineData[], more?: boolean) => void
}
export { LoadDataType, type LoadDataParams }
type LoadDataCallback = (params: LoadDataParams) => void
export default LoadDataCallback
export type LoadDataCallback = (params: LoadDataParams) => void

View File

@ -30,6 +30,7 @@ import { formatValue } from '../common/utils/format'
import { type ArcAttrs } from '../extension/figure/arc'
import { type RectAttrs } from '../extension/figure/rect'
import { type TextAttrs } from '../extension/figure/text'
import { type LoadDataType } from '../common/LoadDataCallback'
export enum IndicatorSeries {
Normal = 'normal',
@ -117,6 +118,19 @@ export type IndicatorDrawCallback<D> = (params: IndicatorDrawParams<D>) => boole
export type IndicatorCalcCallback<D> = (dataList: KLineData[], indicator: Indicator<D>) => Promise<D[]> | D[]
export type IndicatorShouldUpdateCallback<D> = (prev: Indicator<D>, current: Indicator<D>) => (boolean | { calc: boolean, draw: boolean })
export enum IndicatorDataStatus {
Loading = 'loading',
Error = 'error',
Ready = 'ready'
}
export interface IndicatorOnDataStatusChangeParams<D> {
status: IndicatorDataStatus
type: LoadDataType
indicator: Indicator<D>
}
export type IndicatorOnDataStatusChangeCallback<D> = (params: IndicatorOnDataStatusChangeParams<D>) => void
export interface Indicator<D = any> {
/**
* Indicator name
@ -213,6 +227,11 @@ export interface Indicator<D = any> {
*/
draw: Nullable<IndicatorDrawCallback<D>>
/**
* Data status change
*/
onDataStatusChange: Nullable<IndicatorOnDataStatusChangeCallback<D>>
/**
* Calculation result
*/
@ -333,6 +352,9 @@ export default class IndicatorImp<D = any> implements Indicator<D> {
regenerateFigures: Nullable<IndicatorRegenerateFiguresCallback<D>> = null
createTooltipDataSource: Nullable<IndicatorCreateTooltipDataSourceCallback<D>> = null
draw: Nullable<IndicatorDrawCallback<D>> = null
onDataStatusChange: Nullable<IndicatorOnDataStatusChangeCallback<D>> = null
result: D[] = []
private _prevIndicator: Indicator<D>

View File

@ -32,12 +32,6 @@ export default class ActionStore {
this._actions.get(type)?.subscribe(callback)
}
/**
*
* @param type
* @param callback
* @return {boolean}
*/
unsubscribe (type: ActionType, callback?: ActionCallback): void {
const action = this._actions.get(type)
if (isValid(action)) {

View File

@ -19,9 +19,7 @@ import type DeepPartial from '../common/DeepPartial'
import { formatValue } from '../common/utils/format'
import { getDefaultStyles, type Styles, type TooltipLegend } from '../common/Styles'
import { isArray, isNumber, isString, isValid, merge } from '../common/utils/typeChecks'
import type LoadDataCallback from '../common/LoadDataCallback'
import { type LoadDataParams, LoadDataType } from '../common/LoadDataCallback'
import { ActionType } from '../common/Action'
import { type LoadDataCallback, type LoadDataParams, LoadDataType } from '../common/LoadDataCallback'
import { getDefaultCustomApi, type CustomApi, defaultLocale, type Options } from '../Options'
@ -224,7 +222,7 @@ export default class ChartStore {
return this._visibleDataList
}
addData (data: KLineData | KLineData[], type?: LoadDataType, more?: boolean): void {
addData (data: KLineData | KLineData[], type: LoadDataType, more?: boolean): void {
let success = false
let adjustFlag = false
let dataLengthChange = 0
@ -282,10 +280,9 @@ export default class ChartStore {
if (adjustFlag) {
this._timeScaleStore.adjustVisibleRange()
this._tooltipStore.recalculateCrosshair(true)
this._indicatorStore.calcInstance({})
this._indicatorStore.calcInstance(type, {})
this._chart.adjustPaneViewport(false, true, true, true)
}
this._actionStore.execute(ActionType.OnDataReady)
}
}

View File

@ -16,11 +16,12 @@ import { isValid, isString } from '../common/utils/typeChecks'
import type ChartStore from './ChartStore'
import { type IndicatorCreate, type IndicatorFilter } from '../component/Indicator'
import { IndicatorDataStatus, type IndicatorCreate, type IndicatorFilter } from '../component/Indicator'
import type IndicatorImp from '../component/Indicator'
import { IndicatorSeries } from '../component/Indicator'
import { getIndicatorClass } from '../extension/indicator/index'
import TaskScheduler, { generateTaskId } from '../common/TaskScheduler'
import { LoadDataType } from '../common/LoadDataCallback'
export default class IndicatorStore {
private readonly _chartStore: ChartStore
@ -42,15 +43,31 @@ export default class IndicatorStore {
}
}
private _addTask (paneId: string, indicator: IndicatorImp): void {
private _addTask (paneId: string, indicator: IndicatorImp, loadDataType: LoadDataType): void {
this._scheduler.addTask({
id: generateTaskId(paneId, indicator.name),
handler: () => {
indicator.onDataStatusChange?.({
status: IndicatorDataStatus.Loading,
type: loadDataType,
indicator
})
indicator.calcImp(this._chartStore.getDataList()).then(result => {
if (result) {
this._chartStore.getChart().adjustPaneViewport(false, true, true, true)
indicator.onDataStatusChange?.({
status: IndicatorDataStatus.Ready,
type: loadDataType,
indicator
})
}
}).catch(() => {})
}).catch(() => {
indicator.onDataStatusChange?.({
status: IndicatorDataStatus.Error,
type: loadDataType,
indicator
})
})
}
})
}
@ -79,7 +96,7 @@ export default class IndicatorStore {
paneInstances.push(instance)
this._instances.set(paneId, paneInstances)
this._sort(paneId)
this._addTask(paneId, instance)
this._addTask(paneId, instance, LoadDataType.Init)
return true
}
@ -137,11 +154,11 @@ export default class IndicatorStore {
return this._instances.has(paneId)
}
calcInstance (filter: IndicatorFilter): void {
calcInstance (loadDataType: LoadDataType, filter: IndicatorFilter): void {
const filterMap = this.getInstanceByFilter(filter)
filterMap.forEach((indicators, paneId) => {
indicators.forEach(indicator => {
this._addTask(paneId, indicator)
this._addTask(paneId, indicator, loadDataType)
})
})
}
@ -195,7 +212,7 @@ export default class IndicatorStore {
sortFlag = true
}
if (calc) {
this._addTask(paneId, instance)
this._addTask(paneId, instance, LoadDataType.Update)
} else {
if (draw) {
updateFlag = true