+
@@ -398,12 +398,11 @@ import {
type OpenOrderDisplayItem,
} from '../api/order'
import { cancelOrder as apiCancelOrder } from '../api/order'
+import type { ChartDataPoint, ChartTimeRange } from '../api/chart'
import {
- normalizeChartData,
- fetchChartHistory,
- type ChartDataPoint,
- type ChartTimeRange,
-} from '../api/chart'
+ getPmPriceHistoryPublic,
+ priceHistoryToChartData,
+} from '../api/priceHistory'
import {
isCryptoEvent as checkIsCryptoEvent,
inferCryptoSymbol,
@@ -1242,52 +1241,47 @@ const timeRanges = [
{ label: 'ALL', value: 'ALL' },
]
-// 图表数据格式:[时间戳(ms), 概率(0-100)][]。接口约定见 src/api/chart.ts(ChartHistoryParams / ChartHistoryItem / normalizeChartData)
-function generateData(range: string): ChartDataPoint[] {
- const now = Date.now()
- const data: [number, number][] = []
- let stepMs: number
- let count: number
- switch (range) {
- case '1H':
- stepMs = 60 * 1000
- count = 60
- break
- case '6H':
- stepMs = 10 * 60 * 1000
- count = 36
- break
- case '1D':
- stepMs = 60 * 60 * 1000
- count = 24
- break
- case '1W':
- stepMs = 24 * 60 * 60 * 1000
- count = 7
- break
- case '1M':
- case 'ALL':
- stepMs = 24 * 60 * 60 * 1000
- count = 30
- break
- default:
- stepMs = 60 * 60 * 1000
- count = 24
- }
- let value = 15 + Math.random() * 25
- for (let i = count; i >= 0; i--) {
- const t = now - i * stepMs
- value = Math.max(10, Math.min(90, value + (Math.random() - 0.5) * 6))
- data.push([t, Math.round(value * 10) / 10])
- }
- return data
-}
-
const chartContainerRef = ref
(null)
const data = ref<[number, number][]>([])
+/** Yes/No 折线图:接口返回的完整数据(time 已转 ms),用于分时筛选 */
+const rawChartData = ref([])
const cryptoChartLoading = ref(false)
+const chartYesNoLoading = ref(false)
let chartInstance: ECharts | null = null
-let dynamicInterval: number | undefined
+
+/** 分时范围对应的毫秒数,ALL 返回 null 表示不截断 */
+function getTimeRangeMs(range: string): number | null {
+ const H = 60 * 60 * 1000
+ const D = 24 * H
+ switch (range) {
+ case '1H':
+ return 1 * H
+ case '6H':
+ return 6 * H
+ case '1D':
+ return 1 * D
+ case '1W':
+ return 7 * D
+ case '1M':
+ return 30 * D
+ case 'ALL':
+ default:
+ return null
+ }
+}
+
+/** 按分时范围过滤 [timestamp_ms, value][],保留区间 [now - rangeMs, now] 内的点 */
+function filterChartDataByRange(
+ points: ChartDataPoint[],
+ range: string,
+): ChartDataPoint[] {
+ if (!points.length) return []
+ const rangeMs = getTimeRangeMs(range)
+ if (rangeMs == null) return points
+ const nowMs = Date.now()
+ const cutoffMs = nowMs - rangeMs
+ return points.filter(([ts]) => ts >= cutoffMs)
+}
const currentChance = computed(() => {
const ev = eventDetail.value
@@ -1523,7 +1517,7 @@ function buildOptionForCrypto(
function initChart() {
if (!chartContainerRef.value) return
- data.value = generateData(selectedTimeRange.value)
+ data.value = []
chartInstance = echarts.init(chartContainerRef.value)
const w = chartContainerRef.value.clientWidth
if (chartMode.value === 'crypto') {
@@ -1533,12 +1527,15 @@ function initChart() {
}
}
-/** 从接口拉取图表数据(接入时在 updateChartData 中调用并赋给 data.value) */
-async function loadChartFromApi(marketId: string): Promise {
- const res = await fetchChartHistory(
- { marketID: marketId, range: selectedTimeRange.value as ChartTimeRange }
- )
- return normalizeChartData(res.data ?? [])
+/** 从 GET /pmPriceHistory/getPmPriceHistoryPublic 拉取价格历史,market 传 YES 对应的 clobTokenId */
+async function loadChartFromApi(marketParam: string): Promise {
+ const res = await getPmPriceHistoryPublic({
+ market: marketParam,
+ page: 1,
+ pageSize: 500,
+ })
+ const list = res.data?.list ?? []
+ return priceHistoryToChartData(list)
}
const MINUTE_MS = 60 * 1000
@@ -1566,7 +1563,6 @@ function applyCryptoRealtimePoint(point: [number, number]) {
)
}
-// 使用接口时:在 updateChartData 内先 await loadChartFromApi(marketId),再 setOption;暂无接口时用 generateData
async function updateChartData() {
const w = chartContainerRef.value?.clientWidth
if (chartMode.value === 'crypto') {
@@ -1592,60 +1588,35 @@ async function updateChartData() {
} else {
cryptoWsUnsubscribe?.()
cryptoWsUnsubscribe = null
- data.value = generateData(selectedTimeRange.value)
- if (chartInstance)
- chartInstance.setOption(buildOption(data.value, w), { replaceMerge: ['series'] })
+ chartYesNoLoading.value = true
+ try {
+ // 价格历史接口的 market 传 clobTokenIds[0](YES 对应 token ID)
+ const yesTokenId = clobTokenIds.value[0]
+ const points = yesTokenId ? await loadChartFromApi(yesTokenId) : []
+ rawChartData.value = points
+ data.value = filterChartDataByRange(points, selectedTimeRange.value)
+ if (chartInstance)
+ chartInstance.setOption(buildOption(data.value, w), { replaceMerge: ['series'] })
+ } finally {
+ chartYesNoLoading.value = false
+ }
}
}
function selectTimeRange(range: string) {
selectedTimeRange.value = range
- updateChartData()
}
-function getMaxPoints(range: string): number {
- switch (range) {
- case '1H':
- return 60
- case '6H':
- return 36
- case '1D':
- return 24
- case '1W':
- return 7
- case '1M':
- case 'ALL':
- return 30
- default:
- return 24
- }
-}
-
-function startDynamicUpdate() {
- dynamicInterval = window.setInterval(() => {
- if (chartMode.value === 'crypto') return
- const list = [...data.value]
- const last = list[list.length - 1]
- if (!last) return
- const nextVal = Math.max(10, Math.min(90, last[1] + (Math.random() - 0.5) * 4))
- const nextT = Date.now()
- list.push([nextT, Math.round(nextVal * 10) / 10])
- const max = getMaxPoints(selectedTimeRange.value)
- data.value = list.slice(-max)
+watch(selectedTimeRange, (range) => {
+ if (chartMode.value === 'yesno') {
+ data.value = filterChartDataByRange(rawChartData.value, range)
const w = chartContainerRef.value?.clientWidth
if (chartInstance)
chartInstance.setOption(buildOption(data.value, w), { replaceMerge: ['series'] })
- }, 3000)
-}
-
-function stopDynamicUpdate() {
- if (dynamicInterval) {
- clearInterval(dynamicInterval)
- dynamicInterval = undefined
+ } else {
+ updateChartData()
}
-}
-
-watch(selectedTimeRange, () => updateChartData())
+})
// CLOB:当有 market 且存在 clobTokenIds 时连接(使用 Yes/No token ID)
const clobTokenIds = computed(() => {
@@ -1711,15 +1682,13 @@ const unsubscribePositionUpdate = userStore.onPositionUpdate((data) => {
})
onMounted(() => {
- loadEventDetail()
+ loadEventDetail().then(() => updateChartData())
initChart()
- startDynamicUpdate()
window.addEventListener('resize', handleResize)
})
onUnmounted(() => {
unsubscribePositionUpdate()
- stopDynamicUpdate()
cryptoWsUnsubscribe?.()
cryptoWsUnsubscribe = null
window.removeEventListener('resize', handleResize)