feat: 新增热点穿透网状关系图 + 移动端优化

- 新增 /hot-map 热点穿透页:d3-force 力导向网状图展示题材-股票 M:N 关系
  - 股票节点面积/颜色按覆盖题材数分级,穿透核心股高亮
  - 图/核心股列表双视图切换,列表覆盖题材>2 公司降序展示
  - 悬停信息卡、缩放平移、点击跳转股票/题材详情
- 数据采样改为涨幅+热度双榜合并(各 Top50 去重=82 题材),修复覆盖数低估
  (有研新材覆盖数 2→10,核心股 66→1124 家)
- 移动端适配:触屏 tap 选中底部浮层、标签缩放阈值防重叠、自动 fit、紧凑图例
- 主页/题材列表增加热点穿透入口

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Sakurasan
2026-08-06 20:34:14 +08:00
co-authored by Claude
parent 45836f4a30
commit e28d1a2fd0
9 changed files with 1209 additions and 206 deletions
+21
View File
@@ -11,6 +11,7 @@
import { Route as rootRouteImport } from './routes/__root'
import { Route as ThemesRouteImport } from './routes/themes'
import { Route as SectorsRouteImport } from './routes/sectors'
import { Route as HotMapRouteImport } from './routes/hot-map'
import { Route as IndexRouteImport } from './routes/index'
import { Route as ThemeCodeRouteImport } from './routes/theme.$code'
import { Route as StockCodeRouteImport } from './routes/stock.$code'
@@ -26,6 +27,11 @@ const SectorsRoute = SectorsRouteImport.update({
path: '/sectors',
getParentRoute: () => rootRouteImport,
} as any)
const HotMapRoute = HotMapRouteImport.update({
id: '/hot-map',
path: '/hot-map',
getParentRoute: () => rootRouteImport,
} as any)
const IndexRoute = IndexRouteImport.update({
id: '/',
path: '/',
@@ -49,6 +55,7 @@ const ShareCodeRoute = ShareCodeRouteImport.update({
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/hot-map': typeof HotMapRoute
'/sectors': typeof SectorsRoute
'/themes': typeof ThemesRoute
'/share/$code': typeof ShareCodeRoute
@@ -57,6 +64,7 @@ export interface FileRoutesByFullPath {
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/hot-map': typeof HotMapRoute
'/sectors': typeof SectorsRoute
'/themes': typeof ThemesRoute
'/share/$code': typeof ShareCodeRoute
@@ -66,6 +74,7 @@ export interface FileRoutesByTo {
export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
'/hot-map': typeof HotMapRoute
'/sectors': typeof SectorsRoute
'/themes': typeof ThemesRoute
'/share/$code': typeof ShareCodeRoute
@@ -76,6 +85,7 @@ export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths:
| '/'
| '/hot-map'
| '/sectors'
| '/themes'
| '/share/$code'
@@ -84,6 +94,7 @@ export interface FileRouteTypes {
fileRoutesByTo: FileRoutesByTo
to:
| '/'
| '/hot-map'
| '/sectors'
| '/themes'
| '/share/$code'
@@ -92,6 +103,7 @@ export interface FileRouteTypes {
id:
| '__root__'
| '/'
| '/hot-map'
| '/sectors'
| '/themes'
| '/share/$code'
@@ -101,6 +113,7 @@ export interface FileRouteTypes {
}
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
HotMapRoute: typeof HotMapRoute
SectorsRoute: typeof SectorsRoute
ThemesRoute: typeof ThemesRoute
ShareCodeRoute: typeof ShareCodeRoute
@@ -124,6 +137,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof SectorsRouteImport
parentRoute: typeof rootRouteImport
}
'/hot-map': {
id: '/hot-map'
path: '/hot-map'
fullPath: '/hot-map'
preLoaderRoute: typeof HotMapRouteImport
parentRoute: typeof rootRouteImport
}
'/': {
id: '/'
path: '/'
@@ -157,6 +177,7 @@ declare module '@tanstack/react-router' {
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
HotMapRoute: HotMapRoute,
SectorsRoute: SectorsRoute,
ThemesRoute: ThemesRoute,
ShareCodeRoute: ShareCodeRoute,