Skip to content

Commit 97a4921

Browse files
authored
Merge pull request #673 from klinecharts/feature/#663
opt: opt `customApi.formatDate`
2 parents f3aebb0 + 8a97202 commit 97a4921

File tree

12 files changed

+84
-51
lines changed

12 files changed

+84
-51
lines changed

docs/@views/api/references/chart/init.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,12 @@
4545
styles?: string | Styles
4646
timezone?: string
4747
customApi?: {
48-
formatDate?: (timestamp: number, format: string, type: number) => string
48+
formatDate?: (params: {
49+
dateTimeFormat: Intl.DateTimeFormat
50+
timestamp: number
51+
template: string
52+
type: 'tooltip' | 'crosshair' | 'xAxis'
53+
}) => string
4954
formatBigNumber?: (value: string | number) => string
5055
}
5156
thousandsSeparator?: {

docs/@views/api/references/instance/setCustomApi.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
```typescript
22
(
33
customApi: {
4-
formatDate?: (timestamp: number, format: string, type: number) => string
4+
formatDate?: (params: {
5+
dateTimeFormat: Intl.DateTimeFormat
6+
timestamp: number
7+
template: string
8+
type: 'tooltip' | 'crosshair' | 'xAxis'
9+
}) => string
510
formatBigNumber?: (value: string | number) => string
611
}
712
) => void
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,31 @@
1-
import { init } from 'klinecharts';
1+
import { init, utils } from 'klinecharts'
22

33
const chart = init(
44
'init-formatDate-chart',
55
{
66
customApi: {
7-
formatDate: (timestamp, _, type) => {
8-
const date = new Date(timestamp)
9-
const year = date.getFullYear()
10-
const month = `${date.getMonth() + 1}`.padStart(2, '0')
11-
const day = `${date.getDate()}`.padStart(2, '0')
12-
const hour = `${date.getHours()}`.padStart(2, '0')
13-
const minute = `${date.getMinutes()}`.padStart(2, '0')
7+
formatDate: ({
8+
dateTimeFormat,
9+
timestamp,
10+
type
11+
}) => {
1412
switch (type) {
15-
case 0: {
16-
return `${year}-${month}-${day} ${hour}:${minute}`
13+
case 'tooltip': {
14+
return utils.formatDate(dateTimeFormat, timestamp, 'YYYY-MM-DD HH:mm')
1715
}
18-
case 1: {
19-
return `${year}-${month}-${day}`
16+
case 'crosshair': {
17+
return utils.formatDate(dateTimeFormat, timestamp, 'YYYY-MM-DD')
2018
}
21-
case 2: {
22-
return `${month}-${day}`
19+
case 'xAxis': {
20+
return utils.formatDate(dateTimeFormat, timestamp, 'MM-DD')
2321
}
2422
}
25-
return `${month}-${day} ${hour}-${minute}`
23+
return utils.formatDate(dateTimeFormat, timestamp, 'MM-DD HH:mm')
2624
}
2725
}
2826
}
2927
)
3028

3129
fetch('https://klinecharts.com/datas/kline.json')
3230
.then(res => res.json())
33-
.then(dataList => { chart.applyNewData(dataList); });
31+
.then(dataList => { chart.applyNewData(dataList) })
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,28 @@
1-
import { init } from 'klinecharts';
1+
import { init, utils } from 'klinecharts'
22

33
const chart = init('setCustomApi-formatDate-chart')
44

55
chart.setCustomApi({
6-
formatDate: (timestamp, _, type) => {
7-
const date = new Date(timestamp)
8-
const year = date.getFullYear()
9-
const month = `${date.getMonth() + 1}`.padStart(2, '0')
10-
const day = `${date.getDate()}`.padStart(2, '0')
11-
const hour = `${date.getHours()}`.padStart(2, '0')
12-
const minute = `${date.getMinutes()}`.padStart(2, '0')
6+
formatDate: ({
7+
dateTimeFormat,
8+
timestamp,
9+
type
10+
}) => {
1311
switch (type) {
14-
case 0: {
15-
return `${year}-${month}-${day} ${hour}:${minute}`
12+
case 'tooltip': {
13+
return utils.formatDate(dateTimeFormat, timestamp, 'YYYY-MM-DD HH:mm')
1614
}
17-
case 1: {
18-
return `${year}-${month}-${day}`
15+
case 'crosshair': {
16+
return utils.formatDate(dateTimeFormat, timestamp, 'YYYY-MM-DD')
1917
}
20-
case 2: {
21-
return `${month}-${day}`
18+
case 'xAxis': {
19+
return utils.formatDate(dateTimeFormat, timestamp, 'MM-DD')
2220
}
2321
}
24-
return `${month}-${day} ${hour}-${minute}`
22+
return utils.formatDate(dateTimeFormat, timestamp, 'MM-DD HH:mm')
2523
}
2624
})
2725

2826
fetch('https://klinecharts.com/datas/kline.json')
2927
.then(res => res.json())
30-
.then(dataList => { chart.applyNewData(dataList); });
28+
.then(dataList => { chart.applyNewData(dataList) })

src/Options.ts

+11-4
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,19 @@ import type { IndicatorCreate } from './component/Indicator'
1919
import type { PaneOptions } from './pane/types'
2020

2121
export enum FormatDateType {
22-
Tooltip,
23-
Crosshair,
24-
XAxis
22+
Tooltip = 'tooltip',
23+
Crosshair = 'crosshair',
24+
XAxis = 'xAxis',
2525
}
2626

27-
export type FormatDate = (timestamp: number, format: string, type: FormatDateType) => string
27+
export interface FormatDateParams {
28+
dateTimeFormat: Intl.DateTimeFormat
29+
timestamp: number
30+
template: string
31+
type: FormatDateType
32+
}
33+
34+
export type FormatDate = (params: FormatDateParams) => string
2835

2936
export type FormatBigNumber = (value: string | number) => string
3037

src/Store.ts

+24-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
import type Nullable from './common/Nullable'
1616
import type DeepPartial from './common/DeepPartial'
17+
import type PickRequired from './common/PickRequired'
1718
import type { KLineData, VisibleRangeData } from './common/Data'
1819
import type VisibleRange from './common/VisibleRange'
1920
import type Coordinate from './common/Coordinate'
@@ -24,7 +25,7 @@ import type BarSpace from './common/BarSpace'
2425
import type Precision from './common/Precision'
2526
import Action from './common/Action'
2627
import { ActionType, type ActionCallback } from './common/Action'
27-
import { formatValue, formatTimestampToString, formatBigNumber, formatThousands, formatFoldDecimal } from './common/utils/format'
28+
import { formatValue, formatTimestampByTemplate, formatBigNumber, formatThousands, formatFoldDecimal } from './common/utils/format'
2829
import { getDefaultStyles, type TooltipFeatureStyle, type Styles, type TooltipLegend } from './common/Styles'
2930
import { isArray, isString, isValid, isNumber, isBoolean, isFunction, merge } from './common/utils/typeChecks'
3031
import { createId } from './common/utils/id'
@@ -36,7 +37,7 @@ import { type LoadDataCallback, type LoadDataParams, LoadDataType } from './comm
3637
import type TimeWeightTick from './common/TimeWeightTick'
3738
import { classifyTimeWeightTicks, createTimeWeightTickList } from './common/TimeWeightTick'
3839

39-
import type { Options, CustomApi, ThousandsSeparator, DecimalFold } from './Options'
40+
import type { Options, CustomApi, ThousandsSeparator, DecimalFold, FormatDateType, FormatDateParams, FormatBigNumber } from './Options'
4041

4142
import { IndicatorDataState, type IndicatorOverride, type IndicatorCreate, type IndicatorFilter, type Indicator } from './component/Indicator'
4243
import type IndicatorImp from './component/Indicator'
@@ -52,7 +53,6 @@ import { getStyles as getExtensionStyles } from './extension/styles/index'
5253
import { PaneIdConstants } from './pane/types'
5354

5455
import type Chart from './Chart'
55-
import type PickRequired from './common/PickRequired'
5656

5757
const BarSpaceLimitConstants = {
5858
MIN: 1,
@@ -150,10 +150,23 @@ export default class StoreImp implements Store {
150150
* Custom api
151151
*/
152152
private readonly _customApi = {
153-
formatDate: (timestamp: number, format: string) => formatTimestampToString(this._dateTimeFormat, timestamp, format),
153+
formatDate: ({
154+
dateTimeFormat,
155+
timestamp,
156+
template
157+
}: FormatDateParams) => formatTimestampByTemplate(dateTimeFormat, timestamp, template),
154158
formatBigNumber
155159
}
156160

161+
/**
162+
* Inner custom api
163+
* @description Internal use only
164+
*/
165+
private readonly _innerCustomApi = {
166+
formatDate: (timestamp: number, template: string, type: FormatDateType) => this._customApi.formatDate({ dateTimeFormat: this._dateTimeFormat, timestamp, template, type }),
167+
formatBigNumber: this._customApi.formatBigNumber
168+
}
169+
157170
/**
158171
* Locale
159172
*/
@@ -397,6 +410,13 @@ export default class StoreImp implements Store {
397410

398411
getCustomApi (): CustomApi { return this._customApi }
399412

413+
getInnerCustomApi (): {
414+
formatDate: (timestamp: number, template: string, type: FormatDateType) => string
415+
formatBigNumber: FormatBigNumber
416+
} {
417+
return this._innerCustomApi
418+
}
419+
400420
setLocale (locale: string): void { this._locale = locale }
401421

402422
getLocale (): string { return this._locale }

src/common/utils/format.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@ export function formatTimestampToDateTime (dateTimeFormat: Intl.DateTimeFormat,
9191
return date as unknown as DateTime
9292
}
9393

94-
export function formatTimestampToString (dateTimeFormat: Intl.DateTimeFormat, timestamp: number, format: string): string {
94+
export function formatTimestampByTemplate (dateTimeFormat: Intl.DateTimeFormat, timestamp: number, template: string): string {
9595
const date = formatTimestampToDateTime(dateTimeFormat, timestamp)
9696
// eslint-disable-next-line @typescript-eslint/no-unsafe-return -- ignore
97-
return format.replace(/YYYY|MM|DD|HH|mm|ss/g, key => date[key])
97+
return template.replace(/YYYY|MM|DD|HH|mm|ss/g, key => date[key])
9898
}
9999

100100
export function formatPrecision (value: string | number, precision?: number): string {

src/component/XAxis.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export default abstract class XAxisImp extends AxisImp implements XAxis {
7676
protected override createTicksImp (): AxisTick[] {
7777
const { realFrom, realTo } = this.getRange()
7878
const chartStore = this.getParent().getChart().getChartStore()
79-
const formatDate = chartStore.getCustomApi().formatDate
79+
const formatDate = chartStore.getInnerCustomApi().formatDate
8080
const timeWeightTickList = chartStore.getTimeWeightTickList()
8181
const ticks: AxisTick[] = []
8282

src/index.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ import {
3939
formatValue,
4040
formatPrecision,
4141
formatBigNumber,
42-
formatTimestampToString,
4342
formatThousands,
44-
formatFoldDecimal
43+
formatFoldDecimal,
44+
formatTimestampByTemplate
4545
} from './common/utils/format'
4646
import { calcTextWidth } from './common/utils/canvas'
4747
import { ActionType } from './common/Action'
@@ -149,7 +149,7 @@ const utils = {
149149
formatValue,
150150
formatPrecision,
151151
formatBigNumber,
152-
formatDate: formatTimestampToString,
152+
formatDate: formatTimestampByTemplate,
153153
formatThousands,
154154
formatFoldDecimal,
155155
calcTextWidth,

src/view/CandleTooltipView.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ export default class CandleTooltipView extends IndicatorTooltipView {
363363
const chartStore = this.getWidget().getPane().getChart().getChartStore()
364364
const styles = chartStore.getStyles().candle
365365
const dataList = chartStore.getDataList()
366-
const customApi = chartStore.getCustomApi()
366+
const customApi = chartStore.getInnerCustomApi()
367367
const decimalFold = chartStore.getDecimalFold()
368368
const thousandsSeparator = chartStore.getThousandsSeparator()
369369
const locale = chartStore.getLocale()

src/view/CrosshairVerticalLabelView.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export default class CrosshairVerticalLabelView extends CrosshairHorizontalLabel
3838

3939
override getText (crosshair: Crosshair, chartStore: ChartStore): string {
4040
const timestamp = crosshair.timestamp!
41-
return chartStore.getCustomApi().formatDate(timestamp, 'YYYY-MM-DD HH:mm', FormatDateType.Crosshair)
41+
return chartStore.getInnerCustomApi().formatDate(timestamp, 'YYYY-MM-DD HH:mm', FormatDateType.Crosshair)
4242
}
4343

4444
override getTextAttrs (text: string, textWidth: number, crosshair: Crosshair, bounding: Bounding, _axis: Axis, styles: StateTextStyle): TextAttrs {

src/view/OverlayXAxisView.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export default class OverlayXAxisView extends OverlayYAxisView<XAxis> {
6060
rightX = Math.max(rightX, coordinate.x)
6161
const point = overlay.points[index]
6262
if (isNumber(point.timestamp)) {
63-
const text = chartStore.getCustomApi().formatDate(point.timestamp, 'YYYY-MM-DD HH:mm', FormatDateType.Crosshair)
63+
const text = chartStore.getInnerCustomApi().formatDate(point.timestamp, 'YYYY-MM-DD HH:mm', FormatDateType.Crosshair)
6464
figures.push({ type: 'text', attrs: { x: coordinate.x, y: 0, text, align: 'center' }, ignoreEvent: true })
6565
}
6666
})

0 commit comments

Comments
 (0)