Skip to content

Commit 650dd04

Browse files
feat : Dynamic ApexCharts axes, Handle Missing Values (broken lines)
1 parent 864879c commit 650dd04

1 file changed

Lines changed: 62 additions & 18 deletions

File tree

client/components/MainChart.vue

Lines changed: 62 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,31 @@ const modelsWithValues = computed(() => {
8181
// - account_value = current_balance (includes realized PnL) + unrealized PnL from open positions
8282
// - Includes both realized PnL from closed positions (via total_pnl) and unrealized PnL from open positions
8383
const chartSeries = computed(() => {
84+
// Detect gaps in the data
85+
const timestamps = props.accountValues.map(av => av.timestamp.getTime())
86+
const MIN_GAP = 60 * 60 * 1000 // 1 hour threshold
87+
8488
return props.models.map(model => {
85-
const data = props.accountValues.map(av => ({
86-
x: av.timestamp.getTime(),
87-
// y is the total account value at this timestamp
88-
// This includes: initial_balance + realized PnL (from total_pnl) + unrealized PnL (from open positions)
89-
y: av.models[model.id] || 10000
90-
}))
89+
const data: Array<{ x: number; y: number | null }> = []
90+
91+
props.accountValues.forEach((av, index) => {
92+
// Check if there's a large gap from previous point
93+
if (index > 0) {
94+
const prevTimestamp = timestamps[index - 1]
95+
const currentTimestamp = timestamps[index]
96+
const gap = currentTimestamp - prevTimestamp
97+
98+
if (gap > MIN_GAP) {
99+
// Insert a null point to break the line
100+
data.push({ x: index, y: null })
101+
}
102+
}
103+
104+
data.push({
105+
x: index,
106+
y: av.models[model.id] ?? null,
107+
})
108+
})
91109
92110
return {
93111
name: model.name,
@@ -98,15 +116,20 @@ const chartSeries = computed(() => {
98116
})
99117
})
100118
119+
// Generate category labels for x-axis
120+
const xAxisCategories = computed(() => {
121+
return props.accountValues.map(av => av.timestamp.getTime())
122+
})
123+
101124
// Chart options
102125
const chartOptions = computed(() => {
103126
104127
const allValues = props.accountValues.flatMap(av =>
105128
Object.values(av.models)
106129
)
107-
// const maxValue = allValues.length > 0 ? Math.max(...allValues) : 15000
108-
// const yAxisMax = Math.max(15000, Math.ceil(maxValue / 5000) * 5000)
109-
// const yAxisMin = 5000
130+
const maxValue = allValues.length > 0 ? Math.max(...allValues) : 15000
131+
const yAxisMax = Math.max(15000, Math.ceil(maxValue / 2500) * 2500)
132+
const yAxisMin = Math.floor(Math.min(...allValues) / 2500) * 2500
110133
111134
return {
112135
chart: {
@@ -153,15 +176,28 @@ const chartOptions = computed(() => {
153176
},
154177
},
155178
xaxis: {
156-
type: 'datetime',
179+
type: 'category',
180+
tickAmount: 7,
181+
categories: xAxisCategories.value,
157182
labels: {
158183
style: {
159184
colors: '#000000',
160185
fontSize: '10px',
161186
fontWeight: 600,
162187
fontFamily: 'Space Mono, monospace',
163188
},
164-
format: 'MMM dd HH:mm',
189+
formatter: (val: string) => {
190+
const date = new Date(parseInt(val))
191+
if (isNaN(date.getTime())) return ''
192+
193+
return date.toLocaleString('en-US', {
194+
month: 'short',
195+
day: '2-digit',
196+
hour: '2-digit',
197+
minute: '2-digit',
198+
hour12: false
199+
})
200+
},
165201
},
166202
axisBorder: {
167203
show: true,
@@ -174,12 +210,9 @@ const chartOptions = computed(() => {
174210
},
175211
},
176212
yaxis: {
177-
// min: yAxisMin,
178-
// max: yAxisMax,
179-
// tickAmount: Math.ceil((yAxisMax - yAxisMin) / 5000),
180-
min: 6000,
181-
max: 16000,
182-
tickAmount: 5,
213+
min: yAxisMin,
214+
max: yAxisMax,
215+
tickAmount: Math.ceil((yAxisMax - yAxisMin) / 2500),
183216
labels: {
184217
style: {
185218
colors: '#000000',
@@ -236,7 +269,18 @@ const chartOptions = computed(() => {
236269
fontSize: '11px',
237270
},
238271
x: {
239-
format: 'MMM dd, yyyy HH:mm',
272+
formatter: (val: number, opts: any) => {
273+
const timestamp = xAxisCategories.value[val]
274+
const date = new Date(timestamp)
275+
return date.toLocaleString('en-US', {
276+
month: 'short',
277+
day: '2-digit',
278+
year: 'numeric',
279+
hour: '2-digit',
280+
minute: '2-digit',
281+
hour12: false
282+
})
283+
},
240284
},
241285
y: {
242286
formatter: (val: number) => `$${formatNumber(val)}`,

0 commit comments

Comments
 (0)