Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
S
saas-bi
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
saas-bi
Commits
29c52a95
提交
29c52a95
authored
3月 28, 2025
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
chore: update
上级
89430342
全部展开
显示空白字符变更
内嵌
并排
正在显示
26 个修改的文件
包含
395 行增加
和
116 行删除
+395
-116
Chart.tsx
src/components/chart/Chart.tsx
+34
-0
ChartButtonModal.tsx
src/components/chart/ChartButtonModal.tsx
+46
-21
ChartWrap.tsx
src/components/chart/ChartWrap.tsx
+8
-26
SelectChart.tsx
src/components/chart/SelectChart.tsx
+144
-0
ViewChartButtonModal.tsx
src/components/chart/ViewChartButtonModal.tsx
+2
-2
useChartQuery.ts
src/hooks/useChartQuery.ts
+16
-1
Index.tsx
src/modules/data/chart/bar/views/Index.tsx
+1
-4
Index.tsx
src/modules/data/chart/bubble/views/Index.tsx
+1
-4
Index.tsx
src/modules/data/chart/funnel/views/Index.tsx
+1
-4
Index.tsx
src/modules/data/chart/histogram/views/Index.tsx
+1
-4
Index.tsx
src/modules/data/chart/indicator/views/Index.tsx
+1
-4
Index.tsx
src/modules/data/chart/line/views/Index.tsx
+1
-4
Index.tsx
src/modules/data/chart/map/views/Index.tsx
+1
-4
Index.tsx
src/modules/data/chart/pareto/views/Index.tsx
+1
-6
Index.tsx
src/modules/data/chart/pie/views/Index.tsx
+1
-4
Index.tsx
src/modules/data/chart/point/views/Index.tsx
+1
-4
Index.tsx
src/modules/data/chart/radar/views/Index.tsx
+1
-4
Index.tsx
src/modules/data/chart/table/views/Index.tsx
+1
-4
Index.tsx
src/modules/data/chart/treeMap/views/Index.tsx
+1
-6
Index.tsx
src/modules/data/chart/wordCloud/views/Index.tsx
+1
-4
ButtonModal.tsx
src/modules/data/screen/components/ButtonModal.tsx
+0
-0
query.ts
src/modules/data/screen/query.ts
+24
-2
routes.tsx
src/modules/data/screen/routes.tsx
+9
-0
Index.tsx
src/modules/data/screen/views/Index.tsx
+5
-4
View.tsx
src/modules/data/screen/views/View.tsx
+72
-0
constants.ts
src/utils/constants.ts
+21
-0
没有找到文件。
src/components/chart/Chart.tsx
0 → 100644
浏览文件 @
29c52a95
import
{
useDataQuery
}
from
'@/hooks/useQuery'
import
{
Column
,
Line
,
Pie
,
Radar
,
Scatter
,
WordCloud
}
from
'@ant-design/plots'
export
default
function
Chart
({
type
=
'1'
,
...
props
})
{
const
{
data
}
=
useDataQuery
()
switch
(
type
)
{
case
'1'
:
return
<
Column
data=
{
data
.
list
}
{
...
props
}
/>
case
'2'
:
{
const
defaultConfig
=
{
data
:
data
.
list
,
point
:
{
shapeField
:
'point'
,
sizeField
:
4
},
style
:
{
lineWidth
:
2
},
}
return
<
Line
{
...
defaultConfig
}
{
...
props
}
/>
}
case
'3'
:
{
const
defaultConfig
=
{
data
:
data
.
list
,
angleField
:
props
.
yField
,
colorField
:
props
.
xField
,
}
return
<
Pie
{
...
defaultConfig
}
/>
}
case
'4'
:
return
<
Radar
data=
{
data
.
list
}
{
...
props
}
/>
case
'5'
:
return
<
Scatter
data=
{
data
.
list
}
{
...
props
}
/>
case
'7'
:
return
<
WordCloud
data=
{
data
.
list
}
{
...
props
}
/>
default
:
return
<
Column
data=
{
data
.
list
}
{
...
props
}
/>
}
}
src/components/chart/ChartButtonModal.tsx
浏览文件 @
29c52a95
import
{
useState
}
from
'react'
import
{
use
Effect
,
use
State
}
from
'react'
import
{
Button
,
Flex
,
Modal
,
Form
,
Divider
,
Select
,
Radio
,
Row
,
Col
,
Input
}
from
'antd'
import
{
Button
,
Flex
,
Modal
,
Form
,
Divider
,
Select
,
Radio
,
Row
,
Col
,
Input
}
from
'antd'
import
{
useData
Query
,
useData
FieldQuery
}
from
'@/hooks/useQuery'
import
{
useDataFieldQuery
}
from
'@/hooks/useQuery'
import
{
useCreateChart
}
from
'@/hooks/useChartQuery'
import
{
useCreateChart
,
useUpdateChart
,
useViewChartQuery
}
from
'@/hooks/useChartQuery'
import
{
useAI
}
from
'@/hooks/useAI'
import
{
useAI
}
from
'@/hooks/useAI'
import
{
Column
}
from
'@ant-design/plots
'
import
Chart
from
'./Chart
'
interface
Props
{
interface
Props
{
id
?:
string
type
:
string
type
:
string
setOpen
:
(
open
:
boolean
)
=>
void
setOpen
:
(
open
:
boolean
)
=>
void
}
}
const
ModalContent
=
({
setOpen
,
type
}:
Props
)
=>
{
const
ModalContent
=
({
setOpen
,
type
,
id
=
''
}:
Props
)
=>
{
const
{
data
}
=
useDataQuery
()
const
{
fieldOptions
}
=
useDataFieldQuery
()
const
{
fieldOptions
}
=
useDataFieldQuery
()
const
{
data
:
chartData
}
=
useViewChartQuery
(
id
)
const
[
form
]
=
Form
.
useForm
()
const
[
form
]
=
Form
.
useForm
()
useEffect
(()
=>
{
if
(
id
&&
chartData
)
{
try
{
const
parsedContent
=
JSON
.
parse
(
chartData
.
content
)
form
.
setFieldsValue
({
...
parsedContent
.
form
})
}
catch
(
e
)
{
console
.
error
(
'解析图表数据失败:'
,
e
)
}
}
},
[
id
,
chartData
,
form
])
const
[
results
,
setResults
]
=
useState
({})
const
[
results
,
setResults
]
=
useState
({})
const
xField
=
Form
.
useWatch
(
'x'
,
form
)
const
xField
=
Form
.
useWatch
(
'x'
,
form
)
const
yField
=
Form
.
useWatch
(
'y'
,
form
)
const
yField
=
Form
.
useWatch
(
'y'
,
form
)
const
colorField
=
Form
.
useWatch
(
'colorField'
,
form
)
const
title
=
Form
.
useWatch
(
'title'
,
form
)
const
title
=
Form
.
useWatch
(
'title'
,
form
)
const
config
=
{
data
:
data
.
list
,
xField
,
yField
,
colorField
:
x
Field
,
title
,
...
results
}
const
config
=
{
xField
,
yField
,
color
Field
,
title
,
...
results
}
const
{
post
}
=
useAI
({
const
{
post
}
=
useAI
({
onComplete
:
(
message
)
=>
{
onComplete
:
(
message
)
=>
{
...
@@ -59,17 +72,28 @@ const ModalContent = ({ setOpen, type }: Props) => {
...
@@ -59,17 +72,28 @@ const ModalContent = ({ setOpen, type }: Props) => {
})
})
}
}
const
{
mutate
}
=
useCreateChart
()
const
{
mutate
:
mutateCreate
}
=
useCreateChart
()
const
{
mutate
:
mutateUpdate
}
=
useUpdateChart
()
// 保存
// 保存
const
handleSubmit
=
()
=>
{
const
handleSubmit
=
()
=>
{
form
.
validateFields
().
then
((
values
)
=>
{
form
.
validateFields
().
then
((
values
)
=>
{
const
params
=
{
...
values
,
type
,
content
:
JSON
.
stringify
({
config
})
}
const
params
=
{
...
values
,
type
,
content
:
JSON
.
stringify
({
form
:
values
,
config
})
}
mutate
(
params
,
{
if
(
id
)
{
mutateUpdate
(
{
id
,
...
params
},
{
onSuccess
:
()
=>
setOpen
(
false
),
}
)
}
else
{
mutateCreate
(
params
,
{
onSuccess
:
()
=>
setOpen
(
false
),
onSuccess
:
()
=>
setOpen
(
false
),
})
})
}
})
})
}
}
return
(
return
(
<>
<>
<
Form
<
Form
...
@@ -84,11 +108,11 @@ const ModalContent = ({ setOpen, type }: Props) => {
...
@@ -84,11 +108,11 @@ const ModalContent = ({ setOpen, type }: Props) => {
has_title
:
'无'
,
has_title
:
'无'
,
fill_image
:
'纯色'
,
fill_image
:
'纯色'
,
}
}
>
}
}
>
<
Form
.
Item
label=
"组件名称"
name=
"name"
>
<
Form
.
Item
label=
"组件名称"
name=
"name"
rules=
{
[{
required
:
true
,
message
:
'请输入组件名称'
}]
}
>
<
Input
placeholder=
"请输入"
/>
<
Input
placeholder=
"请输入"
/>
</
Form
.
Item
>
</
Form
.
Item
>
<
Divider
orientation=
"left"
orientationMargin=
"0"
>
<
Divider
orientation=
"left"
orientationMargin=
"0"
>
步骤1:
数字字段设置
数字字段设置
</
Divider
>
</
Divider
>
<
Row
gutter=
{
20
}
>
<
Row
gutter=
{
20
}
>
<
Col
span=
{
8
}
>
<
Col
span=
{
8
}
>
...
@@ -127,17 +151,17 @@ const ModalContent = ({ setOpen, type }: Props) => {
...
@@ -127,17 +151,17 @@ const ModalContent = ({ setOpen, type }: Props) => {
</
Col
>
</
Col
>
</
Row
>
</
Row
>
<
Divider
orientation=
"left"
orientationMargin=
"0"
>
<
Divider
orientation=
"left"
orientationMargin=
"0"
>
步骤2:
辅助可视化设置
辅助可视化设置
</
Divider
>
</
Divider
>
<
Row
gutter=
{
20
}
>
<
Row
gutter=
{
20
}
>
<
Col
span=
{
12
}
>
<
Col
span=
{
12
}
>
<
Form
.
Item
label=
"请选择“标签”字段"
name=
"
label
"
>
<
Form
.
Item
label=
"请选择“标签”字段"
name=
"
colorField
"
>
<
Select
options=
{
fieldOptions
}
placeholder=
"请选择"
></
Select
>
<
Select
options=
{
fieldOptions
}
placeholder=
"请选择"
></
Select
>
</
Form
.
Item
>
</
Form
.
Item
>
</
Col
>
</
Col
>
<
Col
span=
{
12
}
>
<
Col
span=
{
12
}
>
<
Form
.
Item
label=
"请选择颜色规则"
name=
"fill_color"
>
<
Form
.
Item
label=
"请选择颜色规则"
name=
"fill_color"
>
<
Radio
.
Group
options=
{
[
'自动颜色'
,
'不同柱子颜色不同'
]
}
></
Radio
.
Group
>
<
Radio
.
Group
options=
{
[
'自动颜色'
]
}
></
Radio
.
Group
>
</
Form
.
Item
>
</
Form
.
Item
>
</
Col
>
</
Col
>
</
Row
>
</
Row
>
...
@@ -171,9 +195,9 @@ const ModalContent = ({ setOpen, type }: Props) => {
...
@@ -171,9 +195,9 @@ const ModalContent = ({ setOpen, type }: Props) => {
</
Col
>
</
Col
>
</
Row
>
</
Row
>
<
Divider
orientation=
"left"
orientationMargin=
"0"
>
<
Divider
orientation=
"left"
orientationMargin=
"0"
>
步骤3:
预览组件效果
预览组件效果
</
Divider
>
</
Divider
>
{
xField
&&
yField
&&
<
Column
{
...
config
}
/>
}
<
Chart
type=
{
type
}
{
...
config
}
/>
</
Form
>
</
Form
>
<
Flex
justify=
"center"
gap=
{
20
}
>
<
Flex
justify=
"center"
gap=
{
20
}
>
...
@@ -189,15 +213,16 @@ const ModalContent = ({ setOpen, type }: Props) => {
...
@@ -189,15 +213,16 @@ const ModalContent = ({ setOpen, type }: Props) => {
)
)
}
}
export
default
function
ButtonModal
({
t
itle
=
'新建柱状图'
,
type
=
'1
'
})
{
export
default
function
ButtonModal
({
t
ype
=
'1'
,
id
=
'
'
})
{
const
[
open
,
setOpen
]
=
useState
(
false
)
const
[
open
,
setOpen
]
=
useState
(
false
)
const
title
=
id
?
'编辑'
:
'新建'
return
(
return
(
<>
<>
<
Button
type=
"primary"
onClick=
{
()
=>
setOpen
(
true
)
}
>
<
Button
color=
"primary"
variant=
{
id
?
'text'
:
'solid'
}
onClick=
{
()
=>
setOpen
(
true
)
}
>
{
title
}
{
title
}
</
Button
>
</
Button
>
<
Modal
title=
{
title
}
open=
{
open
}
footer=
{
null
}
destroyOnClose
width=
{
1000
}
onCancel=
{
()
=>
setOpen
(
false
)
}
>
<
Modal
title=
{
title
}
open=
{
open
}
footer=
{
null
}
destroyOnClose
width=
{
1000
}
onCancel=
{
()
=>
setOpen
(
false
)
}
>
<
ModalContent
type=
{
type
}
setOpen=
{
(
open
)
=>
setOpen
(
open
)
}
/>
<
ModalContent
type=
{
type
}
setOpen=
{
(
open
)
=>
setOpen
(
open
)
}
id=
{
id
}
/>
</
Modal
>
</
Modal
>
</>
</>
)
)
...
...
src/components/chart/ChartWrap.tsx
浏览文件 @
29c52a95
import
{
Button
,
Card
,
Flex
}
from
'antd'
import
{
Button
,
Card
,
Flex
}
from
'antd'
import
{
ReactNode
}
from
'react'
import
{
lazy
,
ReactNode
}
from
'react'
import
AppList
,
{
AppListProps
}
from
'@/components/AppList'
import
AppList
,
{
AppListProps
}
from
'@/components/AppList'
import
ViewDataButtonModal
from
'../data/ViewMyDataButtonModal'
import
ViewDataButtonModal
from
'../data/ViewMyDataButtonModal'
import
ViewChartButtonModal
from
'./ViewChartButtonModal'
import
ViewChartButtonModal
from
'./ViewChartButtonModal'
import
{
getChartComponentList
}
from
'@/api/data'
import
{
getChartComponentList
}
from
'@/api/data'
import
{
useDeleteChart
}
from
'@/hooks/useChartQuery'
import
{
useDeleteChart
}
from
'@/hooks/useChartQuery'
import
{
CHART_TYPE
}
from
'@/utils/constants'
const
chartType
:
any
=
{
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
1
:
'柱状图'
,
2
:
'折线图'
,
3
:
'饼状图'
,
4
:
'雷达图'
,
5
:
'散点图'
,
6
:
'气泡图'
,
7
:
'词云'
,
8
:
'地图'
,
9
:
'指标卡'
,
10
:
'漏斗图'
,
11
:
'直方图'
,
12
:
'表格'
,
13
:
'帕累托图'
,
14
:
'矩形树图'
,
}
export
default
function
DataWrap
({
export
default
function
DataWrap
({
title
,
title
,
buttons
,
type
,
type
,
}:
{
}:
{
type
:
string
type
:
string
title
:
string
title
:
string
buttons
:
ReactNode
buttons
?
:
ReactNode
children
?:
ReactNode
children
?:
ReactNode
})
{
})
{
const
{
mutate
}
=
useDeleteChart
()
const
{
mutate
}
=
useDeleteChart
()
...
@@ -58,8 +42,8 @@ export default function DataWrap({
...
@@ -58,8 +42,8 @@ export default function DataWrap({
title
:
'组件类型'
,
title
:
'组件类型'
,
dataIndex
:
'type'
,
dataIndex
:
'type'
,
align
:
'center'
,
align
:
'center'
,
render
(
value
)
{
render
(
value
:
keyof
typeof
CHART_TYPE
)
{
return
chartType
[
value
]
||
value
return
CHART_TYPE
[
value
]
||
value
},
},
},
},
{
title
:
'组件名称'
,
dataIndex
:
'name'
,
align
:
'center'
},
{
title
:
'组件名称'
,
dataIndex
:
'name'
,
align
:
'center'
},
...
@@ -75,9 +59,7 @@ export default function DataWrap({
...
@@ -75,9 +59,7 @@ export default function DataWrap({
return
(
return
(
<>
<>
<
ViewChartButtonModal
id=
{
record
.
id
}
></
ViewChartButtonModal
>
<
ViewChartButtonModal
id=
{
record
.
id
}
></
ViewChartButtonModal
>
<
Button
color=
"primary"
variant=
"text"
>
<
ButtonModal
type=
{
type
}
id=
{
record
.
id
}
></
ButtonModal
>
编辑
</
Button
>
<
Button
color=
"danger"
variant=
"text"
onClick=
{
()
=>
handleRemove
(
record
)
}
>
<
Button
color=
"danger"
variant=
"text"
onClick=
{
()
=>
handleRemove
(
record
)
}
>
删除
删除
</
Button
>
</
Button
>
...
@@ -92,7 +74,7 @@ export default function DataWrap({
...
@@ -92,7 +74,7 @@ export default function DataWrap({
<
Card
className=
"app-card"
title=
{
title
}
style=
{
{
flex
:
1
,
overflowX
:
'hidden'
}
}
>
<
Card
className=
"app-card"
title=
{
title
}
style=
{
{
flex
:
1
,
overflowX
:
'hidden'
}
}
>
<
Flex
justify=
"space-between"
style=
{
{
marginBottom
:
'20px'
}
}
>
<
Flex
justify=
"space-between"
style=
{
{
marginBottom
:
'20px'
}
}
>
<
Flex
wrap
gap=
{
10
}
>
<
Flex
wrap
gap=
{
10
}
>
{
buttons
}
<
ButtonModal
type=
{
type
}
></
ButtonModal
>
</
Flex
>
</
Flex
>
<
ViewDataButtonModal
></
ViewDataButtonModal
>
<
ViewDataButtonModal
></
ViewDataButtonModal
>
</
Flex
>
</
Flex
>
...
...
src/components/chart/SelectChart.tsx
0 → 100644
浏览文件 @
29c52a95
import
{
Button
,
Modal
}
from
'antd'
import
AppList
,
{
AppListProps
}
from
'@/components/AppList'
import
{
getChartComponentList
}
from
'@/api/data'
import
{
CHART_TYPE
}
from
'@/utils/constants'
import
{
useState
,
useEffect
}
from
'react'
import
ViewChartButtonModal
from
'./ViewChartButtonModal'
interface
SelectChartProps
{
type
?:
string
value
?:
any
[]
onChange
?:
(
value
:
any
[])
=>
void
}
export
default
function
SelectChart
({
type
,
value
=
[],
onChange
}:
SelectChartProps
)
{
const
[
open
,
setOpen
]
=
useState
(
false
)
const
[
selectedRows
,
setSelectedRows
]
=
useState
<
any
[]
>
([])
const
[
selectedRowKeys
,
setSelectedRowKeys
]
=
useState
<
React
.
Key
[]
>
([])
const
[
dataSource
,
setDataSource
]
=
useState
<
any
[]
>
(
value
)
useEffect
(()
=>
{
setDataSource
(
value
)
},
[
value
])
const
listOptions
:
AppListProps
=
{
queryKey
:
[
'chartComponentList'
,
{
type
}],
fetchApi
:
async
(
params
)
=>
{
const
{
data
}
=
await
getChartComponentList
({
...
params
,
type
})
return
{
...
data
}
},
columns
:
[
{
title
:
'序号'
,
key
:
'index'
,
render
(
_value
,
_record
,
index
)
{
return
index
+
1
},
width
:
62
,
align
:
'center'
,
},
{
title
:
'组件类型'
,
dataIndex
:
'type'
,
align
:
'center'
,
render
(
value
:
keyof
typeof
CHART_TYPE
)
{
return
CHART_TYPE
[
value
]
||
value
},
},
{
title
:
'组件名称'
,
dataIndex
:
'name'
,
align
:
'center'
},
{
title
:
'创建人'
,
dataIndex
:
'created_operator_name'
,
align
:
'center'
},
{
title
:
'创建时间'
,
dataIndex
:
'created_time'
,
align
:
'center'
},
{
title
:
'更新时间'
,
dataIndex
:
'updated_time'
,
align
:
'center'
},
],
rowSelection
:
{
type
:
'checkbox'
,
selectedRowKeys
,
onChange
:
(
keys
:
React
.
Key
[],
rows
:
any
[])
=>
{
setSelectedRowKeys
(
keys
)
setSelectedRows
(
rows
)
},
getCheckboxProps
:
(
record
:
any
)
=>
({
disabled
:
dataSource
.
some
((
item
)
=>
item
.
id
===
record
.
id
),
}),
},
}
const
removeDuplicates
=
(
originalArray
:
any
[],
newArray
:
any
[])
=>
{
const
uniqueArray
=
[...
originalArray
]
newArray
.
forEach
((
newItem
)
=>
{
const
isDuplicate
=
uniqueArray
.
some
((
item
)
=>
item
.
id
===
newItem
.
id
)
if
(
!
isDuplicate
)
{
uniqueArray
.
push
(
newItem
)
}
})
return
uniqueArray
}
const
handleRemove
=
(
record
:
any
)
=>
{
const
newDataSource
=
dataSource
.
filter
((
item
)
=>
item
.
id
!==
record
.
id
)
setDataSource
(
newDataSource
)
onChange
?.(
newDataSource
)
}
const
handleOk
=
()
=>
{
const
newDataSource
=
removeDuplicates
(
dataSource
,
selectedRows
)
setDataSource
(
newDataSource
)
onChange
?.(
newDataSource
)
setSelectedRows
([])
setSelectedRowKeys
([])
setOpen
(
false
)
}
const
selectListOptions
:
AppListProps
=
{
dataSource
,
columns
:
[
{
title
:
'序号'
,
key
:
'index'
,
render
(
_value
,
_record
,
index
)
{
return
index
+
1
},
width
:
62
,
align
:
'center'
,
},
{
title
:
'组件类型'
,
dataIndex
:
'type'
,
align
:
'center'
,
render
(
value
:
keyof
typeof
CHART_TYPE
)
{
return
CHART_TYPE
[
value
]
||
value
},
},
{
title
:
'组件名称'
,
dataIndex
:
'name'
,
align
:
'center'
},
{
title
:
'操作'
,
key
:
'x'
,
width
:
220
,
align
:
'center'
,
render
(
_value
,
record
)
{
return
(
<>
<
ViewChartButtonModal
id=
{
record
.
id
}
></
ViewChartButtonModal
>
<
Button
color=
"danger"
variant=
"text"
onClick=
{
()
=>
handleRemove
(
record
)
}
>
删除
</
Button
>
</>
)
},
},
],
}
return
(
<>
<
Button
type=
"primary"
onClick=
{
()
=>
setOpen
(
true
)
}
style=
{
{
marginBottom
:
20
}
}
>
添加可视化组件
</
Button
>
<
AppList
{
...
selectListOptions
}
style=
{
{
marginBottom
:
20
}
}
/>
<
Modal
title=
"添加可视化组件"
width=
"1000px"
open=
{
open
}
onCancel=
{
()
=>
setOpen
(
false
)
}
onOk=
{
handleOk
}
>
<
AppList
{
...
listOptions
}
/>
</
Modal
>
</>
)
}
src/components/chart/ViewChartButtonModal.tsx
浏览文件 @
29c52a95
import
{
useState
}
from
'react'
import
{
useState
}
from
'react'
import
{
Button
,
Modal
}
from
'antd'
import
{
Button
,
Modal
}
from
'antd'
import
{
Column
}
from
'@ant-design/plots'
import
{
useViewChartQuery
}
from
'@/hooks/useChartQuery'
import
{
useViewChartQuery
}
from
'@/hooks/useChartQuery'
import
Chart
from
'./Chart'
export
default
function
ViewDataButtonModal
({
id
}:
{
id
:
string
})
{
export
default
function
ViewDataButtonModal
({
id
}:
{
id
:
string
})
{
const
[
open
,
setOpen
]
=
useState
(
false
)
const
[
open
,
setOpen
]
=
useState
(
false
)
...
@@ -34,7 +34,7 @@ function ModalContent({ id }: { id: string }) {
...
@@ -34,7 +34,7 @@ function ModalContent({ id }: { id: string }) {
return
(
return
(
<
div
>
<
div
>
<
C
olumn
{
...
config
}
/>
<
C
hart
type=
{
data
.
type
}
{
...
config
}
/>
</
div
>
</
div
>
)
)
}
}
src/hooks/useChartQuery.ts
浏览文件 @
29c52a95
import
{
useQuery
,
useMutation
,
useQueryClient
}
from
'@tanstack/react-query'
import
{
useQuery
,
useMutation
,
useQueryClient
}
from
'@tanstack/react-query'
import
{
createChartComponent
,
deleteChartComponent
,
getChartComponent
}
from
'@/api/data'
import
{
createChartComponent
,
updateChartComponent
,
deleteChartComponent
,
getChartComponent
}
from
'@/api/data'
import
{
message
}
from
'antd'
import
{
message
}
from
'antd'
// 创建
// 创建
...
@@ -15,6 +15,19 @@ export function useCreateChart() {
...
@@ -15,6 +15,19 @@ export function useCreateChart() {
})
})
}
}
// 编辑
export
function
useUpdateChart
()
{
const
queryClient
=
useQueryClient
()
return
useMutation
({
mutationFn
:
(
data
:
{
id
:
string
;
name
:
string
;
type
:
string
;
content
:
string
})
=>
updateChartComponent
(
data
),
onSuccess
:
()
=>
{
message
.
success
(
'编辑成功'
)
queryClient
.
invalidateQueries
({
queryKey
:
[
'chartComponentList'
]
})
},
})
}
// 删除
// 删除
export
function
useDeleteChart
()
{
export
function
useDeleteChart
()
{
const
queryClient
=
useQueryClient
()
const
queryClient
=
useQueryClient
()
...
@@ -36,5 +49,7 @@ export function useViewChartQuery(id: string) {
...
@@ -36,5 +49,7 @@ export function useViewChartQuery(id: string) {
return
getChartComponent
({
id
})
return
getChartComponent
({
id
})
},
},
select
:
(
res
)
=>
res
.
data
,
select
:
(
res
)
=>
res
.
data
,
enabled
:
!!
id
,
staleTime
:
0
,
})
})
}
}
src/modules/data/chart/bar/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
<
ChartWrap
title=
"可视化:柱状图"
type=
"1"
buttons=
{
<
ButtonModal
title=
"新建柱状图"
type=
"1"
/>
}
></
ChartWrap
>
return
<
ChartWrap
title=
"可视化:柱状图"
type=
"1"
></
ChartWrap
>
}
}
src/modules/data/chart/bubble/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
<
ChartWrap
title=
"可视化:气泡图"
type=
"6"
buttons=
{
<
ButtonModal
title=
"新建气泡图"
type=
"6"
/>
}
></
ChartWrap
>
return
<
ChartWrap
title=
"可视化:气泡图"
type=
"6"
></
ChartWrap
>
}
}
src/modules/data/chart/funnel/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
<
ChartWrap
title=
"可视化:漏斗图"
type=
"10"
buttons=
{
<
ButtonModal
title=
"新建漏斗图"
type=
"10"
/>
}
></
ChartWrap
>
return
<
ChartWrap
title=
"可视化:漏斗图"
type=
"10"
></
ChartWrap
>
}
}
src/modules/data/chart/histogram/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
<
ChartWrap
title=
"可视化:直方图"
type=
"11"
buttons=
{
<
ButtonModal
title=
"新建直方图"
type=
"11"
/>
}
></
ChartWrap
>
return
<
ChartWrap
title=
"可视化:直方图"
type=
"11"
></
ChartWrap
>
}
}
src/modules/data/chart/indicator/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
<
ChartWrap
title=
"可视化:指标卡"
type=
"9"
buttons=
{
<
ButtonModal
title=
"新建指标卡"
type=
"9"
/>
}
></
ChartWrap
>
return
<
ChartWrap
title=
"可视化:指标卡"
type=
"9"
></
ChartWrap
>
}
}
src/modules/data/chart/line/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
<
ChartWrap
title=
"可视化:折线图"
type=
"2"
buttons=
{
<
ButtonModal
title=
"新建折线图"
type=
"2"
/>
}
></
ChartWrap
>
return
<
ChartWrap
title=
"可视化:折线图"
type=
"2"
></
ChartWrap
>
}
}
src/modules/data/chart/map/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
<
ChartWrap
title=
"可视化:地图"
type=
"8"
buttons=
{
<
ButtonModal
title=
"新建地图"
type=
"8"
/>
}
></
ChartWrap
>
return
<
ChartWrap
title=
"可视化:地图"
type=
"8"
></
ChartWrap
>
}
}
src/modules/data/chart/pareto/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
(
return
<
ChartWrap
title=
"可视化:帕累托图"
type=
"13"
></
ChartWrap
>
<
ChartWrap
title=
"可视化:帕累托图"
type=
"13"
buttons=
{
<
ButtonModal
title=
"新建帕累托图"
type=
"13"
/>
}
></
ChartWrap
>
)
}
}
src/modules/data/chart/pie/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
<
ChartWrap
title=
"可视化:饼状图"
type=
"3"
buttons=
{
<
ButtonModal
title=
"新建饼状图"
type=
"3"
/>
}
></
ChartWrap
>
return
<
ChartWrap
title=
"可视化:饼状图"
type=
"3"
></
ChartWrap
>
}
}
src/modules/data/chart/point/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
<
ChartWrap
title=
"可视化:散点图"
type=
"5"
buttons=
{
<
ButtonModal
title=
"新建散点图"
type=
"5"
/>
}
></
ChartWrap
>
return
<
ChartWrap
title=
"可视化:散点图"
type=
"5"
></
ChartWrap
>
}
}
src/modules/data/chart/radar/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
<
ChartWrap
title=
"可视化:雷达图"
type=
"4"
buttons=
{
<
ButtonModal
title=
"新建雷达图"
type=
"4"
/>
}
></
ChartWrap
>
return
<
ChartWrap
title=
"可视化:雷达图"
type=
"4"
></
ChartWrap
>
}
}
src/modules/data/chart/table/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
<
ChartWrap
title=
"可视化:表格"
type=
"12"
buttons=
{
<
ButtonModal
title=
"新建表格"
type=
"12"
/>
}
></
ChartWrap
>
return
<
ChartWrap
title=
"可视化:表格"
type=
"12"
></
ChartWrap
>
}
}
src/modules/data/chart/treeMap/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
(
return
<
ChartWrap
title=
"可视化:矩形树图"
type=
"14"
></
ChartWrap
>
<
ChartWrap
title=
"可视化:矩形树图"
type=
"14"
buttons=
{
<
ButtonModal
title=
"新建矩形树图"
type=
"14"
/>
}
></
ChartWrap
>
)
}
}
src/modules/data/chart/wordCloud/views/Index.tsx
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
ChartWrap
from
'@/components/chart/ChartWrap'
import
ChartWrap
from
'@/components/chart/ChartWrap'
const
ButtonModal
=
lazy
(()
=>
import
(
'@/components/chart/ChartButtonModal'
))
export
default
function
DataProcess
()
{
export
default
function
DataProcess
()
{
return
<
ChartWrap
title=
"可视化:词云"
type=
"7"
buttons=
{
<
ButtonModal
title=
"新建词云"
type=
"7"
/>
}
></
ChartWrap
>
return
<
ChartWrap
title=
"可视化:词云"
type=
"7"
></
ChartWrap
>
}
}
src/modules/data/screen/components/ButtonModal.tsx
浏览文件 @
29c52a95
差异被折叠。
点击展开。
src/modules/data/screen/query.ts
浏览文件 @
29c52a95
import
{
useMutation
,
useQueryClient
}
from
'@tanstack/react-query'
import
{
useMutation
,
useQuery
,
useQuery
Client
}
from
'@tanstack/react-query'
import
{
createLargeScreen
,
deleteLargeScreen
}
from
'./api'
import
{
createLargeScreen
,
deleteLargeScreen
,
getLargeScreen
,
updateLargeScreen
}
from
'./api'
import
{
message
}
from
'antd'
import
{
message
}
from
'antd'
// 创建
// 创建
...
@@ -15,6 +15,18 @@ export function useCreateLargeScreen() {
...
@@ -15,6 +15,18 @@ export function useCreateLargeScreen() {
})
})
}
}
// 更新
export
function
useUpdateLargeScreen
()
{
const
queryClient
=
useQueryClient
()
return
useMutation
({
mutationFn
:
(
data
:
{
id
:
string
;
name
:
string
;
type
:
string
;
content
:
string
})
=>
updateLargeScreen
(
data
),
onSuccess
:
()
=>
{
message
.
success
(
'更新成功'
)
queryClient
.
invalidateQueries
({
queryKey
:
[
'largeScreenList'
]
})
},
})
}
// 删除
// 删除
export
function
useDeleteLargeScreen
()
{
export
function
useDeleteLargeScreen
()
{
const
queryClient
=
useQueryClient
()
const
queryClient
=
useQueryClient
()
...
@@ -27,3 +39,13 @@ export function useDeleteLargeScreen() {
...
@@ -27,3 +39,13 @@ export function useDeleteLargeScreen() {
},
},
})
})
}
}
export
function
useViewLargeScreen
(
id
:
string
)
{
return
useQuery
({
queryKey
:
[
'largeScreen'
,
id
],
queryFn
:
()
=>
getLargeScreen
({
id
}),
select
:
(
res
)
=>
res
.
data
,
enabled
:
!!
id
,
staleTime
:
0
,
})
}
src/modules/data/screen/routes.tsx
0 → 100644
浏览文件 @
29c52a95
import
{
lazy
}
from
'react'
import
type
{
RouteObject
}
from
'react-router'
export
const
routes
:
RouteObject
[]
=
[
{
path
:
'/data/screen/view/:id'
,
Component
:
lazy
(()
=>
import
(
'./views/View'
)),
},
]
src/modules/data/screen/views/Index.tsx
浏览文件 @
29c52a95
...
@@ -4,6 +4,7 @@ import ViewDataButtonModal from '@/components/data/ViewMyDataButtonModal'
...
@@ -4,6 +4,7 @@ import ViewDataButtonModal from '@/components/data/ViewMyDataButtonModal'
import
ButtonModal
from
'../components/ButtonModal'
import
ButtonModal
from
'../components/ButtonModal'
import
{
getLargeScreenList
}
from
'../api'
import
{
getLargeScreenList
}
from
'../api'
import
{
useDeleteLargeScreen
}
from
'../query'
import
{
useDeleteLargeScreen
}
from
'../query'
import
{
Link
}
from
'react-router'
export
default
function
DataWrap
()
{
export
default
function
DataWrap
()
{
const
{
mutate
}
=
useDeleteLargeScreen
()
const
{
mutate
}
=
useDeleteLargeScreen
()
...
@@ -39,12 +40,12 @@ export default function DataWrap() {
...
@@ -39,12 +40,12 @@ export default function DataWrap() {
render
(
_value
,
record
)
{
render
(
_value
,
record
)
{
return
(
return
(
<>
<>
<
Link
to=
{
`/data/screen/view/${record.id}`
}
target=
"_blank"
>
<
Button
color=
"primary"
variant=
"text"
>
<
Button
color=
"primary"
variant=
"text"
>
查看
查看
</
Button
>
</
Button
>
<
Button
color=
"primary"
variant=
"text"
>
</
Link
>
编辑
<
ButtonModal
id=
{
record
.
id
}
></
ButtonModal
>
</
Button
>
<
Button
color=
"danger"
variant=
"text"
onClick=
{
()
=>
handleRemove
(
record
)
}
>
<
Button
color=
"danger"
variant=
"text"
onClick=
{
()
=>
handleRemove
(
record
)
}
>
删除
删除
</
Button
>
</
Button
>
...
@@ -56,7 +57,7 @@ export default function DataWrap() {
...
@@ -56,7 +57,7 @@ export default function DataWrap() {
}
}
return
(
return
(
<
Flex
gap=
{
20
}
style=
{
{
height
:
'100%'
}
}
>
<
Flex
gap=
{
20
}
style=
{
{
height
:
'100%'
}
}
>
<
Card
className=
"app-card"
style=
{
{
flex
:
1
,
overflowX
:
'hidden'
}
}
>
<
Card
className=
"app-card"
title=
"数据可视化大屏"
style=
{
{
flex
:
1
,
overflowX
:
'hidden'
}
}
>
<
Flex
justify=
"space-between"
style=
{
{
marginBottom
:
'20px'
}
}
>
<
Flex
justify=
"space-between"
style=
{
{
marginBottom
:
'20px'
}
}
>
<
Flex
wrap
gap=
{
10
}
>
<
Flex
wrap
gap=
{
10
}
>
<
ButtonModal
></
ButtonModal
>
<
ButtonModal
></
ButtonModal
>
...
...
src/modules/data/screen/views/View.tsx
0 → 100644
浏览文件 @
29c52a95
import
{
useParams
}
from
'react-router'
import
{
useViewLargeScreen
}
from
'../query'
import
Chart
from
'@/components/chart/Chart'
import
{
Card
}
from
'antd'
export
default
function
LargeScreenView
()
{
const
{
id
}
=
useParams
()
const
{
data
}
=
useViewLargeScreen
(
id
||
''
)
if
(
!
data
)
return
null
const
components
=
data
.
component
.
map
((
item
:
any
)
=>
{
try
{
const
{
config
}
=
JSON
.
parse
(
item
.
content
)
return
{
...
item
,
config
}
}
catch
(
error
)
{
console
.
log
(
error
)
}
return
item
})
try
{
const
{
form
}
=
JSON
.
parse
(
data
.
content
)
const
getBackground
=
()
=>
{
switch
(
form
.
bg
)
{
case
'default'
:
return
'#f0f2f5'
case
'color'
:
return
form
.
bgColor
||
'#ffffff'
case
'image'
:
return
form
.
bgImage
?
`url(
${
form
.
bgImage
?.
url
})
` : '#ffffff'
default:
return '#ffffff'
}
}
return (
<div
style={{
width: '100vw',
minHeight: '100%',
background: getBackground(),
backgroundSize: form.bg === 'image' ? 'cover' : 'auto',
backgroundPosition: form.bg === 'image' ? 'center' : 'auto',
}}>
<div style={{ padding: 20 }}>
<h2
style={{
fontSize: `
$
{
form
.
titleStyle
.
fontSize
}
px
`,
color: form.titleStyle.color,
fontWeight: form.titleStyle.bold ? 'bold' : 'normal',
fontStyle: form.titleStyle.italic ? 'italic' : 'normal',
textAlign: form.titleStyle.align,
marginBottom: '20px',
}}>
{form.title}
</h2>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(400px, 1fr))', gap: '20px' }}>
{components.map((item: any) => (
<Card title={item.name} key={item.id}>
<Chart type={item.type} {...item.config} />
</Card>
))}
</div>
</div>
</div>
)
} catch (e) {
console.error('解析数据失败:', e)
return null
}
}
src/utils/constants.ts
0 → 100644
浏览文件 @
29c52a95
export
const
CHART_TYPE
=
{
1
:
'柱状图'
,
2
:
'折线图'
,
3
:
'饼状图'
,
4
:
'雷达图'
,
5
:
'散点图'
,
6
:
'气泡图'
,
7
:
'词云'
,
8
:
'地图'
,
9
:
'指标卡'
,
10
:
'漏斗图'
,
11
:
'直方图'
,
12
:
'表格'
,
13
:
'帕累托图'
,
14
:
'矩形树图'
,
}
export
const
CHART_TYPE_OPTIONS
=
Object
.
entries
(
CHART_TYPE
).
map
(([
key
,
value
])
=>
({
label
:
value
,
value
:
key
,
}))
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论