Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
W
wangxiaolu-sfa-ui
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
sfa
wangxiaolu-sfa-ui
Commits
a05f81a5
提交
a05f81a5
authored
12月 30, 2024
作者:
lidongxu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix(bi/competitor/cmm): 修复已知bug
图表筛选问题和图例筛选问题以及左右 2 个 y 轴显示内容,并封装根据原始数据决定如何显示数字字符串带单位描述的函数使用
上级
5768f05c
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
391 行增加
和
296 行删除
+391
-296
index.vue
src/components/LevitatedSphere/index.vue
+2
-2
date.js
src/hooks/date.js
+25
-0
index.js
src/utils/index.js
+17
-0
math.js
src/utils/math.js
+59
-44
LineAndBar.vue
src/views/bi/competitor/cmm/LineAndBar.vue
+171
-163
index.vue
src/views/bi/competitor/cmm/index.vue
+94
-79
index.vue
src/views/bi/competitor/index.vue
+18
-3
GradientArea.vue
src/views/bi/competitor/sycm_store/GradientArea.vue
+1
-1
index.vue
src/views/bi/competitor/sycm_store/index.vue
+4
-4
没有找到文件。
src/components/LevitatedSphere/index.vue
浏览文件 @
a05f81a5
...
...
@@ -12,10 +12,9 @@
@click="handleClick">
<svg-icon
icon-class=
"tool"
></svg-icon>
</div>
<!-- 工具抽屉 -->
<el-drawer
title=
"工具箱"
:visible
.
sync
=
"drawer"
v-model
=
"drawer"
size=
"20%"
@
click
.
native=
"drawer = false"
>
<slot></slot>
...
...
@@ -112,6 +111,7 @@ export default {
},
methods
:
{
handleClick
()
{
console
.
log
(
this
.
downPoint
.
x
,
this
.
upPoint
.
x
,
this
.
downPoint
.
y
,
this
.
upPoint
.
y
)
if
(
this
.
downPoint
.
x
===
this
.
upPoint
.
x
&&
this
.
downPoint
.
y
===
this
.
upPoint
.
y
)
{
this
.
drawer
=
!
this
.
drawer
}
...
...
src/hooks/date.js
0 → 100644
浏览文件 @
a05f81a5
export
const
useDatePickerOptions
=
()
=>
{
const
pickerOptions
=
ref
([
// 日期选项配置
{
text
:
'最近一周'
,
value
()
{
const
end
=
new
Date
().
setDate
((
new
Date
().
getDate
()
-
1
));
const
start
=
new
Date
();
start
.
setTime
(
start
.
getTime
()
-
3600
*
1000
*
24
*
7
);
return
[
start
,
end
]
}
},
{
text
:
'最近一个月'
,
value
()
{
const
end
=
new
Date
().
setDate
((
new
Date
().
getDate
()
-
1
));
const
start
=
new
Date
();
start
.
setTime
(
start
.
getTime
()
-
3600
*
1000
*
24
*
30
);
return
[
start
,
end
]
}
}
])
return
{
pickerOptions
}
}
\ No newline at end of file
src/utils/index.js
浏览文件 @
a05f81a5
...
...
@@ -403,3 +403,19 @@ export function isNumberStr(str) {
return
/^
[
+-
]?(
0|
([
1-9
]\d
*
))(\.\d
+
)?
$/g
.
test
(
str
)
}
// 清除对象里属性的非响应式的值
export
function
resetObjValue
(
obj
,
props
)
{
for
(
let
prop
in
obj
)
{
if
(
obj
.
hasOwnProperty
(
prop
))
{
// 判断属性值是否为数组或对象
if
(
Array
.
isArray
(
obj
[
prop
]))
{
obj
[
prop
]
=
[];
}
else
if
(
typeof
obj
[
prop
]
===
'object'
&&
obj
[
prop
]
!==
null
)
{
obj
[
prop
]
=
{};
}
else
{
obj
[
prop
]
=
undefined
;
// 基础类型重置为 undefined
}
}
}
}
\ No newline at end of file
src/utils/math.js
浏览文件 @
a05f81a5
...
...
@@ -20,14 +20,66 @@ export function divSafe(arg1, arg2) {
}
/**
* 小数数字,转格式千分位用逗号,例如:12345.678 转换后 12,346
* @param {*} num
* @returns
* 将数值转换为带单位的字符串,并添加千分位逗号
* @param {number} value - 要转换的数值
* @param {string} extraDescription - 额外的描述字符串(没有直接返回数据)
* @param {bool} bool - 是否开启转换
* @param {bool} round - 是否取整
* @returns {string} 格式化后的字符串
*/
export
function
toThousands
(
num
)
{
if
(
num
===
null
||
num
===
undefined
)
return
'0'
// 暂存小数位
return
(
Math
.
round
(
num
)
||
0
).
toString
().
replace
(
/
(\d)(?=(?:\d{3})
+$
)
/g
,
'$1,'
)
export
function
formatNumberWithUnit
(
value
,
extraDescription
,
bool
,
round
)
{
if
(
typeof
value
!==
'number'
)
{
throw
new
Error
(
'输入值必须是数字'
);
}
// 不转换
if
(
!
bool
)
{
if
(
!
round
){
if
(
!
extraDescription
)
{
return
value
.
toFixed
(
2
)
}
else
{
return
value
.
toFixed
(
2
)
+
extraDescription
}
}
else
{
if
(
!
extraDescription
)
{
return
Math
.
round
(
value
)
+
''
}
else
{
return
Math
.
round
(
value
)
+
extraDescription
}
}
}
// 转换单位
let
unit
;
let
formattedValue
;
if
(
value
>=
100000000
)
{
unit
=
'亿'
;
formattedValue
=
(
value
/
100000000
);
}
else
if
(
value
>=
10000
)
{
unit
=
'万'
;
formattedValue
=
(
value
/
10000
);
}
else
{
unit
=
''
;
formattedValue
=
value
;
}
// 判断是否取整
if
(
round
)
{
formattedValue
=
Math
.
round
(
formattedValue
)
+
''
;
}
else
{
formattedValue
=
formattedValue
.
toFixed
(
2
);
}
// 如果没有额外描述,直接返回数值
if
(
!
extraDescription
)
{
return
formattedValue
;
}
// 添加千分位逗号
formattedValue
=
formattedValue
.
replace
(
/
\B(?=(\d{3})
+
(?!\d))
/g
,
','
);
return
`
${
formattedValue
}${
unit
}${
extraDescription
}
`
;
}
/**
...
...
@@ -44,43 +96,6 @@ export function roundUpToNextHighestPowerOfTen(num) {
return
(
Number
(
first
)
+
1
)
+
result
}
/**
* 把数字转换成带元/万/亿单位结尾字符串
* @param {*} number
* @param {*} isThousand 是否万分位数值(外面已经把数据除以万以后的数据)
* @returns
*/
export
function
convertToUnit
(
number
,
isThousand
)
{
if
(
number
===
0
||
number
===
undefined
||
number
===
null
)
{
return
"0"
;
}
let
unit
;
let
value
;
if
(
isThousand
)
{
number
=
number
*
10000
}
if
(
number
>=
100000000
)
{
unit
=
" 亿元"
;
value
=
number
/
100000000
;
}
else
if
(
number
>=
10000
)
{
unit
=
" 万元"
;
value
=
number
/
10000
;
}
else
{
unit
=
" 元"
;
value
=
number
;
}
// 保留两位小数
let
formattedValue
=
value
.
toFixed
(
2
);
// 去除末尾可能多余的0
formattedValue
=
parseFloat
(
formattedValue
).
toString
();
return
`
${
formattedValue
}${
unit
}
`
;
}
// 保留 2 位小数
export
function
toFixed2
(
num
)
{
if
(
num
===
null
||
num
===
undefined
)
return
'0'
...
...
src/views/bi/competitor/cmm/LineAndBar.vue
浏览文件 @
a05f81a5
<
template
>
<div
:class=
"className"
<div
ref=
"echartsRef"
:class=
"className"
:style=
"
{ height: height, width: width }" />
</
template
>
<
script
>
<
script
setup
>
import
*
as
echarts
from
'echarts'
import
resize
from
'@/views/dashboard/mixins/resize'
import
{
convertToUnit
,
toFixed2
}
from
'@/utils'
export
default
{
mixins
:
[
resize
],
props
:
{
className
:
{
type
:
String
,
default
:
'chart'
},
width
:
{
type
:
String
,
default
:
'100%'
},
height
:
{
type
:
String
,
default
:
'500px'
},
autoResize
:
{
type
:
Boolean
,
default
:
true
},
chartData
:
{
type
:
Object
,
required
:
true
}
import
{
formatNumberWithUnit
}
from
'@/utils'
const
props
=
defineProps
({
className
:
{
type
:
String
,
default
:
'chart'
},
data
()
{
return
{
chart
:
null
,
myThousand
:
false
}
width
:
{
type
:
String
,
default
:
'100%'
},
watch
:
{
chartData
:
{
deep
:
true
,
handler
(
val
)
{
this
.
myThousand
=
val
.
series
?.
some
(
o
=>
{
return
o
.
data
.
some
(
num
=>
num
>=
10000
)
})
// this.chart.dispose()
// this.initChart()
this
.
chart
.
clear
();
// 清除图表(重新设置)
this
.
setOptions
(
val
)
}
}
height
:
{
type
:
String
,
default
:
'600px'
},
mounted
()
{
this
.
$nextTick
(()
=>
{
this
.
initChart
()
})
autoResize
:
{
type
:
Boolean
,
default
:
true
},
beforeDestroy
()
{
if
(
!
this
.
chart
)
{
return
chartData
:
{
type
:
Object
,
required
:
true
}
})
const
echartsRef
=
ref
(
null
)
const
chart
=
shallowRef
(
null
)
const
myThousand
=
ref
(
false
)
// 是否显示万单位
const
setOptions
=
()
=>
{
// 计算 y 轴显示
const
yAxis
=
[
{
type
:
'value'
,
name
:
'销售额'
,
nameTextStyle
:
{
padding
:
[
0
,
60
,
0
,
0
]
},
axisLabel
:
{
formatter
(
value
)
{
return
formatNumberWithUnit
(
value
,
'元'
,
myThousand
.
value
,
true
)
}
},
axisPointer
:
{
label
:
{
formatter
:
(
params
)
=>
{
return
formatNumberWithUnit
(
params
.
value
,
'元'
,
myThousand
.
value
,
true
)
}
}
}
},
{
type
:
'value'
,
name
:
'观看人次'
,
nameTextStyle
:
{
padding
:
[
0
,
0
,
0
,
60
]
},
axisLabel
:
{
formatter
(
value
)
{
return
formatNumberWithUnit
(
value
,
'人'
,
myThousand
.
value
,
true
)
}
},
axisPointer
:
{
label
:
{
formatter
:
(
params
)
=>
{
return
formatNumberWithUnit
(
params
.
value
,
'人'
,
myThousand
.
value
,
true
)
}
}
}
}
this
.
chart
.
dispose
()
this
.
chart
=
null
},
methods
:
{
initChart
()
{
this
.
chart
=
echarts
.
init
(
this
.
$el
,
'macarons'
)
this
.
setOptions
(
this
.
chartData
)
]
yAxis
.
filter
(
yObj
=>
{
return
props
.
chartData
.
legend
.
some
(
o
=>
{
const
target
=
o
.
data
.
find
(
o
=>
{
return
o
.
name
.
split
(
'-'
)[
1
]
===
yObj
.
name
})
if
(
!
target
?.
show
)
yObj
.
name
=
''
else
yObj
.
name
=
target
.
name
.
split
(
'-'
)[
1
]
})
})
chart
.
value
.
setOption
({
xAxis
:
{
type
:
'category'
,
data
:
props
.
chartData
.
xAxis
,
axisPointer
:
{
type
:
'shadow'
}
},
setOptions
({
expectedData
,
actualData
}
=
{})
{
// 动态计算 max 值并向上取整
// const maxSaleValue = Math.ceil(
// Math.max(
// ...this.chartData?.data?.saleData.flat()
// )
// );
// const maxGkrcValue = Math.ceil(
// Math.max(
// ...this.chartData?.data?.gkrcData.flat()
// )
// );
// const a = roundUpToNextHighestPowerOfTen(maxSaleValue);
// const b = roundUpToNextHighestPowerOfTen(maxGkrcValue);
this
.
chart
.
setOption
({
xAxis
:
{
data
:
this
.
chartData
.
xAxis
,
// boundaryGap: false,
},
grid
:
{
top
:
'6%'
,
left
:
'3%'
,
right
:
'3%'
,
bottom
:
'3%'
,
containLabel
:
true
grid
:
{
top
:
'9%'
,
left
:
'3%'
,
right
:
'3%'
,
bottom
:
'3%'
,
containLabel
:
true
},
toolbox
:
{
show
:
true
,
feature
:
{
saveAsImage
:
{},
// 保存为图片
magicType
:
{
type
:
[
'tiled'
]
// 切换图表类型
},
toolbox
:
{
myThousandTool
:
{
show
:
true
,
feature
:
{
saveAsImage
:
{},
// 保存为图片
magicType
:
{
type
:
[
'stack'
,
'tiled'
]
// 切换图表类型
},
myThousandTool
:
{
show
:
true
,
title
:
'切换万单位'
,
icon
:
'path://M50,50 L100,50 L100,100 L150,100 L150,150 L100,150 L100,200 L50,200 L50,150 L0,150 L0,100 L50,100 Z'
,
onclick
:
()
=>
{
this
.
myThousand
=
!
this
.
myThousand
this
.
setOptions
()
}
}
title
:
'切换万单位'
,
icon
:
'path://M50,50 L100,50 L100,100 L150,100 L150,150 L100,150 L100,200 L50,200 L50,150 L0,150 L0,100 L50,100 Z'
,
onclick
:
()
=>
{
myThousand
.
value
=
!
myThousand
.
value
setOptions
()
}
},
tooltip
:
{
trigger
:
'axis'
,
axisPointer
:
{
type
:
'cross'
},
padding
:
[
5
,
10
],
formatter
:
(
params
)
=>
{
let
tooltip
=
''
;
params
.
forEach
((
item
)
=>
{
if
(
item
.
seriesName
.
split
(
'-'
)[
1
]
===
'销售额'
)
{
tooltip
+=
item
.
marker
+
item
.
seriesName
+
': '
+
(
this
.
myThousand
?
convertToUnit
(
item
.
value
,
true
)
:
toFixed2
(
item
.
value
)
+
'元'
)
+
'<br>'
;
}
else
if
(
item
.
seriesName
.
split
(
'-'
)[
1
]
===
'观看人次'
)
{
tooltip
+=
item
.
marker
+
item
.
seriesName
+
': '
+
toFixed2
(
item
.
value
)
+
(
this
.
myThousand
?
'万'
:
''
)
+
'人<br>'
;
}
});
return
tooltip
;
}
}
},
tooltip
:
{
trigger
:
'axis'
,
axisPointer
:
{
type
:
'cross'
,
crossStyle
:
{
color
:
'#999'
}
},
formatter
:
function
(
params
)
{
let
tooltip
=
''
;
params
.
forEach
((
item
)
=>
{
// 获取系列颜色
var
color
=
item
.
color
;
// 拼接提示内容
if
(
item
.
seriesName
.
split
(
'-'
)[
1
]
===
'销售额'
)
{
tooltip
+=
'<span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:'
+
color
+
';"></span>'
+
item
.
seriesName
+
': '
+
formatNumberWithUnit
(
item
.
value
,
'元'
,
myThousand
.
value
)
+
'<br>'
;
}
else
if
(
item
.
seriesName
.
split
(
'-'
)[
1
]
===
'观看人次'
)
{
tooltip
+=
'<span style="display:inline-block;margin-right:5px;border-radius:10px;width:9px;height:9px;background-color:'
+
color
+
';"></span>'
+
item
.
seriesName
+
': '
+
formatNumberWithUnit
(
item
.
value
,
'人'
,
myThousand
.
value
)
+
'<br>'
;
}
},
yAxis
:
[
{
type
:
'value'
,
name
:
'销售额'
,
// nameTextStyle: {
// padding: [0, 80, 0, 0]
// },
axisLabel
:
{
formatter
:
'{value} '
+
(
this
.
myThousand
?
'万'
:
''
)
+
'元'
},
// min: 0, // 设置最小值
// max: a,
// offset: 20
},
{
type
:
'value'
,
name
:
'观看人次'
,
// nameTextStyle: {
// padding: [0, 0, 0, 80]
// },
axisLabel
:
{
formatter
:
'{value} '
+
(
this
.
myThousand
?
'万'
:
''
)
+
'人'
},
// min: 0, // 设置最小值
// max: b,
// offset: 20
},
],
// legend: {
// data: this.chartData.legend
// },
// legend: this.chartData.legend,
series
:
[
...
this
.
chartData
.
series
?.
map
(
o
=>
{
return
{
...
o
,
data
:
o
.
data
.
map
(
num
=>
{
return
parseFloat
((
this
.
myThousand
?
num
/
10000
:
num
).
toFixed
(
2
))
})
}
})
]
})
}
}
});
return
tooltip
;
}
// padding: [5, 10],
// formatter: (params) => {
// let tooltip = '';
// params.forEach((item) => {
// if (item.seriesName.split('-')[1] === '销售额') {
// tooltip += item.marker + item.seriesName + ': ' + (this.myThousand ? convertToUnit(item.value, true) : toFixed2(item.value) + '元') + '
<
br
>
';
// } else if (item.seriesName.split('
-
')[1] === '
观看人次
') {
// tooltip += item.marker + item.seriesName + '
:
' + toFixed2(item.value) + (this.myThousand ? '
万
' : '') + '
人
<
br
>
';
// }
// });
// console.log(tooltip)
// return tooltip;
// }
},
yAxis,
series: props.chartData.series
}, true)
}
watchEffect(() => {
if (!chart.value) return
myThousand.value = props.chartData.series?.some(o => {
return o.data.some(num => num >= 10000)
})
setOptions()
})
const initChart = () => {
chart.value = echarts.init(echartsRef.value)
setOptions()
}
onMounted(() => {
nextTick(() => {
initChart()
})
})
onBeforeUnmount(() => {
if (!chart.value) {
return
}
chart.value.dispose()
chart.value = null
})
</
script
>
src/views/bi/competitor/cmm/index.vue
浏览文件 @
a05f81a5
<
template
>
<div
class=
"
chart_wrap
"
>
<div
class=
"
tabs-container
"
>
<el-form
:model=
"queryParams"
inline
size=
"default"
>
...
...
@@ -16,6 +16,19 @@
</el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"数据类型"
>
<el-select
v-model=
"queryParams.typeList"
@
change=
"queryChangeFn"
multiple
clearable
collapse-tags
collapse-tags-tooltip
>
<el-option
v-for=
"str in typeList"
:label=
"str"
:value=
"str"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"日期选择"
>
<el-date-picker
v-model=
"queryParams.date"
type=
"daterange"
...
...
@@ -24,17 +37,10 @@
range-separator=
"至"
start-placeholder=
"开始日期"
end-placeholder=
"结束日期"
:
picker-option
s=
"pickerOptions"
:
shortcut
s=
"pickerOptions"
@
change=
"queryChangeFn('date')"
>
</el-date-picker>
</el-form-item>
<el-form-item
label=
"数据类型"
>
<el-checkbox-group
v-model=
"queryParams.typeList"
@
change=
"queryChangeFn"
>
<el-checkbox
label=
"销售额"
></el-checkbox>
<el-checkbox
label=
"观看人次"
></el-checkbox>
</el-checkbox-group>
</el-form-item>
</el-form>
<div
class=
"chart_wrap"
>
<group-legend
:legendData=
"chartData.legend"
...
...
@@ -52,48 +58,39 @@
import
{
ref
,
reactive
}
from
'vue'
import
LineCharts
from
'./LineAndBar.vue'
import
{
getCmmListAPI
}
from
'@/api'
import
{
generatorDayList
,
parseTime
,
getBrandColor
}
from
'@/utils'
import
{
generatorDayList
,
parseTime
,
getBrandColor
,
resetObjValue
}
from
'@/utils'
import
{
useDatePickerOptions
}
from
'@/hooks/date'
// 最近 30 日日期数组
const
dateList
=
[
new
Date
().
setDate
((
new
Date
().
getDate
()
-
30
)),
new
Date
().
setDate
((
new
Date
().
getDate
()
-
1
))]
// 数据类型
const
dataTypeList
=
[
'销售额'
,
'观看人次'
]
const
queryParams
=
reactive
({
// 查询表单
brandList
:
[],
date
:
[
new
Date
().
setDate
((
new
Date
().
getDate
()
-
30
)),
new
Date
().
setDate
((
new
Date
().
getDate
()
-
1
))],
typeList
:
[
'销售额'
,
'观看人次'
]
})
const
pickerOptions
=
reactive
({
// 日期选项配置
shortcuts
:
[{
text
:
'最近一周'
,
onClick
(
picker
)
{
const
end
=
new
Date
().
setDate
((
new
Date
().
getDate
()
-
1
));
const
start
=
new
Date
();
start
.
setTime
(
start
.
getTime
()
-
3600
*
1000
*
24
*
7
);
picker
.
$emit
(
'pick'
,
[
start
,
end
]);
}
},
{
text
:
'最近一个月'
,
onClick
(
picker
)
{
const
end
=
new
Date
().
setDate
((
new
Date
().
getDate
()
-
1
));
const
start
=
new
Date
();
start
.
setTime
(
start
.
getTime
()
-
3600
*
1000
*
24
*
30
);
picker
.
$emit
(
'pick'
,
[
start
,
end
]);
}
}]
date
:
dateList
,
typeList
:
dataTypeList
})
const
{
pickerOptions
}
=
useDatePickerOptions
()
const
brandList
=
ref
([])
// 直播间列表
const
typeList
=
ref
(
dataTypeList
)
const
allChartData
=
reactive
({
// 图表所有数据
series
:
[],
xAxis
:
[],
legend
:
[]
legend
:
[],
series
:
[]
})
const
chartData
=
reactive
({
// 图表内要用的数据
series
:
[],
xAxis
:
[],
legend
:
[]
legend
:
[],
series
:
[]
})
// 获取数据
const
getList
=
async
()
=>
{
allChartData
.
series
=
[]
allChartData
.
legend
=
[]
// 重置数据源
resetObjValue
(
allChartData
)
// 获取 x 轴时间
allChartData
.
xAxis
=
generatorDayList
(
queryParams
.
date
[
0
],
queryParams
.
date
[
1
])
const
{
data
}
=
await
getCmmListAPI
({
startDate
:
parseTime
(
queryParams
.
date
[
0
],
'{y}-{m}-{d}'
),
endDate
:
parseTime
(
queryParams
.
date
[
1
],
'{y}-{m}-{d}'
)
...
...
@@ -101,29 +98,38 @@ const getList = async () => {
data
.
map
((
list
,
index
)
=>
{
// list:每个直播间
let
color
=
getBrandColor
(
list
[
0
]?.
name
)
// 每个系列对象
const
saleObj
=
{
name
:
list
[
0
]?.
name
+
'-销售额'
,
type
:
'bar'
,
data
:
[],
itemStyle
:
{
color
}
},
color
,
yAxisIndex
:
0
}
const
gkrcObj
=
{
name
:
list
[
0
]?.
name
+
'-观看人次'
,
type
:
'line'
,
data
:
[],
showSymbol
:
false
,
symbol
:
'none'
,
lineStyle
:
{
width
:
2
,
// 设置折线的宽度
type
:
'solid'
,
// 设置折线的类型
color
},
color
,
yAxisIndex
:
1
,
}
// 按照日期添加数据
// 按照日期归并数据
const
listMap
=
new
Map
()
list
.
forEach
(
o
=>
{
listMap
.
set
(
o
.
date
.
split
(
'-'
).
slice
(
1
).
join
(
'-'
),
o
)
})
allChartData
.
xAxis
.
forEach
(
date
=>
{
const
findObj
=
list
.
find
(
o
=>
o
.
date
.
includes
(
date
)
)
const
findObj
=
list
Map
.
get
(
date
)
if
(
findObj
)
{
saleObj
.
data
.
push
(
findObj
.
saleSumTotal
)
gkrcObj
.
data
.
push
(
findObj
.
gkrcNumTotal
)
...
...
@@ -132,14 +138,14 @@ const getList = async () => {
gkrcObj
.
data
.
push
(
0
)
}
})
//
legendData 名字
//
添加图例数据
allChartData
.
legend
.
push
({
data
:
[{
name
:
saleObj
.
name
,
type
:
'bar'
,
color
:
color
,
effective
:
true
,
show
:
true
show
:
true
,
},
{
name
:
gkrcObj
.
name
,
type
:
'line'
,
...
...
@@ -149,8 +155,7 @@ const getList = async () => {
}],
orient
:
'verticalAlign'
})
// allChartData.legend.push(saleObj.name)
// allChartData.legend.push(gkrcObj.name)
// 添加系列数据
allChartData
.
series
.
push
(
saleObj
)
allChartData
.
series
.
push
(
gkrcObj
)
})
...
...
@@ -170,25 +175,32 @@ const filterData = () => {
return
queryParams
.
brandList
.
find
(
nameStr
=>
obj
.
data
.
find
(
o
=>
o
.
name
.
split
(
'-'
)[
0
]
===
nameStr
))
})
}
// 查看数据类型必须走
series
=
series
.
filter
(
obj
=>
{
return
queryParams
.
typeList
.
find
(
str
=>
obj
.
name
.
split
(
'-'
)[
1
]
===
str
)
})
legend
=
legend
.
filter
(
obj
=>
{
// TODO:会不会有丢失响应式的
const
list
=
[...
obj
.
data
]
list
.
forEach
((
o
,
index
)
=>
{
const
isHave
=
queryParams
.
typeList
.
includes
(
o
.
name
.
split
(
'-'
)[
1
])
if
(
!
isHave
)
o
.
show
=
false
else
o
.
show
=
true
// 数据类型筛选
if
(
queryParams
.
typeList
.
length
>
0
)
{
series
=
series
.
filter
(
obj
=>
{
return
queryParams
.
typeList
.
find
(
str
=>
obj
.
name
.
split
(
'-'
)[
1
]
===
str
)
})
obj
.
data
=
list
return
true
})
// 根据图例状态筛选数据是否显示
// 图例组件数据源不变,只是显示/隐藏
legend
.
filter
(
obj
=>
{
obj
.
data
.
forEach
((
o
,
index
)
=>
{
const
isHave
=
queryParams
.
typeList
.
includes
(
o
.
name
.
split
(
'-'
)[
1
])
// 设置图例组件显示/隐藏
if
(
!
isHave
)
o
.
show
=
false
else
o
.
show
=
true
})
})
}
else
{
// 数据类型都没选
legend
.
forEach
(
obj
=>
{
obj
.
data
.
forEach
(
o
=>
{
o
.
show
=
true
})
})
}
// 据图例状态,筛选数据显示
series
=
series
.
filter
(
sObj
=>
{
let
nowSeries
=
true
chartData
.
legend
.
forEach
(
obj
=>
{
legend
.
forEach
(
obj
=>
{
const
now
=
obj
.
data
.
find
(
o
=>
{
return
o
.
name
===
sObj
.
name
})
...
...
@@ -205,47 +217,50 @@ const filterData = () => {
chartData
.
xAxis
=
allChartData
.
xAxis
}
// 默认打开页面请求一次所有数据,并保存在数据源
(
async
function
init
()
{
// 生成 x 轴时间
allChartData
.
xAxis
=
generatorDayList
(
queryParams
.
date
[
0
],
queryParams
.
date
[
1
])
const
init
=
async
function
()
{
// 请求数据
const
data
=
await
getList
()
// 初始化直播间列表
brandList
.
value
=
data
.
map
(
list
=>
list
[
0
].
name
)
// 筛选图表数据
filterData
()
}
)();
}
init
()
// 筛选条件改变了
const
queryChangeFn
=
async
(
arg
)
=>
{
if
(
arg
===
'date'
&&
!
queryParams
.
date
)
return
if
(
arg
===
'date'
&&
queryParams
.
date
)
{
// 时间变化,并且有值,需要重新请求
allChartData
.
xAxis
=
generatorDayList
(
queryParams
.
date
[
0
],
queryParams
.
date
[
1
])
await
getList
()
}
filterData
()
}
// 图例点击改变了
const
legendChangeFn
=
(
o
)
=>
{
const
legendChangeFn
=
()
=>
{
filterData
()
}
// 重置
const
reset
=
async
()
=>
{
// 重置查询参数
queryParams
.
brandList
=
[]
queryParams
.
date
=
[
new
Date
().
setDate
((
new
Date
().
getDate
()
-
30
)),
new
Date
().
setDate
((
new
Date
().
getDate
()
-
1
))]
queryParams
.
typeList
=
[
'销售额'
,
'观看人次'
]
allChartData
.
xAxis
=
generatorDayList
(
queryParams
.
date
[
0
],
queryParams
.
date
[
1
])
// 重新获取
await
getList
()
// 筛选图表数据
filterData
()
queryParams
.
date
=
dateList
queryParams
.
typeList
=
dataTypeList
init
()
}
</
script
>
<
style
scoped
lang=
"scss"
></
style
>
\ No newline at end of file
lang=
"scss"
>
.tabs-container
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
.chart_wrap
{
flex
:
1
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-around
;
}
}
</
style
>
\ No newline at end of file
src/views/bi/competitor/index.vue
浏览文件 @
a05f81a5
...
...
@@ -20,9 +20,9 @@ import sycmStore from './sycm_store'
import
sycmPrd
from
'./sycm_prd'
import
{
ref
}
from
'vue'
const
list
=
ref
([
{
name
:
'蝉妈妈'
,
component
:
cmm
},
{
name
:
'生意参谋-竞店'
,
component
:
s
ycmStore
},
{
name
:
'生意参谋-竞品'
,
component
:
s
ycmPrd
}
{
name
:
'蝉妈妈'
,
component
:
shallowRef
(
cmm
)
},
{
name
:
'生意参谋-竞店'
,
component
:
s
hallowRef
(
sycmStore
)
},
{
name
:
'生意参谋-竞品'
,
component
:
s
hallowRef
(
sycmPrd
)
}
])
const
activeName
=
ref
(
list
.
value
[
0
].
name
)
</
script
>
...
...
@@ -30,9 +30,23 @@ const activeName = ref(list.value[0].name)
<
style
scoped
lang=
"scss"
>
.app-container
{
height
:
calc
(
100vh
-
84px
);
.tabs
{
background
:
var
(
--
el-bg-color-overlay
);
padding
:
20px
;
display
:
flex
;
flex-direction
:
column
;
height
:
100%
;
::v-deep
(
.el-tabs__content
)
{
flex
:
1
;
.el-tab-pane
{
height
:
100%
;
}
}
}
}
</
style
>
\ No newline at end of file
src/views/bi/competitor/sycm_store/GradientArea.vue
浏览文件 @
a05f81a5
...
...
@@ -22,7 +22,7 @@ export default {
},
height
:
{
type
:
String
,
default
:
'
5
00px'
default
:
'
6
00px'
},
autoResize
:
{
type
:
Boolean
,
...
...
src/views/bi/competitor/sycm_store/index.vue
浏览文件 @
a05f81a5
...
...
@@ -41,7 +41,7 @@
</el-form-item>
-->
</el-form>
<div
class=
"chart_wrap"
>
<
!--
<gradient-area
:chartData=
"chartData"
></gradient-area>
--
>
<
gradient-area
:chartData=
"chartData"
></gradient-area
>
</div>
</div>
</
template
>
...
...
@@ -204,10 +204,10 @@ const filterData = () => {
// 直播间列表
brandList
.
value
=
data
.
map
(
list
=>
list
[
0
].
platformStore
)
// 初始化筛选条件(默认请求第一个店铺的第一类型数据)
//
queryParams.brandList = [data[0][0].platformStore]
//
queryParams.typeList = [typeList.value[0]]
queryParams
.
brandList
=
[
data
[
0
][
0
].
platformStore
]
queryParams
.
typeList
=
[
typeList
.
value
[
0
]]
// 筛选图表数据
//
filterData()
filterData
()
})
})();
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论