/* * @Author: ZhaoYing * @Date: 2026-02-03 18:32:53 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-04-13 13:37:43 */ import { useEffect, useState, forwardRef, useImperativeHandle, useRef } from 'react' import { useTranslation } from 'react-i18next' import { useParams } from 'react-router-dom' import { Skeleton } from 'antd'; import ReactEcharts from 'echarts-for-react'; import { getImplicitInterestAreas, } from '@/api/memory' /** Default color palette for area line series */ const Colors = ['#9C6FFF', '#FFB048', '#4DA8FF', '#369F21'] const keys = ['art', 'music', 'tech', 'lifestyle'] as const /** * Interest category item structure * @property {string} category_name - Category name * @property {number} percentage - Interest percentage * @property {string[]} evidence - Supporting evidence * @property {string | null} trending_direction - Trending direction */ interface Item { category_name: string; percentage: number; evidence: string[]; trending_direction: string | null; } /** * Interest areas data structure * @property {string} user_id - User ID * @property {number | string} analysis_timestamp - Analysis timestamp * @property {number} total_summaries_analyzed - Total summaries analyzed * @property {Item} tech - Technology interest * @property {Item} lifestyle - Lifestyle interest * @property {Item} music - Music interest * @property {Item} art - Art interest */ interface InterestAreasItem { user_id: string; analysis_timestamp: number | string; total_summaries_analyzed: number; tech: Item; lifestyle: Item; music: Item; art: Item; } /** * InterestAreas Component * Displays user interest distribution across different categories * Shows percentage breakdown for art, music, tech, and lifestyle */ const InterestAreas = forwardRef<{ handleRefresh: () => void; }>((_props, ref) => { const { t } = useTranslation() const { id } = useParams() const [loading, setLoading] = useState(false) const [data, setData] = useState({} as InterestAreasItem) const chartRef = useRef(null) useEffect(() => { if (!id) return getData() }, [id]) const getData = () => { if (!id) return setLoading(true) getImplicitInterestAreas(id).then((res) => { const response = res as InterestAreasItem setData(response) setLoading(false) }) .finally(() => { setLoading(false) }) } useImperativeHandle(ref, () => ({ handleRefresh: getData })); return (
{t('implicitDetail.interestAreas')}
{loading ? : t(`implicitDetail.${k}`)), axisLabel: { color: '#5B6167', fontSize: 12, fontFamily: 'PingFangSC, PingFang SC', interval: 0, overflow: 'break-word', width: 60 }, axisLine: { lineStyle: { color: '#EBEBEB' } }, axisTick: { show: false }, }, yAxis: { type: 'value', min: 0, max: 100, axisLabel: { color: '#A8A9AA', fontSize: 12, fontFamily: 'PingFangSC, PingFang SC', formatter: '{value}%' }, splitLine: { lineStyle: { color: '#EBEBEB' } }, }, series: [{ type: 'bar', barMaxWidth: 40, borderRadius: [4, 4, 0, 0], data: keys.map((k, i) => ({ value: data[k]?.percentage ?? 0, itemStyle: { color: Colors[i] } })), label: { show: true, position: 'top', formatter: '{c}%', color: '#5B6167', fontSize: 10 }, }] }} style={{ height: '200px', width: '100%' }} notMerge={true} lazyUpdate={true} /> }
) }) export default InterestAreas