Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
C
chart-project
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
czj
chart-project
Commits
bff4fbe7
提交
bff4fbe7
authored
12月 12, 2023
作者:
祖铭松
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: PCA
上级
ad01d3f6
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
686 行增加
和
414 行删除
+686
-414
chart.vue
src/components/MsDimplot/components/chart.vue
+1
-1
chart.vue
src/components/PcaAnalysis/components/chart.vue
+127
-87
config.vue
src/components/PcaAnalysis/components/config.vue
+28
-29
mock.js
src/components/PcaAnalysis/mock.js
+42
-7
index.js
src/components/PcaAnalysis/utils/index.js
+241
-0
index.vue
src/components/Test/index.vue
+53
-38
mock.js
src/components/Test/mock.js
+24
-72
utils.js
src/components/Test/utils.js
+169
-179
index.vue
src/views/home/index.vue
+1
-1
没有找到文件。
src/components/MsDimplot/components/chart.vue
浏览文件 @
bff4fbe7
...
@@ -40,7 +40,7 @@ const generateChart = (data) => {
...
@@ -40,7 +40,7 @@ const generateChart = (data) => {
const
titleConfig
=
{
const
titleConfig
=
{
label
:
!!
ret
.
title
?
ret
.
title
:
null
,
label
:
!!
ret
.
title
?
ret
.
title
:
null
,
color
:
ret
.
title_font_color
||
'#333333'
,
color
:
ret
.
title_font_color
||
'#333333'
,
fontSize
:
ret
.
title_font_size
||
3
0
,
fontSize
:
ret
.
title_font_size
||
2
0
,
fontStyle
:
ret
.
title_font_style
?
'oblique'
:
'normal'
,
fontStyle
:
ret
.
title_font_style
?
'oblique'
:
'normal'
,
fontFamily
:
ret
.
title_font_family
||
'Arial'
,
fontFamily
:
ret
.
title_font_family
||
'Arial'
,
fontWeight
:
ret
.
title_font_weight
?
'bold'
:
'normal'
fontWeight
:
ret
.
title_font_weight
?
'bold'
:
'normal'
...
...
src/components/PcaAnalysis/components/chart.vue
浏览文件 @
bff4fbe7
<
template
>
<
template
>
<div
ref=
"chartRef"
></div>
<div
ref=
"chartRef"
class=
"chart-box"
>
<div
class=
"tip"
></div>
</div>
</
template
>
</
template
>
<
script
setup
>
<
script
setup
>
import
{
ref
,
onMounted
,
onUnmounted
}
from
'vue'
;
import
{
ref
,
onMounted
,
onUnmounted
}
from
'vue'
;
import
*
as
Plot
from
'@observablehq/plot'
;
import
{
chartMockData
}
from
'../mock.js'
;
// import * as d3 from 'd3';
import
*
as
d3
from
'https://cdn.jsdelivr.net/npm/d3@7/+esm'
;
import
{
chartData
}
from
'../mock'
;
import
PubSub
from
'pubsub-js'
;
import
PubSub
from
'pubsub-js'
;
import
{
setTips
,
setColor
,
setLegend
,
setScale
,
setAxis
,
setPoint
,
setLabel
,
setElliptic
}
from
'../utils/index'
;
// 根节点实例
const
chartRef
=
ref
(
null
);
const
chartRef
=
ref
(
null
);
// 配置项数据
// 配置项数据
const
options
=
ref
({});
const
options
=
ref
({});
// 图表实例
const
svgInstance
=
ref
(
null
);
// pubsub实例
// pubsub实例
const
pubSubInstance
=
ref
(
null
);
const
pubSubInstance
=
ref
(
null
);
// plot实例
const
plotInstance
=
ref
(
null
);
// 生成图表
// 生成图表
const
generateChart
=
(
data
)
=>
{
const
generateChart
=
(
data
)
=>
{
const
ret
=
options
.
value
;
const
ret
=
options
.
value
;
// console.log(ret);
let
width
=
Number
(
ret
.
chart_width
)
||
700
;
// 点,线,阴影颜色设置
let
height
=
Number
(
ret
.
chart_height
)
||
800
;
let
point_color
=
'#FF5733'
;
let
marginTop
=
Number
(
ret
.
margin_top
)
||
120
;
let
line_color
=
'#39FDBE'
;
let
marginRight
=
Number
(
ret
.
margin_Right
)
||
120
;
let
shadow_color
=
'#D6D6D6'
;
let
marginBottom
=
Number
(
ret
.
margin_Bottom
)
||
120
;
if
(
ret
.
data_color_list
?.
length
)
{
let
marginLeft
=
Number
(
ret
.
margin_Left
)
||
120
;
point_color
=
ret
.
data_color_list
[
0
];
let
legendPosition
=
ret
.
legend_position
?.
split
(
','
)
||
[
0.5
,
1
];
line_color
=
ret
.
data_color_list
[
1
];
let
colors
=
ret
.
data_color_list
||
[
'#155C9C'
,
'#44A79D'
];
shadow_color
=
ret
.
data_color_list
[
2
];
let
legendData
=
[
'AD'
,
'Non_AD'
];
}
plotInstance
.
value
=
Plot
.
plot
({
// 标题配置
width
:
ret
.
chart_width
||
800
,
const
titleConfig
=
{
height
:
ret
.
chart_height
||
600
,
label
:
!!
ret
.
title
?
ret
.
title
:
null
,
marginTop
:
ret
.
margin_top
||
60
,
color
:
ret
.
title_font_color
||
'#333333'
,
marginRight
:
ret
.
margin_right
||
60
,
fontSize
:
ret
.
title_font_size
||
20
,
marginBottom
:
ret
.
margin_bottom
||
60
,
fontStyle
:
ret
.
title_font_style
?
'oblique'
:
'normal'
,
marginLeft
:
ret
.
margin_left
||
60
,
fontFamily
:
ret
.
title_font_family
||
'Arial'
,
color
:
{
fontWeight
:
ret
.
title_font_weight
?
'bold'
:
'normal'
legend
:
ret
.
show_legend
};
},
x
:
{
// 大椭圆
grid
:
ret
.
show_x_gridLine
,
let
ellipticOne
=
{
domain
:
[
-
100
,
100
]
rx
:
(
width
-
marginLeft
-
marginRight
)
/
2
-
20
,
},
ry
:
(
height
-
marginTop
-
marginBottom
)
/
2
-
20
,
y
:
{
cx
:
(
marginLeft
+
width
-
marginLeft
-
marginRight
)
/
2
+
60
,
grid
:
ret
.
show_y_gridLine
,
cy
:
(
marginTop
+
height
-
marginTop
-
marginBottom
)
/
2
+
60
domain
:
[
-
100
,
100
]
};
},
marks
:
[
// 椭圆 AD
Plot
.
frame
(),
let
ellipticAD
=
{
Plot
.
ruleX
([
0
],
{
strokeDasharray
:
'5'
}),
rx
:
80
,
Plot
.
ruleY
([
0
],
{
strokeDasharray
:
'5'
}),
ry
:
350
,
Plot
.
axisX
({
cx
:
(
marginLeft
+
width
-
marginLeft
-
marginRight
)
/
2
+
60
,
interval
:
50
,
cy
:
(
marginTop
+
height
-
marginTop
-
marginBottom
)
/
2
+
60
,
label
:
!!
ret
.
x_title
?
ret
.
x_title
:
null
,
rotate
:
10
,
stroke
:
ret
.
x_tickMarks_color
||
'currentColor'
,
fill
:
colors
[
0
],
tickSize
:
ret
.
show_x_tickMarks
?
ret
.
x_tickMarks_length
:
0
,
fillOpacity
:
0.2
fill
:
ret
.
xtitle_font_color
||
'currentColor'
,
};
fontSize
:
ret
.
xtitle_font_size
||
16
,
fontStyle
:
ret
.
xtitle_font_style
?
'oblique'
:
'normal'
,
// 椭圆 Non_AD
fontFamily
:
ret
.
xtitle_font_family
||
'Arial'
,
let
ellipticNon_AD
=
{
fontWeight
:
ret
.
xtitle_font_weight
?
'bold'
:
'normal'
rx
:
350
,
}),
ry
:
60
,
Plot
.
axisY
({
cx
:
(
marginLeft
+
width
-
marginLeft
-
marginRight
)
/
2
+
60
,
interval
:
50
,
cy
:
(
marginTop
+
height
-
marginTop
-
marginBottom
)
/
2
+
20
,
label
:
!!
ret
.
y_title
?
ret
.
y_title
:
null
,
rotate
:
20
,
stroke
:
ret
.
y_tickMarks_color
||
'currentColor'
,
fill
:
colors
[
1
],
tickSize
:
ret
.
show_x_tickMarks
?
ret
.
y_tickMarks_length
:
0
,
fillOpacity
:
0.2
fill
:
ret
.
ytitle_font_color
||
'currentColor'
,
};
fontSize
:
ret
.
ytitle_font_size
||
16
,
fontStyle
:
ret
.
ytitle_font_style
?
'oblique'
:
'normal'
,
const
svg
=
d3
.
create
(
'svg'
).
attr
(
'width'
,
width
).
attr
(
'height'
,
height
);
fontFamily
:
ret
.
ytitle_font_family
||
'Arial'
,
fontWeight
:
ret
.
ytitle_font_weight
?
'bold'
:
'normal'
let
configObj
=
{
}),
...
ret
,
Plot
.
dot
(
data
,
{
x
:
'x'
,
y
:
'y'
,
fill
:
point_color
,
r
:
Number
(
ret
.
point_radius
)
||
5
,
tip
:
true
}),
svg
,
// Plot.linearRegressionX(data, {
width
,
// x: 'x',
height
,
// y: 'y',
marginTop
,
// ci: 0.5,
marginRight
,
// stroke: line_color,
marginBottom
,
// fill: shadow_color,
marginLeft
,
// fillOpacity: ret.shadow_opacity || 0.5
titleConfig
,
// }),
colors
,
Plot
.
text
([
ret
.
title
||
''
],
{
legendData
,
x
:
1
,
legendPosition
,
fill
:
ret
.
title_font_color
||
'currentColor'
,
ellipticOne
,
fontSize
:
ret
.
title_font_size
||
20
,
ellipticAD
,
fontStyle
:
ret
.
title_font_style
?
'oblique'
:
'normal'
,
ellipticNon_AD
fontFamily
:
ret
.
title_font_family
||
'Arial'
,
};
fontWeight
:
ret
.
title_font_weight
?
'bold'
:
'normal'
,
frameAnchor
:
'top'
,
setChart
(
configObj
,
data
);
textAnchor
:
'start'
})
svgInstance
.
value
=
svg
.
node
();
]
});
// Append the SVG element.
chartRef
.
value
.
appendChild
(
plotInstance
.
value
);
chartRef
.
value
.
appendChild
(
svgInstance
.
value
);
};
const
setChart
=
(
config
,
data
)
=>
{
const
color
=
setColor
(
config
);
const
{
x
,
y
}
=
setScale
(
config
,
data
);
let
configObj
=
{
...
config
,
color
,
x
,
y
};
// rect && elliptic
setElliptic
(
configObj
);
// rects
const
points
=
setPoint
(
configObj
,
data
);
// tips
setTips
(
points
);
// axis
setAxis
(
configObj
);
// legend
config
.
show_legend
&&
setLegend
(
configObj
);
// label
setLabel
(
configObj
);
};
};
onMounted
(()
=>
{
onMounted
(()
=>
{
const
chartData
=
chartMockData
;
pubSubInstance
.
value
=
PubSub
.
subscribe
(
'options'
,
(
m
,
data
)
=>
{
pubSubInstance
.
value
=
PubSub
.
subscribe
(
'options'
,
(
m
,
data
)
=>
{
options
.
value
=
data
;
options
.
value
=
data
;
chartRef
.
value
.
removeChild
(
plot
Instance
.
value
);
chartRef
.
value
.
removeChild
(
svg
Instance
.
value
);
generateChart
(
chartData
);
generateChart
(
chartData
);
});
});
generateChart
(
chartData
);
generateChart
(
chartData
);
...
@@ -117,4 +149,12 @@ onUnmounted(() => {
...
@@ -117,4 +149,12 @@ onUnmounted(() => {
});
});
</
script
>
</
script
>
<
style
scoped
></
style
>
<
style
scoped
>
.chart-box
{
position
:
relative
;
}
.main
{
width
:
500px
;
overflow
:
hidden
;
}
</
style
>
src/components/PcaAnalysis/components/config.vue
浏览文件 @
bff4fbe7
...
@@ -26,6 +26,10 @@
...
@@ -26,6 +26,10 @@
<input
type=
"text"
v-model=
"dynamic_parameter.margin_left"
/>
<input
type=
"text"
v-model=
"dynamic_parameter.margin_left"
/>
</div>
</div>
<h3
class=
"type content"
>
文本
</h3>
<h3
class=
"type content"
>
文本
</h3>
<div
class=
"form-item"
>
<span>
标题:
</span>
<input
type=
"text"
v-model=
"dynamic_parameter.title"
/>
</div>
<div
class=
"form-item"
>
<div
class=
"form-item"
>
<span>
字体:
</span>
<span>
字体:
</span>
<input
type=
"text"
v-model=
"dynamic_parameter.title_font_family"
/>
<input
type=
"text"
v-model=
"dynamic_parameter.title_font_family"
/>
...
@@ -55,10 +59,6 @@
...
@@ -55,10 +59,6 @@
<span>
显示刻度线:
</span>
<span>
显示刻度线:
</span>
<input
type=
"checkbox"
v-model=
"dynamic_parameter.show_x_tickMarks"
/>
<input
type=
"checkbox"
v-model=
"dynamic_parameter.show_x_tickMarks"
/>
</div>
</div>
<div
class=
"form-item"
>
<span>
显示网格:
</span>
<input
type=
"checkbox"
v-model=
"dynamic_parameter.show_x_gridLine"
/>
</div>
<div
class=
"form-item"
>
<div
class=
"form-item"
>
<span>
刻度线颜色:
</span>
<span>
刻度线颜色:
</span>
<input
type=
"text"
v-model=
"dynamic_parameter.x_tickMarks_color"
/>
<input
type=
"text"
v-model=
"dynamic_parameter.x_tickMarks_color"
/>
...
@@ -88,7 +88,11 @@
...
@@ -88,7 +88,11 @@
<input
type=
"checkbox"
v-model=
"dynamic_parameter.xtitle_font_style"
/>
<input
type=
"checkbox"
v-model=
"dynamic_parameter.xtitle_font_style"
/>
</div>
</div>
<div
class=
"form-item"
>
<div
class=
"form-item"
>
<span>
x轴标题:
</span>
<span>
标题展示:
</span>
<input
type=
"checkbox"
v-model=
"dynamic_parameter.show_x_title"
/>
</div>
<div
class=
"form-item"
>
<span>
标题:
</span>
<input
type=
"text"
v-model=
"dynamic_parameter.x_title"
/>
<input
type=
"text"
v-model=
"dynamic_parameter.x_title"
/>
</div>
</div>
<h3
class=
"type content"
>
Y轴配置
</h3>
<h3
class=
"type content"
>
Y轴配置
</h3>
...
@@ -100,10 +104,6 @@
...
@@ -100,10 +104,6 @@
<span>
显示刻度线:
</span>
<span>
显示刻度线:
</span>
<input
type=
"checkbox"
v-model=
"dynamic_parameter.show_y_tickMarks"
/>
<input
type=
"checkbox"
v-model=
"dynamic_parameter.show_y_tickMarks"
/>
</div>
</div>
<div
class=
"form-item"
>
<span>
显示网格:
</span>
<input
type=
"checkbox"
v-model=
"dynamic_parameter.show_y_gridLine"
/>
</div>
<div
class=
"form-item"
>
<div
class=
"form-item"
>
<span>
刻度线颜色:
</span>
<span>
刻度线颜色:
</span>
<input
type=
"text"
v-model=
"dynamic_parameter.y_tickMarks_color"
/>
<input
type=
"text"
v-model=
"dynamic_parameter.y_tickMarks_color"
/>
...
@@ -133,23 +133,22 @@
...
@@ -133,23 +133,22 @@
<input
type=
"checkbox"
v-model=
"dynamic_parameter.ytitle_font_style"
/>
<input
type=
"checkbox"
v-model=
"dynamic_parameter.ytitle_font_style"
/>
</div>
</div>
<div
class=
"form-item"
>
<div
class=
"form-item"
>
<span>
x轴标题:
</span>
<span>
标题展示:
</span>
<input
type=
"text"
v-model=
"dynamic_parameter.y_title"
/>
<input
type=
"checkbox"
v-model=
"dynamic_parameter.show_y_title"
/>
</div>
<h3
class=
"type content"
>
图表配置
</h3>
<div
class=
"form-item"
>
<span>
散点图半径:
</span>
<input
type=
"text"
v-model=
"dynamic_parameter.point_radius"
/>
</div>
</div>
<div
class=
"form-item"
>
<div
class=
"form-item"
>
<span>
阴影透明度
:
</span>
<span>
标题
:
</span>
<input
type=
"text"
v-model=
"dynamic_parameter.
shadow_opacity
"
/>
<input
type=
"text"
v-model=
"dynamic_parameter.
y_title
"
/>
</div>
</div>
<h3
class=
"type content"
>
图例
</h3>
<h3
class=
"type content"
>
图例
</h3>
<div
class=
"form-item"
>
<div
class=
"form-item"
>
<span>
显示图例:
</span>
<span>
显示图例:
</span>
<input
type=
"checkbox"
v-model=
"dynamic_parameter.show_legend"
/>
<input
type=
"checkbox"
v-model=
"dynamic_parameter.show_legend"
/>
</div>
</div>
<div
class=
"form-item"
>
<span>
图例位置:
</span>
<input
type=
"text"
v-model=
"dynamic_parameter.legend_position"
/>
</div>
<div
class=
"btn"
>
<div
class=
"btn"
>
<button
@
click=
"submit"
>
提交
</button>
<button
@
click=
"submit"
>
提交
</button>
</div>
</div>
...
@@ -165,39 +164,39 @@ const dynamic_parameter = reactive({
...
@@ -165,39 +164,39 @@ const dynamic_parameter = reactive({
//长宽间距
//长宽间距
chart_width
:
700
,
chart_width
:
700
,
chart_height
:
800
,
chart_height
:
800
,
margin_top
:
6
0
,
margin_top
:
12
0
,
margin_right
:
6
0
,
margin_right
:
12
0
,
margin_bottom
:
6
0
,
margin_bottom
:
12
0
,
margin_left
:
6
0
,
margin_left
:
12
0
,
//标题配置
//标题配置
title
:
''
,
title
:
'
Principal
'
,
title_font_family
:
'Arial'
,
title_font_family
:
'Arial'
,
title_font_weight
:
true
,
title_font_weight
:
true
,
title_font_size
:
20
,
title_font_size
:
20
,
title_font_color
:
'#333333'
,
title_font_color
:
'#333333'
,
title_font_style
:
tru
e
,
title_font_style
:
fals
e
,
//横轴标题
//横轴标题
xtitle_font_family
:
'Arial'
,
xtitle_font_family
:
'Arial'
,
xtitle_font_weight
:
false
,
xtitle_font_weight
:
false
,
xtitle_font_style
:
false
,
xtitle_font_style
:
false
,
xtitle_font_size
:
1
6
,
xtitle_font_size
:
1
4
,
xtitle_font_color
:
'#333333'
,
xtitle_font_color
:
'#333333'
,
//纵轴标题
//纵轴标题
ytitle_font_family
:
'Arial'
,
ytitle_font_family
:
'Arial'
,
ytitle_font_weight
:
false
,
ytitle_font_weight
:
false
,
ytitle_font_style
:
false
,
ytitle_font_style
:
false
,
ytitle_font_size
:
1
6
,
ytitle_font_size
:
1
4
,
ytitle_font_color
:
'#333333'
,
ytitle_font_color
:
'#333333'
,
//颜色设置
//颜色设置
data_color_list
:
[
'#
FF5733'
,
'#39FDBE'
,
'#D6D6D6
'
],
data_color_list
:
[
'#
155C9C'
,
'#44A79D
'
],
point_radius
:
5
,
// 散点图半径
point_radius
:
5
,
// 散点图半径
shadow_opacity
:
0.5
,
// 阴影透明度 0~1
shadow_opacity
:
0.5
,
// 阴影透明度 0~1
//图例
//图例
show_legend
:
true
,
show_legend
:
true
,
legend_position
:
'
1
,1'
,
legend_position
:
'
0.5
,1'
,
//坐标轴
//坐标轴
show_x_axis
:
true
,
show_x_axis
:
true
,
show_x_line
:
true
,
show_x_line
:
true
,
...
@@ -240,7 +239,7 @@ onMounted(() => {
...
@@ -240,7 +239,7 @@ onMounted(() => {
<
style
scoped
>
<
style
scoped
>
.form-item
span
{
.form-item
span
{
display
:
inline-block
;
display
:
inline-block
;
width
:
1
0
0px
;
width
:
1
2
0px
;
text-align
:
left
;
text-align
:
left
;
}
}
.btn
{
.btn
{
...
...
src/components/PcaAnalysis/mock.js
浏览文件 @
bff4fbe7
export
const
chartData
=
[
export
const
chartMockData
=
[
{
type
:
'type1'
,
x
:
'-30'
,
y
:
'-90'
},
{
{
type
:
'type1'
,
x
:
'-30'
,
y
:
'10'
},
"name"
:
"AD"
,
{
type
:
'type1'
,
x
:
'-15'
,
y
:
'20'
},
"PC1"
:
-
13.6199
,
{
type
:
'type1'
,
x
:
'15'
,
y
:
'18'
},
"PC2"
:
19.2571
]
},
\ No newline at end of file
{
"name"
:
"AD"
,
"PC1"
:
-
26.9176
,
"PC2"
:
-
83.0864
},
{
"name"
:
"AD"
,
"PC1"
:
10.7576
,
"PC2"
:
16.4817
},
{
"name"
:
"AD"
,
"PC1"
:
-
26.8031
,
"PC2"
:
10.3311
},
{
"name"
:
"Non_AD"
,
"PC1"
:
-
31.6168
,
"PC2"
:
11.5461
},
{
"name"
:
"Non_AD"
,
"PC1"
:
122.4475
,
"PC2"
:
-
8.1394
},
{
"name"
:
"Non_AD"
,
"PC1"
:
-
5.0412
,
"PC2"
:
19.3962
},
{
"name"
:
"Non_AD"
,
"PC1"
:
-
29.2065
,
"PC2"
:
14.2135
}
]
src/components/PcaAnalysis/utils/index.js
0 → 100644
浏览文件 @
bff4fbe7
import
*
as
d3
from
'https://cdn.jsdelivr.net/npm/d3@7/+esm'
;
// color config
export
const
setColor
=
(
config
)
=>
{
let
colors
=
[
'#2265A1'
,
'#44A79D'
];
if
(
Array
.
isArray
(
config
.
colors
))
{
colors
=
!!
config
.
colors
.
length
?
config
.
colors
:
colors
;
}
else
if
(
!!
config
.
colors
)
{
colors
=
config
.
colors
.
split
(
','
);
}
return
d3
.
scaleOrdinal
(
colors
).
domain
(
config
.
legendData
);
};
// tips
export
const
setTips
=
(
rect
)
=>
{
const
tips
=
d3
.
select
(
'.tip'
)
.
style
(
'visibility'
,
'hidden'
)
.
style
(
'position'
,
'relative'
)
.
style
(
'background-color'
,
'rgba(0, 0, 0, .8)'
)
.
style
(
'color'
,
'#fff'
)
.
style
(
'border-radius'
,
'5px'
)
.
style
(
'width'
,
'120px'
)
.
style
(
'height'
,
'65px'
)
.
style
(
'text-align'
,
'left'
)
.
style
(
'padding'
,
'5px 10px'
)
rect
.
on
(
'mouseover'
,
(
event
,
d
)
=>
{
tips
.
style
(
'visibility'
,
'visible'
);
})
.
on
(
'mousemove'
,
function
(
event
,
d
)
{
tips
.
style
(
'visibility'
,
'visible'
)
.
style
(
'left'
,
event
.
offsetX
+
15
+
'px'
)
.
style
(
'top'
,
event
.
offsetY
+
55
+
'px'
)
.
html
(
`
<div>
${
d
.
name
}
</div>
<div>x:
${
d
.
PC1
}
</div>
<div>y:
${
d
.
PC2
}
</div>
`
);
})
.
on
(
'mouseleave'
,
function
()
{
tips
.
style
(
'visibility'
,
'hidden'
);
});
};
// legend
export
const
setLegend
=
(
config
)
=>
{
const
g
=
config
.
svg
.
append
(
'g'
)
.
attr
(
'transform'
,
`translate(
${(
config
.
width
-
210
)
*
config
.
legendPosition
[
0
]}
,
${(
config
.
height
-
35
)
*
config
.
legendPosition
[
1
]}
)`
)
g
.
append
(
'rect'
).
attr
(
'width'
,
200
)
.
attr
(
'height'
,
30
)
.
attr
(
'stroke'
,
'black'
)
.
attr
(
"stroke-width"
,
2
)
.
attr
(
'fill'
,
'transparent'
)
g
.
append
(
'g'
)
.
attr
(
'transform'
,
`translate(0, 15)`
)
.
selectAll
()
.
data
(
config
.
legendData
)
.
join
(
'g'
)
.
attr
(
'transform'
,
(
d
,
i
)
=>
`translate(
${
i
*
90
+
20
}
, 0)`
)
.
call
((
g
)
=>
g
.
append
(
"path"
)
.
attr
(
"class"
,
"dot"
)
.
attr
(
"opacity"
,
1
)
.
attr
(
"stroke-opacity"
,
1
)
.
attr
(
"stroke-width"
,
2
)
.
attr
(
"stroke"
,
(
d
)
=>
config
.
color
(
d
))
.
attr
(
"fill"
,
'transparent'
)
.
attr
(
"fill-opacity"
,
1
)
.
attr
(
"d"
,
(
d
)
=>
setSymbol
(
d
)))
.
call
((
g
)
=>
g
.
append
(
'text'
)
.
attr
(
'x'
,
15
)
.
attr
(
'y'
,
0
)
.
attr
(
'dy'
,
'0.3em'
)
.
style
(
'font'
,
'13px sans-serif'
)
.
text
((
d
)
=>
d
)
);
};
// scale
export
const
setScale
=
(
config
,
data
)
=>
{
const
xMax
=
d3
.
max
(
data
,
(
d
)
=>
d
.
PC1
)
const
xMin
=
d3
.
min
(
data
,
(
d
)
=>
d
.
PC1
)
const
yMax
=
d3
.
min
(
data
,
(
d
)
=>
d
.
PC2
)
const
yMin
=
d3
.
min
(
data
,
(
d
)
=>
d
.
PC2
)
const
xDomain
=
(
Math
.
abs
(
xMax
)
>=
Math
.
abs
(
xMin
)
?
Math
.
abs
(
xMax
)
:
Math
.
abs
(
xMin
))
+
10
const
yDomain
=
(
Math
.
abs
(
yMax
)
>=
Math
.
abs
(
yMin
)
?
Math
.
abs
(
yMax
)
:
Math
.
abs
(
yMin
))
+
10
const
x
=
d3
.
scaleLinear
()
.
domain
([
-
xDomain
,
xDomain
])
.
range
([
config
.
marginLeft
,
config
.
width
-
config
.
marginRight
])
const
y
=
d3
.
scaleLinear
()
.
domain
([
-
yDomain
,
yDomain
])
.
range
([
config
.
height
-
config
.
marginBottom
,
config
.
marginTop
])
return
{
x
,
y
}
}
// axis
export
const
setAxis
=
(
config
)
=>
{
config
.
show_x_axis
&&
config
.
svg
.
append
(
'g'
)
.
attr
(
'transform'
,
`translate(0,
${
config
.
height
-
config
.
marginBottom
}
)`
)
.
style
(
'font'
,
`
${
config
.
xtitle_font_size
}
px
${
config
.
xtitle_font_family
}
`
)
.
style
(
'color'
,
`
${
config
.
xtitle_font_color
}
`
)
.
style
(
'font-weight'
,
`
${
config
.
xtitle_font_weight
?
'bold'
:
'normal'
}
`
)
.
style
(
'font-style'
,
`
${
config
.
xtitle_font_style
?
'oblique'
:
'normal'
}
`
)
.
call
(
d3
.
axisBottom
(
config
.
x
).
tickSize
(
Number
(
config
.
show_x_tickMarks
?
config
.
x_tickMarks_length
:
0
)))
.
call
(
g
=>
g
.
selectAll
(
"line"
).
clone
()
.
attr
(
"display"
,
d
=>
d
==
0
?
'block'
:
'none'
)
.
attr
(
"stroke-dasharray"
,
'3'
)
.
attr
(
"y2"
,
-
(
config
.
height
-
config
.
marginBottom
-
config
.
marginTop
))
)
.
call
((
g
)
=>
g
.
selectAll
(
'.domain'
).
remove
())
.
selectAll
(
'text'
)
.
style
(
'text-anchor'
,
'middle'
);
config
.
show_x_title
&&
config
.
svg
.
append
(
'g'
)
.
attr
(
'transform'
,
`translate(
${
config
.
width
/
2
}
,
${
config
.
height
-
config
.
marginBottom
+
50
}
)`
)
.
append
(
'text'
)
.
style
(
'text-anchor'
,
'middle'
)
.
text
(
config
.
x_title
)
config
.
show_y_axis
&&
config
.
svg
.
append
(
'g'
)
.
attr
(
'transform'
,
`translate(
${
config
.
marginLeft
}
, 0)`
)
.
style
(
'font'
,
`
${
config
.
ytitle_font_size
}
px
${
config
.
ytitle_font_family
}
`
)
.
style
(
'color'
,
`
${
config
.
ytitle_font_color
}
`
)
.
style
(
'font-weight'
,
`
${
config
.
ytitle_font_weight
?
'bold'
:
'normal'
}
`
)
.
style
(
'font-style'
,
`
${
config
.
ytitle_font_style
?
'oblique'
:
'normal'
}
`
)
.
call
(
d3
.
axisLeft
(
config
.
y
).
tickSize
(
Number
(
config
.
show_y_tickMarks
?
config
.
y_tickMarks_length
:
0
)))
.
call
(
g
=>
g
.
selectAll
(
"line"
).
clone
()
.
attr
(
"display"
,
d
=>
d
==
0
?
'block'
:
'none'
)
.
attr
(
"stroke-dasharray"
,
'3'
)
.
attr
(
"x2"
,
config
.
width
-
config
.
marginLeft
-
config
.
marginRight
))
.
call
((
g
)
=>
g
.
selectAll
(
'.domain'
).
remove
())
config
.
show_y_title
&&
config
.
svg
.
append
(
'g'
)
.
attr
(
'transform'
,
`translate(
${
config
.
marginLeft
-
50
}
,
${
config
.
height
/
2
}
)`
)
.
append
(
'text'
)
.
style
(
'text-anchor'
,
'middle'
)
.
attr
(
'transform'
,
`rotate(-90)`
)
.
text
(
config
.
y_title
)
}
// symbols
export
const
setSymbol
=
(
type
)
=>
{
let
symbol
=
d3
.
symbol
().
size
(
30
)
return
type
==
'AD'
?
symbol
.
type
(
d3
.
symbols
[
0
])()
:
symbol
.
type
(
d3
.
symbols
[
5
])()
}
// rect && elliptic
export
const
setElliptic
=
(
config
)
=>
{
let
rects
=
config
.
svg
.
append
(
'g'
)
.
attr
(
'max-width'
,
config
.
width
-
config
.
marginLeft
-
config
.
marginRight
)
.
attr
(
'height'
,
config
.
height
-
config
.
marginTop
-
config
.
marginBottom
);
rects
.
append
(
'rect'
)
.
attr
(
'x'
,
`
${
config
.
marginLeft
}
`
)
.
attr
(
'y'
,
`
${
config
.
marginTop
}
`
)
.
attr
(
'width'
,
`
${
config
.
width
-
config
.
marginLeft
-
config
.
marginRight
}
`
)
.
attr
(
'height'
,
`
${
config
.
height
-
config
.
marginTop
-
config
.
marginBottom
}
`
)
.
attr
(
'stroke'
,
'#000000'
)
.
attr
(
'stroke-width'
,
2
)
.
attr
(
'fill'
,
'white'
);
rects
.
append
(
'ellipse'
)
.
attr
(
'cx'
,
`
${
config
.
ellipticOne
.
cx
}
`
)
.
attr
(
'cy'
,
`
${
config
.
ellipticOne
.
cy
}
`
)
.
attr
(
'rx'
,
`
${
config
.
ellipticOne
.
rx
}
`
)
.
attr
(
'ry'
,
`
${
config
.
ellipticOne
.
ry
}
`
)
.
attr
(
'stroke'
,
'#ADADAD'
)
.
attr
(
'stroke-width'
,
3
)
.
attr
(
'fill'
,
'transparent'
);
rects
.
append
(
'ellipse'
)
.
attr
(
'cx'
,
`
${
config
.
ellipticAD
.
cx
}
`
)
.
attr
(
'cy'
,
`
${
config
.
ellipticAD
.
cy
}
`
)
.
attr
(
'rx'
,
`
${
config
.
ellipticAD
.
rx
}
`
)
.
attr
(
'ry'
,
`
${
config
.
ellipticAD
.
ry
}
`
)
.
attr
(
'transform-origin'
,
'center'
)
.
attr
(
'transform'
,
`rotate(
${
config
.
ellipticAD
.
rotate
}
)`
)
.
attr
(
'fill'
,
config
.
ellipticAD
.
fill
)
.
attr
(
'fill-opacity'
,
config
.
ellipticAD
.
fillOpacity
);
rects
.
append
(
'ellipse'
)
.
attr
(
'cx'
,
`
${
config
.
ellipticNon_AD
.
cx
}
`
)
.
attr
(
'cy'
,
`
${
config
.
ellipticNon_AD
.
cy
}
`
)
.
attr
(
'rx'
,
`
${
config
.
ellipticNon_AD
.
rx
}
`
)
.
attr
(
'ry'
,
`
${
config
.
ellipticNon_AD
.
ry
}
`
)
.
attr
(
'transform-origin'
,
'center'
)
.
attr
(
'transform'
,
`rotate(
${
config
.
ellipticNon_AD
.
rotate
}
)`
)
.
attr
(
'fill'
,
config
.
ellipticNon_AD
.
fill
)
.
attr
(
'fill-opacity'
,
config
.
ellipticNon_AD
.
fillOpacity
);
}
// point
export
const
setPoint
=
(
config
,
data
)
=>
{
return
config
.
svg
.
append
(
"g"
)
.
selectAll
(
"path"
)
.
data
(
data
)
.
join
(
"path"
)
.
attr
(
"class"
,
"dot"
)
.
attr
(
"opacity"
,
1
)
.
attr
(
"stroke-opacity"
,
1
)
.
attr
(
"stroke-width"
,
2
)
.
attr
(
"stroke"
,
(
d
)
=>
config
.
color
(
d
.
name
))
.
attr
(
"fill"
,
'transparent'
)
.
attr
(
"fill-opacity"
,
1
)
.
attr
(
"d"
,
(
d
)
=>
setSymbol
(
d
.
name
))
.
attr
(
"transform"
,
d
=>
`translate(
${
config
.
x
(
d
.
PC1
)}
,
${
config
.
y
(
d
.
PC2
)}
)`
)
}
// title
export
const
setLabel
=
(
config
)
=>
{
config
.
svg
.
append
(
'text'
)
.
attr
(
'x'
,
config
.
width
/
2
)
.
attr
(
'y'
,
config
.
marginTop
-
50
)
.
attr
(
'fill'
,
config
.
titleConfig
.
color
)
.
attr
(
'font-size'
,
`
${
config
.
titleConfig
.
fontSize
}
px`
)
.
attr
(
'font-family'
,
`
${
config
.
titleConfig
.
fontFamily
}
`
)
.
attr
(
'font-style'
,
`
${
config
.
titleConfig
.
fontStyle
}
`
)
.
attr
(
'font-weight'
,
`
${
config
.
titleConfig
.
fontWeight
}
`
)
.
style
(
'text-anchor'
,
'middle'
)
.
text
(
`
${
config
.
titleConfig
.
label
}
`
);
};
src/components/Test/index.vue
浏览文件 @
bff4fbe7
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
import
{
ref
,
onMounted
}
from
'vue'
;
import
{
ref
,
onMounted
}
from
'vue'
;
import
{
chartMockData
}
from
'./mock.js'
;
import
{
chartMockData
}
from
'./mock.js'
;
import
*
as
d3
from
'https://cdn.jsdelivr.net/npm/d3@7/+esm'
;
import
*
as
d3
from
'https://cdn.jsdelivr.net/npm/d3@7/+esm'
;
import
{
setTips
,
set
MaxMinNumber
,
setLegend
,
setScale
,
setAxis
,
setRect
,
setTopLeftColor
,
getRootConfig
,
setTree
}
from
'./utils'
;
import
{
setTips
,
set
Color
,
setLegend
,
setScale
,
setAxis
,
setPoint
,
setLabel
,
setElliptic
}
from
'./utils'
;
const
chartRef
=
ref
(
null
);
const
chartRef
=
ref
(
null
);
...
@@ -19,21 +19,17 @@ const options = ref({});
...
@@ -19,21 +19,17 @@ const options = ref({});
const
generateChart
=
(
data
)
=>
{
const
generateChart
=
(
data
)
=>
{
const
ret
=
options
.
value
;
const
ret
=
options
.
value
;
let
width
=
10
00
;
let
width
=
7
00
;
let
height
=
7
00
;
let
height
=
8
00
;
let
marginTop
=
120
;
let
marginTop
=
120
;
let
marginRight
=
120
;
let
marginRight
=
120
;
let
marginBottom
=
6
0
;
let
marginBottom
=
12
0
;
let
marginLeft
=
120
;
let
marginLeft
=
120
;
let
dendWidth
=
100
;
let
legendData
=
[
'AD'
,
'Non_AD'
];
let
legendData
=
[
0.8
,
0.85
,
0.9
,
0.95
,
1
];
let
legendPosition
=
[
0.5
,
1
];
let
colorList
=
[
let
colors
=
[
'#155C9C'
,
'#44A79D'
];
[
'#3DD378'
,
'#EC0B88'
,
'#444444'
,
'#5E35B1'
,
'#F9791E'
,
'#C6C6C6'
,
'#F7DC05'
,
'#3D98D3'
],
[
'#017A4A'
,
'#FFCE4E'
,
'#3D98D3'
,
'#FF363C'
,
'#794924'
,
'#8CDB5E'
,
'#D6D6D6'
,
'#FB8C00'
]
];
let
legendPosition
=
[
0
,
0
];
let
heatWidth
=
width
-
marginLeft
-
marginRight
;
// 标题配置
const
titleConfig
=
{
const
titleConfig
=
{
label
:
!!
ret
.
title
?
ret
.
title
:
null
,
label
:
!!
ret
.
title
?
ret
.
title
:
null
,
color
:
ret
.
title_font_color
||
'#333333'
,
color
:
ret
.
title_font_color
||
'#333333'
,
...
@@ -43,6 +39,32 @@ const generateChart = (data) => {
...
@@ -43,6 +39,32 @@ const generateChart = (data) => {
fontWeight
:
ret
.
title_font_weight
?
'bold'
:
'normal'
fontWeight
:
ret
.
title_font_weight
?
'bold'
:
'normal'
};
};
// 大椭圆
let
ellipticOne
=
{
rx
:
(
width
-
marginLeft
-
marginRight
)
/
2
-
20
,
ry
:
(
height
-
marginTop
-
marginBottom
)
/
2
-
20
,
cx
:
(
marginLeft
+
width
-
marginLeft
-
marginRight
)
/
2
+
60
,
cy
:
(
marginTop
+
height
-
marginTop
-
marginBottom
)
/
2
+
60
};
// 椭圆 AD
let
ellipticAD
=
{
rx
:
80
,
ry
:
350
,
cx
:
(
marginLeft
+
width
-
marginLeft
-
marginRight
)
/
2
+
60
,
cy
:
(
marginTop
+
height
-
marginTop
-
marginBottom
)
/
2
+
60
,
rotate
:
10
};
// 椭圆 Non_AD
let
ellipticNon_AD
=
{
rx
:
350
,
ry
:
60
,
cx
:
(
marginLeft
+
width
-
marginLeft
-
marginRight
)
/
2
+
60
,
cy
:
(
marginTop
+
height
-
marginTop
-
marginBottom
)
/
2
+
20
,
rotate
:
20
};
const
svg
=
d3
.
create
(
'svg'
).
attr
(
'width'
,
width
).
attr
(
'height'
,
height
);
const
svg
=
d3
.
create
(
'svg'
).
attr
(
'width'
,
width
).
attr
(
'height'
,
height
);
let
configObj
=
{
let
configObj
=
{
...
@@ -53,12 +75,13 @@ const generateChart = (data) => {
...
@@ -53,12 +75,13 @@ const generateChart = (data) => {
marginRight
,
marginRight
,
marginBottom
,
marginBottom
,
marginLeft
,
marginLeft
,
dendWidth
,
titleConfig
,
titleConfig
,
colors
,
legendData
,
legendData
,
colorList
,
legendPosition
,
heatWidth
,
ellipticOne
,
legendPosition
ellipticAD
,
ellipticNon_AD
};
};
setChart
(
configObj
,
data
);
setChart
(
configObj
,
data
);
...
@@ -68,45 +91,33 @@ const generateChart = (data) => {
...
@@ -68,45 +91,33 @@ const generateChart = (data) => {
};
};
const
setChart
=
(
config
,
data
)
=>
{
const
setChart
=
(
config
,
data
)
=>
{
const
categories
=
data
.
map
((
d
)
=>
d
.
index
);
const
color
=
setColor
(
config
);
const
newArr
=
data
.
map
((
d
)
=>
Object
.
keys
(
d
).
map
((
e
)
=>
d
[
e
])).
map
((
item
)
=>
({
index
:
item
[
0
],
values
:
item
.
slice
(
1
)
}));
const
{
x
,
y
}
=
setScale
(
config
,
data
);
const
{
maxNumber
,
minNumber
}
=
setMaxMinNumber
(
data
);
const
color
=
d3
.
scaleSequential
([
minNumber
,
maxNumber
],
d3
.
interpolateMagma
);
let
configObj
=
{
let
configObj
=
{
...
config
,
...
config
,
categories
,
color
,
color
};
const
{
x
,
y
}
=
setScale
(
config
,
categories
);
const
{
root
}
=
getRootConfig
(
config
,
newArr
);
configObj
=
{
...
configObj
,
root
,
x
,
x
,
y
y
};
};
// elliptic
setElliptic
(
configObj
);
// rects
// rects
const
rects
=
setRec
t
(
configObj
,
data
);
const
points
=
setPoin
t
(
configObj
,
data
);
// tips
// tips
setTips
(
rec
ts
);
setTips
(
poin
ts
);
// axis
// axis
setAxis
(
configObj
);
setAxis
(
configObj
);
// topLeftColor
setTopLeftColor
(
configObj
,
data
);
// legend
// legend
setLegend
(
configObj
);
setLegend
(
configObj
);
//
tree
//
label
set
Tree
(
configObj
);
set
Label
(
configObj
);
};
};
onMounted
(()
=>
{
onMounted
(()
=>
{
...
@@ -119,4 +130,8 @@ onMounted(() => {
...
@@ -119,4 +130,8 @@ onMounted(() => {
.chart-box
{
.chart-box
{
position
:
relative
;
position
:
relative
;
}
}
.main
{
width
:
500px
;
overflow
:
hidden
;
}
</
style
>
</
style
>
src/components/Test/mock.js
浏览文件 @
bff4fbe7
export
const
chartMockData
=
[
export
const
chartMockData
=
[
{
{
"index"
:
"AD1"
,
"name"
:
"AD"
,
"AD1"
:
"1"
,
"x"
:
-
13.6199
,
"AD2"
:
"0.84"
,
"y"
:
19.2571
"AD3"
:
"0.83"
,
"AD4"
:
"0.9"
,
"Non_AD_5"
:
"0.95"
,
"Non_AD_6"
:
"0.81"
,
"Non_AD_7"
:
"0.98"
,
"Non_AD_8"
:
"1.0"
,
},
},
{
{
"index"
:
"AD2"
,
"name"
:
"AD"
,
"AD1"
:
"0.8"
,
"x"
:
-
26.9176
,
"AD2"
:
"0.9"
,
"y"
:
-
83.0864
"AD3"
:
"0.85"
,
"AD4"
:
"0.95"
,
"Non_AD_5"
:
"1"
,
"Non_AD_6"
:
"0.92"
,
"Non_AD_7"
:
"0.91"
,
"Non_AD_8"
:
"0.81"
,
},
},
{
{
"index"
:
"AD3"
,
"name"
:
"AD"
,
"AD1"
:
"1"
,
"x"
:
10.7576
,
"AD2"
:
"0.99"
,
"y"
:
16.4817
"AD3"
:
"0.91"
,
"AD4"
:
"0.98"
,
"Non_AD_5"
:
"0.95"
,
"Non_AD_6"
:
"0.93"
,
"Non_AD_7"
:
"0.94"
,
"Non_AD_8"
:
"1.0"
,
},
},
{
{
"index"
:
"AD4"
,
"name"
:
"AD"
,
"AD1"
:
"0.99"
,
"x"
:
-
26.8031
,
"AD2"
:
"0.81"
,
"y"
:
10.3311
"AD3"
:
"0.82"
,
"AD4"
:
"0.93"
,
"Non_AD_5"
:
"0.99"
,
"Non_AD_6"
:
"0.98"
,
"Non_AD_7"
:
"0.91"
,
"Non_AD_8"
:
"0.97"
,
},
},
{
{
"index"
:
"Non_AD_5"
,
"name"
:
"Non_AD"
,
"AD1"
:
"0.99"
,
"x"
:
-
31.6168
,
"AD2"
:
"0.98"
,
"y"
:
11.5461
"AD3"
:
"0.97"
,
"AD4"
:
"0.95"
,
"Non_AD_5"
:
"0.91"
,
"Non_AD_6"
:
"0.99"
,
"Non_AD_7"
:
"0.98"
,
"Non_AD_8"
:
"0.95"
,
},
},
{
{
"index"
:
"Non_AD_6"
,
"name"
:
"Non_AD"
,
"AD1"
:
"0.98"
,
"x"
:
122.4475
,
"AD2"
:
"0.97"
,
"y"
:
-
8.1394
"AD3"
:
"0.92"
,
"AD4"
:
"0.9"
,
"Non_AD_5"
:
"0.95"
,
"Non_AD_6"
:
"0.99"
,
"Non_AD_7"
:
"0.89"
,
"Non_AD_8"
:
"0.87"
,
},
},
{
{
"index"
:
"Non_AD_7"
,
"name"
:
"Non_AD"
,
"AD1"
:
"0.99"
,
"x"
:
-
5.0412
,
"AD2"
:
"0.98"
,
"y"
:
19.3962
"AD3"
:
"0.89"
,
"AD4"
:
"0.91"
,
"Non_AD_5"
:
"0.92"
,
"Non_AD_6"
:
"0.89"
,
"Non_AD_7"
:
"0.92"
,
"Non_AD_8"
:
"1"
,
},
},
{
{
"index"
:
"Non_AD_8"
,
"name"
:
"Non_AD"
,
"AD1"
:
"0.96"
,
"x"
:
-
29.2065
,
"AD2"
:
"0.99"
,
"y"
:
14.2135
"AD3"
:
"0.97"
,
"AD4"
:
"0.94"
,
"Non_AD_5"
:
"0.94"
,
"Non_AD_6"
:
"0.89"
,
"Non_AD_7"
:
"0.91"
,
"Non_AD_8"
:
"1"
,
}
}
]
]
src/components/Test/utils.js
浏览文件 @
bff4fbe7
import
*
as
d3
from
'https://cdn.jsdelivr.net/npm/d3@7/+esm'
;
import
*
as
d3
from
'https://cdn.jsdelivr.net/npm/d3@7/+esm'
;
import
hcluster
from
'../../utils/hcluster'
;
// max min
export
const
setMaxMinNumber
=
(
data
)
=>
{
const
newArr
=
data
.
map
((
d
)
=>
Object
.
keys
(
d
).
map
((
e
)
=>
d
[
e
])).
map
((
f
)
=>
f
.
slice
(
1
))
let
maxNumArr
=
[],
minNumArr
=
[],
maxNumber
=
0
,
minNumber
=
0
;
for
(
let
i
=
0
;
i
<
newArr
.
length
;
i
++
)
{
maxNumArr
.
push
(
d3
.
max
(
newArr
[
i
]));
minNumArr
.
push
(
d3
.
min
(
newArr
[
i
]));
}
// 最大值 最小值
maxNumber
=
d3
.
max
(
maxNumArr
);
minNumber
=
d3
.
min
(
minNumArr
);
return
{
maxNumber
,
minNumber
}
}
// scale
export
const
coordinateScale
=
(
config
,
data
)
=>
{
const
x
=
d3
.
scaleLinear
()
.
domain
([
config
.
paddedMin
,
config
.
paddedMax
])
.
range
([
config
.
marginLeft
,
config
.
width
-
config
.
marginRight
]);
const
y
=
d3
// color config
.
scaleLinear
()
export
const
setColor
=
(
config
)
=>
{
.
domain
(
d3
.
extent
(
data
,
(
d
)
=>
d
.
y
))
let
colors
=
[
'#2265A1'
,
'#44A79D'
];
.
range
([
config
.
rectHeight
,
config
.
marginTop
+
30
]);
if
(
Array
.
isArray
(
config
.
colors
))
{
return
{
colors
=
!!
config
.
colors
.
length
?
config
.
colors
:
colors
;
x
,
y
}
else
if
(
!!
config
.
colors
)
{
colors
=
config
.
colors
.
split
(
','
);
}
}
}
return
d3
.
scaleOrdinal
(
colors
).
domain
(
config
.
legendData
);
};
// tips
// tips
export
const
setTips
=
(
rect
)
=>
{
export
const
setTips
=
(
rect
)
=>
{
...
@@ -48,11 +20,10 @@ export const setTips = (rect) => {
...
@@ -48,11 +20,10 @@ export const setTips = (rect) => {
.
style
(
'background-color'
,
'rgba(0, 0, 0, .8)'
)
.
style
(
'background-color'
,
'rgba(0, 0, 0, .8)'
)
.
style
(
'color'
,
'#fff'
)
.
style
(
'color'
,
'#fff'
)
.
style
(
'border-radius'
,
'5px'
)
.
style
(
'border-radius'
,
'5px'
)
.
style
(
'width'
,
'80px'
)
.
style
(
'width'
,
'120px'
)
.
style
(
'height'
,
'25px'
)
.
style
(
'height'
,
'65px'
)
.
style
(
'line-height'
,
'25px'
)
.
style
(
'text-align'
,
'left'
)
.
style
(
'text-align'
,
'center'
)
.
style
(
'padding'
,
'5px 10px'
)
.
style
(
'padding'
,
'5px'
)
rect
.
on
(
'mouseover'
,
(
event
,
d
)
=>
{
rect
.
on
(
'mouseover'
,
(
event
,
d
)
=>
{
tips
.
style
(
'visibility'
,
'visible'
);
tips
.
style
(
'visibility'
,
'visible'
);
...
@@ -61,7 +32,11 @@ export const setTips = (rect) => {
...
@@ -61,7 +32,11 @@ export const setTips = (rect) => {
tips
.
style
(
'visibility'
,
'visible'
)
tips
.
style
(
'visibility'
,
'visible'
)
.
style
(
'left'
,
event
.
offsetX
+
15
+
'px'
)
.
style
(
'left'
,
event
.
offsetX
+
15
+
'px'
)
.
style
(
'top'
,
event
.
offsetY
+
55
+
'px'
)
.
style
(
'top'
,
event
.
offsetY
+
55
+
'px'
)
.
html
(
`
${
d
.
count
}
`
);
.
html
(
`
<div>
${
d
.
name
}
</div>
<div>x:
${
d
.
x
}
</div>
<div>y:
${
d
.
y
}
</div>
`
);
})
})
.
on
(
'mouseleave'
,
function
()
{
.
on
(
'mouseleave'
,
function
()
{
tips
.
style
(
'visibility'
,
'hidden'
);
tips
.
style
(
'visibility'
,
'hidden'
);
...
@@ -71,173 +46,189 @@ export const setTips = (rect) => {
...
@@ -71,173 +46,189 @@ export const setTips = (rect) => {
// legend
// legend
export
const
setLegend
=
(
config
)
=>
{
export
const
setLegend
=
(
config
)
=>
{
config
.
svg
.
append
(
'g'
)
const
g
=
config
.
svg
.
append
(
'g'
)
.
attr
(
'transform'
,
`translate(
${(
config
.
width
-
100
)
*
config
.
legendPosition
[
0
]}
,
${(
config
.
height
-
100
)
*
config
.
legendPosition
[
1
]}
)`
)
.
attr
(
'transform'
,
`translate(
${(
config
.
width
-
210
)
*
config
.
legendPosition
[
0
]}
,
${(
config
.
height
-
35
)
*
config
.
legendPosition
[
1
]}
)`
)
g
.
append
(
'rect'
).
attr
(
'width'
,
200
)
.
attr
(
'height'
,
30
)
.
attr
(
'stroke'
,
'black'
)
.
attr
(
"stroke-width"
,
2
)
.
attr
(
'fill'
,
'transparent'
)
g
.
append
(
'g'
)
.
attr
(
'transform'
,
`translate(0, 15)`
)
.
selectAll
()
.
selectAll
()
.
data
(
config
.
legendData
)
.
data
(
config
.
legendData
)
.
join
(
'g'
)
.
join
(
'g'
)
.
attr
(
'transform'
,
(
d
,
i
,
nodes
)
=>
`translate(0,
${(
nodes
.
length
-
i
)
*
20
-
20
}
)`
)
.
attr
(
'transform'
,
(
d
,
i
)
=>
`translate(
${
i
*
90
+
20
}
, 0)`
)
.
call
((
g
)
=>
g
.
append
(
'rect'
).
attr
(
'width'
,
40
).
attr
(
'height'
,
20
).
attr
(
'fill'
,
d
=>
config
.
color
(
d
)))
.
call
((
g
)
=>
g
.
append
(
"path"
)
.
attr
(
"class"
,
"dot"
)
.
attr
(
"opacity"
,
1
)
.
attr
(
"stroke-opacity"
,
1
)
.
attr
(
"stroke-width"
,
2
)
.
attr
(
"stroke"
,
(
d
)
=>
config
.
color
(
d
))
.
attr
(
"fill"
,
'transparent'
)
.
attr
(
"fill-opacity"
,
1
)
.
attr
(
"d"
,
(
d
)
=>
setSymbol
(
d
)))
.
call
((
g
)
=>
.
call
((
g
)
=>
g
g
.
append
(
'text'
)
.
append
(
'text'
)
.
attr
(
'x'
,
4
5
)
.
attr
(
'x'
,
1
5
)
.
attr
(
'y'
,
11
)
.
attr
(
'y'
,
0
)
.
attr
(
'dy'
,
'0.3em'
)
.
attr
(
'dy'
,
'0.3em'
)
.
style
(
'font'
,
'13px sans-serif'
)
.
style
(
'font'
,
'13px sans-serif'
)
.
text
((
d
)
=>
d
)
.
text
((
d
)
=>
d
)
);
);
};
};
//
topLeft Color
//
scale
export
const
set
TopLeftColor
=
(
config
,
data
)
=>
{
export
const
set
Scale
=
(
config
,
data
)
=>
{
config
.
svg
const
xMax
=
d3
.
max
(
data
,
(
d
)
=>
d
.
x
)
.
append
(
'g'
)
const
xMin
=
d3
.
min
(
data
,
(
d
)
=>
d
.
x
)
.
attr
(
'transform'
,
`translate(
${
config
.
marginLeft
}
,
${
config
.
marginTop
-
20
}
)`
)
const
yMax
=
d3
.
min
(
data
,
(
d
)
=>
d
.
y
)
.
selectAll
()
const
yMin
=
d3
.
min
(
data
,
(
d
)
=>
d
.
y
)
.
data
(
data
)
.
join
(
'g'
)
const
xDomain
=
(
Math
.
abs
(
xMax
)
>=
Math
.
abs
(
xMin
)
?
Math
.
abs
(
xMax
)
:
Math
.
abs
(
xMin
))
+
10
.
append
(
'rect'
)
const
yDomain
=
(
Math
.
abs
(
yMax
)
>=
Math
.
abs
(
yMin
)
?
Math
.
abs
(
yMax
)
:
Math
.
abs
(
yMin
))
+
10
.
attr
(
'x'
,
(
d
,
i
)
=>
config
.
x
.
bandwidth
()
*
i
)
.
attr
(
'y'
,
0
)
.
attr
(
'width'
,
config
.
x
.
bandwidth
())
.
attr
(
'height'
,
20
)
.
style
(
'fill'
,
(
d
,
i
)
=>
config
.
colorList
[
0
][
i
]);
config
.
svg
.
append
(
'g'
)
.
attr
(
'transform'
,
`translate(
${
config
.
marginLeft
-
20
}
,
${
config
.
marginTop
}
)`
)
.
selectAll
()
.
data
(
data
)
.
join
(
'g'
)
.
append
(
'rect'
)
.
attr
(
'x'
,
(
d
,
i
)
=>
0
)
.
attr
(
'y'
,
(
d
,
i
)
=>
config
.
y
.
bandwidth
()
*
i
)
.
attr
(
'width'
,
20
)
.
attr
(
'height'
,
config
.
y
.
bandwidth
())
.
style
(
'fill'
,
(
d
,
i
)
=>
config
.
colorList
[
1
][
i
]);
}
// scale
export
const
setScale
=
(
config
,
categories
)
=>
{
const
x
=
d3
const
x
=
d3
.
scale
Band
()
.
scale
Linear
()
.
domain
(
categories
)
.
domain
(
[
-
xDomain
,
xDomain
]
)
.
range
([
config
.
marginLeft
,
config
.
width
-
config
.
marginRight
])
;
.
range
([
config
.
marginLeft
,
config
.
width
-
config
.
marginRight
])
const
y
=
d3
const
y
=
d3
.
scale
Band
()
.
scale
Linear
()
.
domain
([
...
categories
].
reverse
()
)
.
domain
([
-
yDomain
,
yDomain
]
)
.
range
([
config
.
height
-
config
.
marginBottom
,
config
.
marginTop
])
;
.
range
([
config
.
height
-
config
.
marginBottom
,
config
.
marginTop
])
return
{
x
,
y
}
return
{
x
,
y
}
}
}
// axis
// axis
export
const
setAxis
=
(
config
)
=>
{
export
const
setAxis
=
(
config
)
=>
{
const
xAxis
=
(
g
)
=>
config
.
svg
.
append
(
'g'
)
g
.
attr
(
'transform'
,
`translate(0,
${
config
.
height
-
config
.
marginBottom
}
)`
)
.
attr
(
'transform'
,
`translate(0,
${
config
.
height
-
config
.
marginBottom
}
)`
)
.
style
(
'font'
,
'12px verdana'
)
// .style('font', '12px verdana')
.
call
(
d3
.
axisBottom
(
config
.
x
).
tickSizeOuter
(
0
))
.
call
(
d3
.
axisBottom
(
config
.
x
).
tickSizeOuter
(
0
))
.
call
(
g
=>
g
.
selectAll
(
"line"
).
clone
()
.
call
((
g
)
=>
g
.
selectAll
(
'.domain'
).
remove
())
.
attr
(
"display"
,
d
=>
d
==
0
?
'block'
:
'none'
)
.
selectAll
(
'text'
)
.
attr
(
"stroke-dasharray"
,
'3'
)
.
style
(
'text-anchor'
,
'middle'
);
.
attr
(
"y2"
,
-
(
config
.
height
-
config
.
marginBottom
-
config
.
marginTop
))
const
yAxis
=
(
g
)
=>
)
g
.
call
((
g
)
=>
g
.
selectAll
(
'.domain'
).
remove
())
.
attr
(
'transform'
,
`translate(
${
config
.
width
-
config
.
marginRight
+
5
}
, 0)`
)
.
selectAll
(
'text'
)
// .style('font', '12px verdana')
.
style
(
'text-anchor'
,
'middle'
);
.
call
(
d3
.
axisLeft
(
config
.
y
).
ticks
(
null
,
's'
))
config
.
svg
.
append
(
'g'
)
.
call
((
g
)
=>
g
.
selectAll
(
'.domain'
).
remove
())
.
attr
(
'transform'
,
`translate(
${
config
.
width
/
2
}
,
${
config
.
height
-
config
.
marginBottom
+
50
}
)`
)
.
selectAll
(
'text'
)
.
append
(
'text'
)
.
style
(
'text-anchor'
,
'start'
)
.
text
(
'PC1 - Proportaion of variance: 0.4'
)
.
attr
(
'transform'
,
`translate(10, 0)`
);
.
style
(
'text-anchor'
,
'middle'
)
config
.
svg
.
append
(
'g'
).
call
(
xAxis
);
config
.
svg
.
append
(
'g'
)
config
.
svg
.
append
(
'g'
).
call
(
yAxis
);
.
attr
(
'transform'
,
`translate(
${
config
.
marginLeft
}
, 0)`
)
.
style
(
'font'
,
'12px verdana'
)
.
call
(
d3
.
axisLeft
(
config
.
y
).
ticks
(
null
,
's'
))
.
call
(
g
=>
g
.
selectAll
(
"line"
).
clone
()
.
attr
(
"display"
,
d
=>
d
==
0
?
'block'
:
'none'
)
.
attr
(
"stroke-dasharray"
,
'3'
)
.
attr
(
"x2"
,
config
.
width
-
config
.
marginLeft
-
config
.
marginRight
))
.
call
((
g
)
=>
g
.
selectAll
(
'.domain'
).
remove
())
config
.
svg
.
append
(
'g'
)
.
attr
(
'transform'
,
`translate(
${
config
.
marginLeft
-
50
}
,
${
config
.
height
/
2
}
)`
)
.
append
(
'text'
)
.
text
(
'PC2 - Proportaion of variance: 0.18'
)
.
style
(
'text-anchor'
,
'middle'
)
.
attr
(
'transform'
,
`rotate(-90)`
)
}
}
// rect
// symbols
export
const
setRect
=
(
config
,
data
)
=>
{
export
const
setSymbol
=
(
type
)
=>
{
const
rects
=
config
.
svg
let
symbol
=
d3
.
symbol
().
size
(
30
)
.
append
(
'g'
)
return
type
==
'AD'
?
symbol
.
type
(
d3
.
symbols
[
0
])()
:
symbol
.
type
(
d3
.
symbols
[
5
])()
.
selectAll
(
'g'
)
}
.
data
(
data
)
.
enter
()
// elliptic
export
const
setElliptic
=
(
config
)
=>
{
let
rects
=
config
.
svg
.
append
(
'g'
)
.
append
(
'g'
)
.
attr
(
'class'
,
(
d
,
i
)
=>
`
${
i
}
bar`
)
.
attr
(
'max-width'
,
config
.
width
-
config
.
marginLeft
-
config
.
marginRight
)
.
selectAll
(
'g'
)
.
attr
(
'height'
,
config
.
height
-
config
.
marginTop
-
config
.
marginBottom
);
.
data
((
d
)
=>
config
.
categories
.
map
((
e
)
=>
{
return
{
xval
:
d
.
index
,
yval
:
e
,
count
:
d
[
e
]
};
})
)
.
enter
()
.
append
(
'g'
);
rects
rects
.
append
(
'rect'
)
.
append
(
'rect'
)
.
attr
(
'x'
,
(
d
)
=>
config
.
x
(
d
.
xval
))
.
attr
(
'x'
,
`
${
config
.
marginLeft
}
`
)
.
attr
(
'y'
,
(
d
)
=>
config
.
y
(
d
.
yval
))
.
attr
(
'y'
,
`
${
config
.
marginTop
}
`
)
.
attr
(
'width'
,
config
.
x
.
bandwidth
())
.
attr
(
'width'
,
`
${
config
.
width
-
config
.
marginLeft
-
config
.
marginRight
}
`
)
.
attr
(
'height'
,
config
.
y
.
bandwidth
())
.
attr
(
'height'
,
`
${
config
.
height
-
config
.
marginTop
-
config
.
marginBottom
}
`
)
.
style
(
'fill'
,
(
d
)
=>
config
.
color
(
d
.
count
));
.
attr
(
'stroke'
,
'#000000'
)
.
attr
(
'stroke-width'
,
2
)
.
attr
(
'fill'
,
'white'
);
return
rects
rects
}
.
append
(
'ellipse'
)
.
attr
(
'cx'
,
`
${
config
.
ellipticOne
.
cx
}
`
)
.
attr
(
'cy'
,
`
${
config
.
ellipticOne
.
cy
}
`
)
.
attr
(
'rx'
,
`
${
config
.
ellipticOne
.
rx
}
`
)
.
attr
(
'ry'
,
`
${
config
.
ellipticOne
.
ry
}
`
)
.
attr
(
'stroke'
,
'#ADADAD'
)
.
attr
(
'stroke-width'
,
3
)
.
attr
(
'fill'
,
'transparent'
);
// root config
rects
export
const
getRootConfig
=
(
config
,
chartData
)
=>
{
.
append
(
'ellipse'
)
const
normalizedData
=
()
=>
{
.
attr
(
'cx'
,
`
${
config
.
ellipticAD
.
cx
}
`
)
let
minmaxes
=
d3
.
attr
(
'cy'
,
`
${
config
.
ellipticAD
.
cy
}
`
)
.
range
(
chartData
[
0
].
values
.
length
)
.
attr
(
'rx'
,
`
${
config
.
ellipticAD
.
rx
}
`
)
.
map
((
d
)
=>
[
d3
.
min
(
chartData
.
map
((
el
)
=>
el
.
values
[
d
])),
d3
.
max
(
chartData
.
map
((
el
)
=>
el
.
values
[
d
]))]);
.
attr
(
'ry'
,
`
${
config
.
ellipticAD
.
ry
}
`
)
return
chartData
.
map
((
el
)
=>
({
.
attr
(
'transform-origin'
,
'center'
)
...
el
,
.
attr
(
'transform'
,
`rotate(
${
config
.
ellipticAD
.
rotate
}
)`
)
normalized
:
el
.
values
.
map
((
n
,
i
)
=>
(
n
-
minmaxes
[
i
][
0
])
/
(
minmaxes
[
i
][
1
]
-
minmaxes
[
i
][
0
]))
.
attr
(
'fill'
,
config
.
colors
[
0
])
}));
.
attr
(
'fill-opacity'
,
0.2
);
};
const
clustering
=
hcluster
().
distance
(
'angular'
).
linkage
(
'avg'
).
posKey
(
'normalized'
).
data
(
normalizedData
());
const
tree
=
(
data
)
=>
{
const
root
=
d3
.
hierarchy
(
data
).
sort
((
a
,
b
)
=>
d3
.
ascending
(
a
.
height
,
b
.
height
));
root
.
dx
=
0
;
root
.
dy
=
config
.
dendWidth
/
(
root
.
height
+
1
);
return
d3
.
cluster
()
.
size
([
config
.
heatWidth
,
config
.
dendWidth
])
.
separation
(()
=>
2
)(
root
);
};
const
root
=
tree
(
clustering
.
tree
());
return
{
root
,
}
rects
.
append
(
'ellipse'
)
.
attr
(
'cx'
,
`
${
config
.
ellipticNon_AD
.
cx
}
`
)
.
attr
(
'cy'
,
`
${
config
.
ellipticNon_AD
.
cy
}
`
)
.
attr
(
'rx'
,
`
${
config
.
ellipticNon_AD
.
rx
}
`
)
.
attr
(
'ry'
,
`
${
config
.
ellipticNon_AD
.
ry
}
`
)
.
attr
(
'transform-origin'
,
'center'
)
.
attr
(
'transform'
,
`rotate(
${
config
.
ellipticNon_AD
.
rotate
}
)`
)
.
attr
(
'fill'
,
config
.
colors
[
1
])
.
attr
(
'fill-opacity'
,
0.2
);
}
}
// tree
// point
export
const
setTree
=
(
config
)
=>
{
export
const
setPoint
=
(
config
,
data
)
=>
{
// top tree
return
config
.
svg
config
.
svg
.
append
(
'g'
)
.
append
(
"g"
)
.
attr
(
'fill'
,
'none'
)
.
selectAll
(
"path"
)
.
attr
(
'stroke'
,
'#555'
)
.
data
(
data
)
.
attr
(
'stroke-width'
,
1
)
.
join
(
"path"
)
.
attr
(
'transform'
,
`translate(
${
config
.
dendWidth
+
20
}
, 0)`
)
.
attr
(
"class"
,
"dot"
)
.
selectAll
(
'path'
)
.
attr
(
"opacity"
,
1
)
.
data
(
config
.
root
.
links
())
.
attr
(
"stroke-opacity"
,
1
)
.
join
(
'path'
)
.
attr
(
"stroke-width"
,
2
)
.
attr
(
.
attr
(
"stroke"
,
(
d
)
=>
config
.
color
(
d
.
name
))
'd'
,
.
attr
(
"fill"
,
'transparent'
)
(
d
)
=>
`
.
attr
(
"fill-opacity"
,
1
)
M
${
d
.
target
.
x
}
,
${
d
.
target
.
y
}
.
attr
(
"d"
,
(
d
)
=>
setSymbol
(
d
.
name
))
L
${
d
.
target
.
x
}
,
${
d
.
source
.
y
}
.
attr
(
"transform"
,
d
=>
`translate(
${
config
.
x
(
d
.
x
)}
,
${
config
.
y
(
d
.
y
)}
)`
)
${
d
.
source
.
x
}
,
${
d
.
source
.
y
}
}
${
d
.
source
.
x
}
,
${
d
.
source
.
y
}
`
// title
);
export
const
setLabel
=
(
config
)
=>
{
};
config
.
svg
.
append
(
'text'
)
\ No newline at end of file
.
attr
(
'x'
,
config
.
width
/
2
)
.
attr
(
'y'
,
30
)
.
attr
(
'fill'
,
config
.
titleConfig
.
color
)
.
attr
(
'font-size'
,
`
${
config
.
titleConfig
.
fontSize
}
px`
)
.
attr
(
'font-family'
,
`
${
config
.
titleConfig
.
fontFamily
}
`
)
.
attr
(
'font-style'
,
`
${
config
.
titleConfig
.
fontStyle
}
`
)
.
attr
(
'font-weight'
,
`
${
config
.
titleConfig
.
fontWeight
}
`
)
.
style
(
'text-anchor'
,
'middle'
)
.
text
(
'Principal'
);
};
src/views/home/index.vue
浏览文件 @
bff4fbe7
...
@@ -21,7 +21,7 @@ import ClusterHeatmapSecond from '../../components/ClusterHeatmapSecond/index.vu
...
@@ -21,7 +21,7 @@ import ClusterHeatmapSecond from '../../components/ClusterHeatmapSecond/index.vu
import
CircularHeatmap
from
'../../components/CircularHeatmap/index.vue'
;
import
CircularHeatmap
from
'../../components/CircularHeatmap/index.vue'
;
import
Test
from
'../../components/Test/index.vue'
;
import
Test
from
'../../components/Test/index.vue'
;
const
chartCurrent
=
ref
(
6
);
const
chartCurrent
=
ref
(
0
);
const
chartList
=
shallowRef
([
const
chartList
=
shallowRef
([
{
title
:
'线性拟合图'
,
value
:
1
,
comName
:
LinearFitting
},
{
title
:
'线性拟合图'
,
value
:
1
,
comName
:
LinearFitting
},
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论