Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
I
integrity_practice_management_new
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
David Yang
integrity_practice_management_new
Commits
05865f2c
Commit
05865f2c
authored
Sep 08, 2026
by
Andy-bubu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: add dedicated pie chart palette
parent
ac1721ba
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
356 additions
and
16 deletions
+356
-16
ui-architecture.md
docs/ui-architecture.md
+4
-0
ui-migration-checklist.md
docs/ui-migration-checklist.md
+2
-0
xinyuan-design-system.md
docs/xinyuan-design-system.md
+5
-2
xinyuan-ui-audit.md
docs/xinyuan-ui-audit.md
+2
-0
XinyuanEChart.jsx
src/components/XinyuanEChart.jsx
+129
-0
chartPalette.js
src/design-system/chartPalette.js
+158
-0
theme.css
src/design-system/theme.css
+18
-0
tokens.css
src/design-system/tokens.css
+17
-0
index.jsx
src/pages/problem_rectification/dashboard/index.jsx
+21
-14
No files found.
docs/ui-architecture.md
View file @
05865f2c
...
...
@@ -21,6 +21,8 @@ app.js (固定浅色主题初始化)
-
`src/config/application.js`
:稳定
`APPLICATION_NAME`
、展示名和 base;路由、应用切换与授权判断从同一应用标识派生。
-
`src/design-system/`
:权威主题、Tokens 和跨应用 Shell 样式;页面不得复制这些规则。
-
`src/design-system/chartPalette.js`
:只为 Pie/Donut 解析独立
`--rc-pie-chart-*`
Token,并按完整稳定分类 key 域确定性消解 16 色内的冲突;不替代普通图表
`chartTokens.js`
。
-
`src/components/XinyuanEChart.jsx`
:业务中立的 ECharts 边界,仅对
`series.type === 'pie'`
注入专用扇区色、同色引导线、间隙和圆角,同时保留 radius、center、label、legend、tooltip、事件、ARIA、resize 与键盘焦点;非 Pie series 不改色。
-
`AppShell/DashboardSidebar/DashboardNavbar/ApplicationSwitcherDialog`
:业务无关的共享壳层。
-
`ApplicationSwitcherDialog`
从既有
`SiteContext.site.group`
读取动态分组,从
`GET /application/info`
与
`UserContext.applications`
合并真实可访问应用;分组仅影响呈现,不改变路由、会话或跳转。
-
`SubjectWorkbench`
:把现有 Subject/View/动作配置适配为工作台 props,不定义组件外观。
...
...
@@ -45,6 +47,8 @@ Grid View 的 `viewAuth` 在查询前过滤;没有可访问 View 时数据链
根主题固定为
`light`
,内容画布保持浅色,Sidebar 通过独立 Token 保持深色;Portal 跟随内容区主题。应用切换数据来自真实 application info;登出调用现有 logout API 后清理登录态并回到 base-aware 登录路径。
Pie/Donut 是普通图表色板之外的独立例外:前六个
`--xinyuan-pie-chart-*`
为品牌红、灰蓝、灰紫、暖金、暖棕、石板灰,扩展色保持低饱和且无绿色。适配器覆盖页面旧扇区颜色,并让 ECharts 的 Legend/Tooltip 标记跟随数据项视觉色;普通 Bar/Line/Ranking、KPI、HeroUI Primary 与页面 Surface 不读取该色板。
## 历史源码隔离
`.umirc.ts`
只挂载 Login、Layout 和七个 SubjectWorkbench 路由。
`src/pages/problem_rectification`
、
`src/catalyst-ui-kit`
与 demo services 是仓库历史源码,不属于当前运行图。审计必须分别报告“活动路由扫描”和“全仓扫描”,不能用历史命中否定活动迁移,也不能宣称全仓已清零。
...
...
docs/ui-migration-checklist.md
View file @
05865f2c
...
...
@@ -23,6 +23,7 @@
-
[
x
]
新增记录 Modal:4xl 居中弹窗、blur Backdrop、标准关闭按钮、可滚动 Body、两列动态表单和次级/主操作层级
-
[
x
]
Select、Autocomplete、DatePicker、DropZone 直接 compound API
-
[
x
]
活动路由 KPI/图表判定为不适用
-
[
x
]
Pie/Donut 独立 16 色 Token 与共享 ECharts 适配器已按问题整改基准预置;活动路由无真实饼图,未制造页面或业务数据
-
[
x
]
Grid
`shortTitle`
严格布尔隐藏标题展示列,标题数据与查询协议保留
-
[
x
]
Detail
`shortTitle`
随活动详情 View 隐藏记录标题与 title 字段
-
[
x
]
View/字段授权只读取
`integrity_practice_management`
应用项;零 View 不查询、不展示操作,单 View 隐藏 Tabs
...
...
@@ -76,6 +77,7 @@
-
[
]
全仓旧组件扫描为零:未完成。未挂载历史
`src/pages/problem_rectification`
与
`src/catalyst-ui-kit`
仍保留,且不进入当前应用路由。
-
[
]
KPI/图表 Tooltip 页面验收:不适用。七条活动路由没有这些业务模块,未伪造数据或页面。
-
[
]
Pie/Donut 真实数据像素验收:待活动业务提供真实图表后验证 2/3/4/6/6+ 分类、Tooltip、Legend 与筛选/排序稳定性;当前仅完成共享映射自动检查和无业务页面回归。
-
[
]
五项功能全部真实线上失败/重试矩阵:未完成。当前列表、详情和通知接口可用,但没有制造材料部分成功、业务保存失败或通知 1/99/100 的业务数据;不得以浏览器夹具替代真实线上状态验收。
## 2026-08-26 五项功能追加验收
...
...
docs/xinyuan-design-system.md
View file @
05865f2c
...
...
@@ -16,7 +16,10 @@ Inter 禁止通过 `src/tailwind.css` 导入。Tailwind v4 内容扫描必须排
## 品牌与图表色板
-
鑫元品牌主色固定为
`#DA241A`
。HeroUI v3 的
`--accent`
、
`--accent-hover`
、
`--focus`
以及共享
`--rc-brand-primary`
均不得被页面或深色主题改写为其他色相;primary 色阶仅作为兼容别名维护。
-
图表统一使用
`--rc-chart-1`
至
`--rc-chart-16`
,由
`src/design-system/chartTokens.js`
提供 ECharts 的解析值。顺序为品牌红、低饱和暖色、灰紫中性色和蓝灰色,禁止绿色、荧光色和彩虹式相邻对撞;单系列始终使用
`chart-1`
。
-
普通 Bar / Line / Ranking 图表继续使用
`--xinyuan-chart-1`
至
`--xinyuan-chart-16`
及其
`--rc-chart-*`
别名,现有值、顺序和语义映射保持不变;单系列始终使用
`chart-1`
。
-
Pie / Donut 独立使用
`--xinyuan-pie-chart-1`
至
`--xinyuan-pie-chart-16`
及其
`--rc-pie-chart-*`
别名。前六色固定为
`#DA241A`
、
`#3F5F86`
、
`#8A668F`
、
`#C28A3D`
、
`#8A6253`
、
`#667080`
;后续仅使用批准的低饱和灰蓝、灰紫、暖棕和暖灰,不得出现绿色、青绿色、荧光色或彩虹序列。
-
Pie / Donut 必须通过
`XinyuanEChart`
和
`createResolvedXinyuanPieChartColorMap()`
按稳定分类 key 确定性分配颜色,同图 16 类以内冲突消解且不重复。筛选、排序、Tab 或主题切换不得按当前数组下标重新定义分类颜色;扇区、引导线、Legend 和 Tooltip 圆点使用同一视觉色。
-
饼图专用色板不影响 HeroUI 主色、KPI 或普通图表;未来新增饼图/环形图禁止在页面写
`color`
、扇区
`itemStyle.color`
或统一灰色
`labelLine.lineStyle.color`
。
-
KPI 图标色调复用同一图表色板的暖色/灰紫/蓝灰衍生值,卡片表面保持中性,不以高饱和渐变区分指标。
## 组件合同
...
...
@@ -38,7 +41,7 @@ Inter 禁止通过 `src/tailwind.css` 导入。Tailwind v4 内容扫描必须排
-
通知:Navbar 直接组合
`Badge.Anchor + Badge + Button + Tooltip`
,Bell 位于全局动作区;通知页使用平台真实接口和 HeroUI Tabs/SearchField/Pagination/Card。
-
文件:可编辑 file 字段统一使用 HeroUI Tabs、Autocomplete 和 Pro DropZone;材料中心选择及本地上传都只向业务草稿写
`{name,type,size,url}`
。
-
远程引用:使用 HeroUI
`Autocomplete`
/
`Popover.Root + Button + SearchField + controlled ListBox`
。多选触发器固定 40px 高并只显示“已选择 N 项”,候选长标题单行省略且通过
`title`
暴露全文;弹层最大 24rem、移动端收敛到
`100vw - 24px`
、列表最大 288px。多选后保持打开,单选后关闭;有值时显示官方
`Autocomplete.ClearButton`
,清空分别回传空数组或原协议要求的空值,不改变 ID 保存协议。
-
KPI/图表:仅在真实业务路由存在时使用
Pro KPI、PieChart、BarChart、ComposedChart、ChartTooltip;当前七条业务路由无 KPI/图表,不制造测试模块
。
-
KPI/图表:仅在真实业务路由存在时使用
批准的共享实现;当前七条业务路由无 KPI/图表,不制造测试模块。未来的 ECharts Pie/Donut 直接使用
`src/components/XinyuanEChart.jsx`
,图表外层仍由 HeroUI/HeroUI Pro Card 承载
。
## 基准同步记录
...
...
docs/xinyuan-ui-audit.md
View file @
05865f2c
...
...
@@ -52,6 +52,8 @@
-
字段:HeroUI Input/TextArea/Checkbox/Select/Autocomplete/DatePicker,Pro DropZone;Select 选项仅来自
`settings.options`
,用户/引用仅保存 ID,日期继续转 ISO。
-
Portal/暗色:根主题固定
`light`
,Sidebar 使用独立深色 Token;Modal、Dropdown、Autocomplete、Select、DatePicker 均继承内容区主题并实测打开态。
-
KPI/图表:七条活动路由无 KPI 或图表模块,不适用;没有制造测试模块或业务数字。相关 Pro 子路径已验证可导入。
-
Pie/Donut 专项(2026-09-08):活动路由仍无饼图,未新增演示页面或伪造数据。全仓仅
`src/pages/problem_rectification/dashboard/index.jsx`
的三处未挂载历史环图调用;其扇区颜色已移交共享
`XinyuanEChart`
,页面旧
`color`
、扇区色和统一灰色引导线覆盖已移除。新增独立 16 色
`--xinyuan-pie-chart-*`
/
`--rc-pie-chart-*`
,普通
`--xinyuan-chart-*`
/
`--rc-chart-*`
的值、顺序和语义未改。
-
Pie/Donut 颜色来源:
`chartPalette.js`
先规范化并排序稳定分类 key,再以确定性哈希和线性冲突消解分配专用 Token;16 类以内同图不重复。该共享能力仅对
`series.type === 'pie'`
生效,未来活动业务出现真实饼图时必须直接接入,不得在页面恢复私有色板。
## 浏览器验收
...
...
src/components/XinyuanEChart.jsx
0 → 100644
View file @
05865f2c
import
{
createResolvedXinyuanPieChartColorMap
,
getXinyuanEChartsTheme
,
}
from
'@/design-system/chartPalette'
;
import
ReactECharts
from
'echarts-for-react'
;
import
{
useCallback
,
useEffect
,
useMemo
,
useRef
}
from
'react'
;
function
withoutColor
(
style
)
{
if
(
!
style
||
typeof
style
!==
'object'
)
return
style
;
const
{
color
:
_legacyColor
,
...
rest
}
=
style
;
return
rest
;
}
function
applyPieTheme
(
series
,
theme
)
{
if
(
series
?.
type
!==
'pie'
)
return
series
;
const
colorMap
=
createResolvedXinyuanPieChartColorMap
(
Array
.
isArray
(
series
.
data
)
?
series
.
data
.
map
((
item
)
=>
item
?.
name
)
:
[],
);
const
data
=
Array
.
isArray
(
series
.
data
)
?
series
.
data
.
map
((
item
,
index
)
=>
{
if
(
!
item
||
typeof
item
!==
'object'
||
Array
.
isArray
(
item
))
return
item
;
const
key
=
String
(
item
.
name
??
''
).
trim
();
return
{
...
item
,
itemStyle
:
{
...
item
.
itemStyle
,
borderColor
:
theme
.
sectorGap
,
borderRadius
:
theme
.
sectorRadius
,
borderWidth
:
theme
.
sectorGapWidth
,
color
:
colorMap
.
get
(
key
)
||
theme
.
piePalette
[
index
%
theme
.
piePalette
.
length
],
},
};
})
:
series
.
data
;
return
{
...
series
,
color
:
theme
.
piePalette
,
itemStyle
:
{
...
series
.
itemStyle
,
borderColor
:
theme
.
sectorGap
,
borderRadius
:
theme
.
sectorRadius
,
borderWidth
:
theme
.
sectorGapWidth
,
},
labelLine
:
series
.
labelLine
?
{
...
series
.
labelLine
,
lineStyle
:
withoutColor
(
series
.
labelLine
.
lineStyle
),
}
:
series
.
labelLine
,
data
,
padAngle
:
series
.
padAngle
??
1
,
};
}
export
default
function
XinyuanEChart
({
ariaLabel
,
className
=
''
,
height
=
320
,
onEvents
,
option
,
})
{
const
chartRef
=
useRef
(
null
);
const
hideTooltip
=
useCallback
(()
=>
{
chartRef
.
current
?.
getEchartsInstance
?.().
dispatchAction
({
type
:
'hideTip'
});
},
[]);
useEffect
(()
=>
{
window
.
addEventListener
(
'resize'
,
hideTooltip
);
return
()
=>
window
.
removeEventListener
(
'resize'
,
hideTooltip
);
},
[
hideTooltip
]);
const
themedOption
=
useMemo
(()
=>
{
const
theme
=
getXinyuanEChartsTheme
();
const
series
=
Array
.
isArray
(
option
?.
series
)
?
option
.
series
.
map
((
item
)
=>
applyPieTheme
(
item
,
theme
))
:
applyPieTheme
(
option
?.
series
,
theme
);
return
{
animationDuration
:
320
,
animationDurationUpdate
:
240
,
animationEasing
:
'cubicOut'
,
aria
:
{
enabled
:
true
,
decal
:
{
show
:
false
},
...
option
?.
aria
,
},
color
:
option
?.
color
||
theme
.
palette
,
...
option
,
series
,
tooltip
:
option
?.
tooltip
?
{
appendToBody
:
true
,
backgroundColor
:
theme
.
tooltipBackground
,
borderColor
:
theme
.
tooltipBorder
,
borderWidth
:
1
,
className
:
'rc-echarts-tooltip'
,
confine
:
true
,
enterable
:
false
,
padding
:
[
10
,
12
],
renderMode
:
'html'
,
...
option
.
tooltip
,
textStyle
:
{
color
:
theme
.
tooltipForeground
,
fontFamily
:
theme
.
fontFamily
,
fontSize
:
12
,
...
option
.
tooltip
?.
textStyle
,
},
}
:
undefined
,
};
},
[
option
]);
return
(
<
div
aria
-
label=
{
ariaLabel
}
className=
{
`rc-chart-interaction w-full min-w-0 ${className}`
.
trim
()
}
role=
"img"
tabIndex=
{
0
}
>
<
ReactECharts
lazyUpdate
notMerge
onEvents=
{
{
globalout
:
hideTooltip
,
...
onEvents
}
}
option=
{
themedOption
}
opts=
{
{
renderer
:
'canvas'
}
}
ref=
{
chartRef
}
style=
{
{
height
,
width
:
'100%'
}
}
/>
</
div
>
);
}
src/design-system/chartPalette.js
0 → 100644
View file @
05865f2c
export
const
XINYUAN_CHART_PALETTE
=
Object
.
freeze
(
Array
.
from
({
length
:
16
},
(
_
,
index
)
=>
`var(--rc-chart-
${
index
+
1
}
)`
),
);
// Pie and donut slices need more hue separation than linear series. Keep this
// palette independent so bar/line/ranking charts retain their approved colors.
export
const
XINYUAN_PIE_CHART_PALETTE
=
Object
.
freeze
(
Array
.
from
({
length
:
16
},
(
_
,
index
)
=>
`var(--rc-pie-chart-
${
index
+
1
}
)`
),
);
function
normalizeChartKey
(
key
)
{
return
String
(
key
??
''
).
trim
();
}
function
hashChartKey
(
key
)
{
return
Array
.
from
(
key
).
reduce
(
(
value
,
character
)
=>
((
value
*
31
)
+
character
.
codePointAt
(
0
))
>>>
0
,
0
,
);
}
export
function
getXinyuanPieChartColor
(
index
=
0
)
{
return
XINYUAN_PIE_CHART_PALETTE
[
Math
.
max
(
0
,
Number
(
index
)
||
0
)
%
XINYUAN_PIE_CHART_PALETTE
.
length
];
}
function
readRootToken
(
tokenName
,
fallback
=
''
)
{
if
(
typeof
window
===
'undefined'
||
typeof
document
===
'undefined'
)
{
return
fallback
;
}
return
window
.
getComputedStyle
(
document
.
documentElement
)
.
getPropertyValue
(
tokenName
)
.
trim
()
||
fallback
;
}
const
concreteColorCache
=
new
Map
();
function
convertOklchToRgb
(
value
)
{
const
match
=
String
(
value
).
trim
().
match
(
/^oklch
\(\s
*
([\d
.
]
+
)
%
?\s
+
([\d
.
]
+
)
%
?\s
+
([\d
.-
]
+
)(?:
deg
)?\s
*
\)
$/i
,
);
if
(
!
match
)
return
value
;
const
lightnessValue
=
Number
(
match
[
1
]);
const
chromaValue
=
Number
(
match
[
2
]);
const
lightness
=
lightnessValue
>
1
?
lightnessValue
/
100
:
lightnessValue
;
const
chroma
=
chromaValue
>
1
?
chromaValue
/
100
:
chromaValue
;
const
hue
=
(
Number
(
match
[
3
])
*
Math
.
PI
)
/
180
;
const
a
=
chroma
*
Math
.
cos
(
hue
);
const
b
=
chroma
*
Math
.
sin
(
hue
);
const
l
=
(
lightness
+
0.3963377774
*
a
+
0.2158037573
*
b
)
**
3
;
const
m
=
(
lightness
-
0.1055613458
*
a
-
0.0638541728
*
b
)
**
3
;
const
s
=
(
lightness
-
0.0894841775
*
a
-
1.291485548
*
b
)
**
3
;
const
channels
=
[
4.0767416621
*
l
-
3.3077115913
*
m
+
0.2309699292
*
s
,
-
1.2684380046
*
l
+
2.6097574011
*
m
-
0.3413193965
*
s
,
-
0.0041960863
*
l
-
0.7034186147
*
m
+
1.707614701
*
s
,
].
map
((
channel
)
=>
{
const
clamped
=
Math
.
max
(
0
,
Math
.
min
(
1
,
channel
));
const
encoded
=
clamped
<=
0.0031308
?
12.92
*
clamped
:
1.055
*
(
clamped
**
(
1
/
2.4
))
-
0.055
;
return
Math
.
round
(
encoded
*
255
);
});
return
`rgb(
${
channels
.
join
(
', '
)}
)`
;
}
function
readConcreteColorToken
(
tokenName
,
fallback
=
''
)
{
const
raw
=
readRootToken
(
tokenName
,
fallback
);
const
cached
=
concreteColorCache
.
get
(
tokenName
);
if
(
cached
?.
raw
===
raw
)
return
cached
.
value
;
if
(
typeof
document
===
'undefined'
||
!
raw
)
{
return
raw
||
fallback
;
}
const
probe
=
document
.
createElement
(
'span'
);
probe
.
style
.
color
=
raw
;
if
(
!
probe
.
style
.
color
)
return
fallback
;
probe
.
style
.
position
=
'absolute'
;
probe
.
style
.
pointerEvents
=
'none'
;
document
.
body
?.
appendChild
(
probe
);
const
resolved
=
convertOklchToRgb
(
window
.
getComputedStyle
(
probe
).
color
||
fallback
);
probe
.
remove
();
concreteColorCache
.
set
(
tokenName
,
{
raw
,
value
:
resolved
});
return
resolved
;
}
export
function
resolveXinyuanChartColor
(
color
,
fallback
=
''
)
{
const
match
=
String
(
color
||
''
).
trim
().
match
(
/^var
\((
--
[^
)
]
+
)\)
$/
);
return
match
?
readConcreteColorToken
(
match
[
1
],
fallback
)
:
String
(
color
||
fallback
);
}
export
function
createResolvedXinyuanPieChartColorMap
(
keys
=
[])
{
const
stableKeys
=
[...
new
Set
(
keys
.
map
(
normalizeChartKey
).
filter
(
Boolean
))].
sort
();
const
colorMap
=
new
Map
();
const
usedIndexes
=
new
Set
();
stableKeys
.
forEach
((
key
)
=>
{
const
preferredIndex
=
hashChartKey
(
key
)
%
XINYUAN_PIE_CHART_PALETTE
.
length
;
let
paletteIndex
=
preferredIndex
;
for
(
let
offset
=
0
;
offset
<
XINYUAN_PIE_CHART_PALETTE
.
length
;
offset
+=
1
)
{
const
candidate
=
(
preferredIndex
+
offset
)
%
XINYUAN_PIE_CHART_PALETTE
.
length
;
if
(
!
usedIndexes
.
has
(
candidate
))
{
paletteIndex
=
candidate
;
usedIndexes
.
add
(
candidate
);
break
;
}
}
colorMap
.
set
(
key
,
resolveXinyuanChartColor
(
getXinyuanPieChartColor
(
paletteIndex
)));
});
return
colorMap
;
}
export
function
getXinyuanEChartsTheme
()
{
const
documentFont
=
typeof
document
===
'undefined'
?
'Inter, sans-serif'
:
window
.
getComputedStyle
(
document
.
body
).
fontFamily
;
return
{
axis
:
readRootToken
(
'--xinyuan-chart-axis'
,
'#737373'
),
fontFamily
:
documentFont
||
'Inter, sans-serif'
,
foreground
:
readConcreteColorToken
(
'--foreground'
,
readRootToken
(
'--xinyuan-chart-tooltip-foreground'
,
'#222222'
),
),
grid
:
readRootToken
(
'--xinyuan-chart-grid'
,
'#e8e8e8'
),
label
:
readRootToken
(
'--xinyuan-chart-label'
,
'#737373'
),
palette
:
Array
.
from
({
length
:
16
},
(
_
,
index
)
=>
(
readConcreteColorToken
(
`--xinyuan-chart-
${
index
+
1
}
`
,
'#667085'
)
)),
piePalette
:
Array
.
from
({
length
:
16
},
(
_
,
index
)
=>
(
readConcreteColorToken
(
`--xinyuan-pie-chart-
${
index
+
1
}
`
,
'#667080'
)
)),
sectorGap
:
readConcreteColorToken
(
'--xinyuan-chart-sector-gap'
,
'#ffffff'
),
sectorGapWidth
:
Number
.
parseFloat
(
readRootToken
(
'--xinyuan-chart-sector-gap-width'
,
'2'
),
)
||
2
,
sectorRadius
:
Number
.
parseFloat
(
readRootToken
(
'--xinyuan-chart-sector-radius'
,
'10'
),
)
||
10
,
tooltipBackground
:
readRootToken
(
'--xinyuan-chart-tooltip-background'
,
'#ffffff'
),
tooltipBorder
:
readRootToken
(
'--xinyuan-chart-tooltip-border'
,
'#dedede'
),
tooltipForeground
:
readRootToken
(
'--xinyuan-chart-tooltip-foreground'
,
'#222222'
),
tooltipShadow
:
readRootToken
(
'--xinyuan-chart-tooltip-shadow'
,
'0 16px 40px rgb(15 23 42 / 14%)'
,
),
};
}
src/design-system/theme.css
View file @
05865f2c
...
...
@@ -91,7 +91,25 @@
--xinyuan-chart-14
:
#8A6F63
;
--xinyuan-chart-15
:
#9A8174
;
--xinyuan-chart-16
:
#B5A69D
;
/* Pie / donut only. Keep this palette independent from linear charts. */
--xinyuan-pie-chart-1
:
#DA241A
;
--xinyuan-pie-chart-2
:
#3F5F86
;
--xinyuan-pie-chart-3
:
#8A668F
;
--xinyuan-pie-chart-4
:
#C28A3D
;
--xinyuan-pie-chart-5
:
#8A6253
;
--xinyuan-pie-chart-6
:
#667080
;
--xinyuan-pie-chart-7
:
#74879A
;
--xinyuan-pie-chart-8
:
#9A8174
;
--xinyuan-pie-chart-9
:
#6F6674
;
--xinyuan-pie-chart-10
:
#B87958
;
--xinyuan-pie-chart-11
:
#61758F
;
--xinyuan-pie-chart-12
:
#807783
;
--xinyuan-pie-chart-13
:
#B0A4A0
;
--xinyuan-pie-chart-14
:
#AFA5B1
;
--xinyuan-pie-chart-15
:
#897A73
;
--xinyuan-pie-chart-16
:
#556B88
;
--xinyuan-chart-sector-gap
:
var
(
--surface
);
--xinyuan-chart-sector-gap-width
:
2px
;
--xinyuan-chart-sector-radius
:
10px
;
--xinyuan-chart-grid
:
#e8e8e8
;
--xinyuan-chart-axis
:
#737373
;
...
...
src/design-system/tokens.css
View file @
05865f2c
...
...
@@ -180,6 +180,23 @@
--rc-chart-14
:
var
(
--xinyuan-chart-14
);
--rc-chart-15
:
var
(
--xinyuan-chart-15
);
--rc-chart-16
:
var
(
--xinyuan-chart-16
);
/* Pie / donut series are intentionally separate from linear chart colors. */
--rc-pie-chart-1
:
var
(
--xinyuan-pie-chart-1
);
--rc-pie-chart-2
:
var
(
--xinyuan-pie-chart-2
);
--rc-pie-chart-3
:
var
(
--xinyuan-pie-chart-3
);
--rc-pie-chart-4
:
var
(
--xinyuan-pie-chart-4
);
--rc-pie-chart-5
:
var
(
--xinyuan-pie-chart-5
);
--rc-pie-chart-6
:
var
(
--xinyuan-pie-chart-6
);
--rc-pie-chart-7
:
var
(
--xinyuan-pie-chart-7
);
--rc-pie-chart-8
:
var
(
--xinyuan-pie-chart-8
);
--rc-pie-chart-9
:
var
(
--xinyuan-pie-chart-9
);
--rc-pie-chart-10
:
var
(
--xinyuan-pie-chart-10
);
--rc-pie-chart-11
:
var
(
--xinyuan-pie-chart-11
);
--rc-pie-chart-12
:
var
(
--xinyuan-pie-chart-12
);
--rc-pie-chart-13
:
var
(
--xinyuan-pie-chart-13
);
--rc-pie-chart-14
:
var
(
--xinyuan-pie-chart-14
);
--rc-pie-chart-15
:
var
(
--xinyuan-pie-chart-15
);
--rc-pie-chart-16
:
var
(
--xinyuan-pie-chart-16
);
--rc-chart-primary
:
var
(
--rc-chart-1
);
--rc-chart-risk
:
var
(
--rc-chart-1
);
--rc-chart-warning
:
var
(
--rc-chart-3
);
...
...
src/pages/problem_rectification/dashboard/index.jsx
View file @
05865f2c
...
...
@@ -15,6 +15,7 @@ import {
TableHeader
,
TableRow
,
}
from
'@/catalyst-ui-kit/javascript/table'
;
import
XinyuanEChart
from
'@/components/XinyuanEChart'
;
import
ReactECharts
from
'echarts-for-react'
;
import
clsx
from
'clsx'
;
import
dayjs
from
'dayjs'
;
...
...
@@ -179,9 +180,8 @@ function FocusIssueDetailDialog({ issueType, items = [], onClose }) {
);
}
function
buildDonutOption
(
data
,
colors
)
{
function
buildDonutOption
(
data
)
{
return
{
color
:
colors
,
tooltip
:
{
trigger
:
'item'
,
backgroundColor
:
'rgba(15,23,42,0.9)'
,
...
...
@@ -211,9 +211,7 @@ function buildDonutOption(data, colors) {
c
:
{
fontSize
:
11
,
color
:
'#64748b'
},
},
},
labelLine
:
{
lineStyle
:
{
color
:
'#cbd5e1'
},
},
labelLine
:
{
show
:
true
},
data
,
},
],
...
...
@@ -571,7 +569,6 @@ function buildBubbleMatrixOption(data = []) {
function buildQualityRatingOption(data)
{
return
{
color
:
[
CHART_COLOR_SET
[
10
],
CHART_COLOR_SET
[
5
],
CHART_COLOR_SET
[
0
]],
tooltip
:
{
trigger
:
'item'
,
backgroundColor
:
'rgba(15,23,42,0.9)'
,
...
...
@@ -602,9 +599,7 @@ function buildQualityRatingOption(data) {
c
:
{
fontSize
:
12
,
color
:
'#64748b'
},
},
},
labelLine
:
{
lineStyle
:
{
color
:
'#cbd5e1'
},
},
labelLine
:
{
show
:
true
},
data
,
},
],
...
...
@@ -679,7 +674,7 @@ export function ProblemRectificationDashboardPage({ dashboardMode = 'overview' }
};
const
progressOption
=
useMemo
(
()
=>
buildDonutOption
(
summary
.
progressDistribution
,
CHART_COLOR_SET
),
()
=>
buildDonutOption
(
summary
.
progressDistribution
),
[
summary
.
progressDistribution
],
);
const
activeCategoryData
=
summary
.
categoryDistributions
?.[
activeCategoryLevel
]
||
[];
...
...
@@ -688,7 +683,7 @@ export function ProblemRectificationDashboardPage({ dashboardMode = 'overview' }
[
activeCategoryData
],
);
const
rootCauseOption
=
useMemo
(
()
=>
buildDonutOption
(
summary
.
rootCauseDistribution
,
CHART_COLOR_SET
),
()
=>
buildDonutOption
(
summary
.
rootCauseDistribution
),
[
summary
.
rootCauseDistribution
],
);
const
sourceComparisonOption
=
useMemo
(
...
...
@@ -887,7 +882,11 @@ export function ProblemRectificationDashboardPage({ dashboardMode = 'overview' }
description=
"按整改进度统计数量与占比,直观看当前积压主要落在哪个状态。"
>
{
summary
.
progressDistribution
.
length
>
0
?
(
<
ReactECharts
option=
{
progressOption
}
style=
{
{
height
:
340
}
}
/>
<
XinyuanEChart
ariaLabel=
"整改进度分布环形图"
height=
{
340
}
option=
{
progressOption
}
/>
)
:
(
<
EmptyBlock
title=
"暂无整改进度分布数据"
/>
)
}
...
...
@@ -942,7 +941,11 @@ export function ProblemRectificationDashboardPage({ dashboardMode = 'overview' }
description=
"按问题原因分类统计,便于识别制度、流程或执行层面的共性成因。"
>
{
summary
.
rootCauseDistribution
.
length
>
0
?
(
<
ReactECharts
option=
{
rootCauseOption
}
style=
{
{
height
:
360
}
}
/>
<
XinyuanEChart
ariaLabel=
"问题根本原因分布环形图"
height=
{
360
}
option=
{
rootCauseOption
}
/>
)
:
(
<
EmptyBlock
title=
"暂无问题原因统计数据"
/>
)
}
...
...
@@ -1030,7 +1033,11 @@ export function ProblemRectificationDashboardPage({ dashboardMode = 'overview' }
description=
"按六项整改评估字段自动计算并展示高、中、低分布;任一负向维度为低,至少两个正向维度为高,其余有效结果为中。"
>
{
summary
.
qualityRatingDistribution
.
length
>
0
?
(
<
ReactECharts
option=
{
qualityRatingOption
}
style=
{
{
height
:
380
}
}
/>
<
XinyuanEChart
ariaLabel=
"综合整改质效结果环形图"
height=
{
380
}
option=
{
qualityRatingOption
}
/>
)
:
(
<
EmptyBlock
title=
"暂无综合整改质效结果数据"
/>
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment