Merge #1 into develop from web

update web
This commit is contained in:
赵莹
2025-12-15 07:16:19 +00:00
parent a4e276ab27
commit ea0a445d5b
65 changed files with 842 additions and 408 deletions

View File

@@ -1,4 +1,4 @@
import { type FC, useRef, useEffect, useState } from 'react'
import { type FC, useRef, useEffect, useState, useMemo, useCallback } from 'react'
import { useTranslation } from 'react-i18next'
import ReactEcharts from 'echarts-for-react';
import type { ConfigForm } from '../types'
@@ -30,6 +30,7 @@ const LineChart: FC<LineCardProps> = ({ config }) => {
const { t } = useTranslation()
const chartRef = useRef<ReactEcharts>(null);
const debounceRef = useRef()
const resizeScheduledRef = useRef(false)
const xAxisData = [1, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60]
const [initialData, setInitialData] = useState([])
const [currentData, setCurrentData] = useState({
@@ -38,7 +39,7 @@ const LineChart: FC<LineCardProps> = ({ config }) => {
data: [],
config: {}
})
const seriesData = [
const seriesData = useMemo(() => [
{
...SeriesConfig,
name: `${t('forgettingEngine.quicklyForget')}(λ_time=0.3)`,
@@ -51,56 +52,77 @@ const LineChart: FC<LineCardProps> = ({ config }) => {
data: [],
config: {lambda_mem: 1, lambda_time: 0.3, offset: 0.2}
}
]
], [t])
useEffect(() => {
getInitData()
}, [])
useEffect(() => {
const handleResize = () => {
if (chartRef.current && !resizeScheduledRef.current) {
resizeScheduledRef.current = true
requestAnimationFrame(() => {
chartRef.current?.getEchartsInstance().resize();
resizeScheduledRef.current = false
});
}
}
const resizeObserver = new ResizeObserver(handleResize)
const chartElement = chartRef.current?.getEchartsInstance().getDom().parentElement
if (chartElement) {
resizeObserver.observe(chartElement)
}
return () => {
resizeObserver.disconnect()
}
}, [initialData])
useEffect(() => {
if (config) {
clearTimeout(debounceRef.current)
debounceRef.current = setTimeout(() => {
getCaculateData(config)
}, 500)
}, 300)
}
return () => {
console.log('clearTimeout')
clearTimeout(debounceRef.current)
}
}, [config])
// 快速遗忘lambda_mem=0.3lambda_time=1offset=0.05
// 慢速遗忘lambda_mem=1lambda_time=0.3offset=0.2
const getInitData = () => {
const getInitData = useCallback(() => {
const list = seriesData.map(item => ({
...item,
data: formatData(item.config)
}))
setInitialData(list)
}
}, [seriesData])
const calculateSeriesData = (days: number, data: ConfigForm) => {
const { offset, lambda_time, lambda_mem } = data;
const S = 1
const calculateSeriesData = useCallback((days: number, data: ConfigForm) => {
const offset = Number(data.offset)
const lambda_time = Number(data.lambda_time)
const lambda_mem = Number(data.lambda_mem)
// R = offset + (1 - offset) × e^(-λtime × t / (λmem × S))
return (Number(offset) + (1 - Number(offset)) * Math.exp(-Number(lambda_time) * days / (Number(lambda_mem) * S))).toFixed(4)
}
const formatData = (data: ConfigForm) => {
return +(offset + (1 - offset) * Math.exp(-lambda_time * days / lambda_mem)).toFixed(4)
}, [])
const formatData = useCallback((data: ConfigForm) => {
return xAxisData.map(days => Number(calculateSeriesData(days, data)))
}
}, [calculateSeriesData])
const getCaculateData = (data: ConfigForm) => {
const getCaculateData = useCallback((data: ConfigForm) => {
if (!data) {
return
}
console.log('getCaculateData', data)
setCurrentData({
...currentData,
setCurrentData(prev => ({
...prev,
config: data,
name: `${t('forgettingEngine.currentConfig')}(λ_time=${data.lambda_time})`,
data: xAxisData.map(days => Number(calculateSeriesData(days, data)))
})
}
}))
}, [t, calculateSeriesData])
return (
<>
@@ -175,17 +197,6 @@ const LineChart: FC<LineCardProps> = ({ config }) => {
opts={{ renderer: 'canvas' }}
notMerge={true}
lazyUpdate={true}
onEvents={{
// 图表渲染完成后再次调整大小,确保宽度正确
// 使用 setTimeout 避免在主渲染过程中调用 resize
rendered: () => {
if (chartRef.current) {
setTimeout(() => {
chartRef.current?.getEchartsInstance().resize();
}, 0);
}
}
}}
/>
)}
</>

View File

@@ -39,10 +39,12 @@ export interface CurveRecord {
}
export interface ConfigForm {
config_id?: string;
statement_granularity?: string;
include_dialogue_context?: boolean;
max_context?: string;
lambda_time: string | number;
lambda_mem: string | number;
offset: string | number;
[key: string]: any;
}