|
@@ -1,16 +1,17 @@
|
|
|
<template>
|
|
|
<MetricsCards v-model="metrics" :metric-items="metricsItems" @change="changeMetric"></MetricsCards>
|
|
|
- <div style="height: 500px;" ref="chartRef"></div>
|
|
|
+ <div style="height: 350px;" ref="chartRef"></div>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
-import { ref,onMounted, onBeforeUnmount, Ref, onBeforeMount, watch, computed, inject } from 'vue'
|
|
|
+import { ref,onMounted, onBeforeUnmount, Ref, onBeforeMount, watch, computed } from 'vue'
|
|
|
import * as echarts from 'echarts'
|
|
|
import { useShopInfo } from '/@/stores/shopInfo'
|
|
|
import { getLineData, getCardData } from '../api'
|
|
|
import { spCampaignMetricsEnum } from '/@/views/adManage/utils/enum.js'
|
|
|
import MetricsCards from '/@/components/MetricsCards/index.vue'
|
|
|
import XEUtils from 'xe-utils'
|
|
|
+import { buildChartOpt } from '/@/views/adManage/utils/tools.js'
|
|
|
|
|
|
defineOptions({
|
|
|
name: "DataTendencyChart"
|
|
@@ -31,62 +32,167 @@ onBeforeUnmount(() => {
|
|
|
removeResize()
|
|
|
})
|
|
|
|
|
|
-let chartObj:any
|
|
|
-const chartRef = ref()
|
|
|
-const dateRange: string[] = inject('dateRange', [])
|
|
|
-const shopInfo = useShopInfo()
|
|
|
-// 初始显示指标,长度必须为3
|
|
|
-const metrics = ref([
|
|
|
- {metric: 'Impression', color: '#3fd4cf', 'label': '曝光量'},
|
|
|
- {metric: 'Click', color: '#0085ff', 'label': '点击量'},
|
|
|
+const metrics = ref([
|
|
|
+ {metric: 'Impression', color: '#0085ff', 'label': '曝光量'},
|
|
|
+ {metric: 'Click', color: '#3fd4cf', 'label': '点击量'},
|
|
|
{metric: 'Spend', color: '#ff9500', 'label': '花费'},
|
|
|
])
|
|
|
+const shopInfo = useShopInfo()
|
|
|
const metricsItems: Ref<MetricData[]> = ref([])
|
|
|
-
|
|
|
-const getDataset = async () => {
|
|
|
- const resp = await getLineData({profile: shopInfo.profile.profile_id, start: dateRange[0], end: dateRange[1]})
|
|
|
- return resp.data
|
|
|
-}
|
|
|
-const initLine = async () => {
|
|
|
- chartObj = echarts.init(chartRef.value)
|
|
|
-
|
|
|
- const option: any = {
|
|
|
- dataset: {
|
|
|
- source: []
|
|
|
- },
|
|
|
- tooltip: {
|
|
|
- trigger: 'axis',
|
|
|
- axisPointer: {
|
|
|
- // type: 'cross',
|
|
|
- label: {
|
|
|
- backgroundColor: '#6a7985'
|
|
|
- }
|
|
|
+let chartObj:any
|
|
|
+const chartRef = ref()
|
|
|
+const option: any = {
|
|
|
+ dataset: {
|
|
|
+ source: []
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ axisPointer: {
|
|
|
+ label: {
|
|
|
+ backgroundColor: '#6a7985'
|
|
|
}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ selected: {}, // 控制显隐
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ top: 50, right: 150, bottom: 30, left: 55,
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category'
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {
|
|
|
+ id: 0,
|
|
|
+ type: 'value',
|
|
|
+ name: '曝光量',
|
|
|
+ splitLine: {
|
|
|
+ show: true // 设置显示分割线
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ show: true,
|
|
|
+ lineStyle: {
|
|
|
+ color: '#0085ff'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ show: true
|
|
|
},
|
|
|
- legend: {
|
|
|
- selected: {}, // 控制显隐
|
|
|
- show: false
|
|
|
+ {
|
|
|
+ id: 1,
|
|
|
+ type: 'value',
|
|
|
+ name: '点击量',
|
|
|
+ position: 'right',
|
|
|
+ splitLine: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ show: true,
|
|
|
+ lineStyle: {
|
|
|
+ color: '#3fd4cf'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ show: true
|
|
|
},
|
|
|
- grid: {
|
|
|
- top: 50, right: 150, bottom: 30, left: 55,
|
|
|
+ {
|
|
|
+ id: 2,
|
|
|
+ type: 'value',
|
|
|
+ position: 'right',
|
|
|
+ offset: 90,
|
|
|
+ name: '花费',
|
|
|
+ splitLine: {
|
|
|
+ show: false
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ show: true,
|
|
|
+ lineStyle: {
|
|
|
+ color: '#ff9500'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ show: true
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ id: 0,
|
|
|
+ name: '曝光量',
|
|
|
+ type: 'bar',
|
|
|
+ encode: {
|
|
|
+ x: 'date',
|
|
|
+ y: 'Impression'
|
|
|
+ },
|
|
|
+ barWidth: '20px',
|
|
|
+ yAxisIndex: 0,
|
|
|
+ itemStyle: {
|
|
|
+ color: '#0085ff',
|
|
|
+ borderRadius: [10, 10, 0, 0],
|
|
|
+ }
|
|
|
},
|
|
|
- xAxis: {
|
|
|
- type: 'time'
|
|
|
+ {
|
|
|
+ id: 1,
|
|
|
+ name: '点击量',
|
|
|
+ type: 'line',
|
|
|
+ encode: {
|
|
|
+ x: 'date',
|
|
|
+ y: 'Click'
|
|
|
+ },
|
|
|
+ symbolSize: 6,
|
|
|
+ symbol: 'circle',
|
|
|
+ smooth: true,
|
|
|
+ yAxisIndex: 1,
|
|
|
+ itemStyle: { color: '#3fd4cf', borderColor: '#3fd4cf' },
|
|
|
+ areaStyle: {
|
|
|
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
+ { offset: 0, color: '#3fd4cf53' },
|
|
|
+ { offset: 1, color: '#3fd4cf03' },
|
|
|
+ ]),
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ focus:'series'
|
|
|
+ }
|
|
|
},
|
|
|
- yAxis: [],
|
|
|
- series: []
|
|
|
- }
|
|
|
+ {
|
|
|
+ id: 2,
|
|
|
+ name: '花费',
|
|
|
+ type: 'line',
|
|
|
+ encode: {
|
|
|
+ x: 'date',
|
|
|
+ y: 'Spend'
|
|
|
+ },
|
|
|
+ symbolSize: 6,
|
|
|
+ symbol: 'circle',
|
|
|
+ smooth: true,
|
|
|
+ yAxisIndex: 2,
|
|
|
+ itemStyle: { color: '#ff9500', borderColor: '#ff9500' },
|
|
|
+ areaStyle: {
|
|
|
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
|
+ { offset: 0, color: '#ff950053' },
|
|
|
+ { offset: 1, color: '#ff950003' },
|
|
|
+ ]),
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ focus:'series'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+}
|
|
|
+const getDataset = async () => {
|
|
|
+ const resp = await getLineData({profile: shopInfo.profile.profile_id, start: '2023-11-01', end: '2023-11-04'})
|
|
|
+ return resp.data
|
|
|
+}
|
|
|
+const initLine = async () => {
|
|
|
+ chartObj = echarts.init(chartRef.value)
|
|
|
const items = await getDataset()
|
|
|
option.dataset.source = items
|
|
|
-
|
|
|
- const opt = buildOption()
|
|
|
- option.series = opt.series
|
|
|
- option.yAxis = opt.yAxis
|
|
|
-
|
|
|
+ for(const info of metrics.value) {
|
|
|
+ option.legend.selected[info.label] = true
|
|
|
+ }
|
|
|
chartObj.setOption(option)
|
|
|
}
|
|
|
+
|
|
|
const getMetricsItems = async () => {
|
|
|
- const resp = await getCardData({start: dateRange[0], end: dateRange[1], profile: shopInfo.profile.profile_id})
|
|
|
+ const resp = await getCardData({start: '2023-11-01', end: '2023-11-04', profile: shopInfo.profile.profile_id})
|
|
|
const data = resp.data
|
|
|
XEUtils.arrayEach(spCampaignMetricsEnum, info => {
|
|
|
const tmp:MetricData = {
|
|
@@ -98,58 +204,20 @@ const getMetricsItems = async () => {
|
|
|
disabled: info.initShow ? true : false
|
|
|
}
|
|
|
metricsItems.value.push(tmp)
|
|
|
+ option.legend.selected[info.label] = false
|
|
|
})
|
|
|
}
|
|
|
-const buildOption = () => {
|
|
|
- const opt:any = {
|
|
|
- yAxis: [],
|
|
|
- series: []
|
|
|
- }
|
|
|
- XEUtils.arrayEach(metrics.value, (info, index) => {
|
|
|
- const tmp:any = {
|
|
|
- type: 'value',
|
|
|
- name: info.label,
|
|
|
- position: 'left',
|
|
|
- splitLine: {
|
|
|
- show: false // 设置显示分割线
|
|
|
- },
|
|
|
- axisLine: {
|
|
|
- show: true,
|
|
|
- lineStyle: {
|
|
|
- color: info.color
|
|
|
- }
|
|
|
- },
|
|
|
- show: true
|
|
|
- }
|
|
|
- if (index > 0) {
|
|
|
- tmp["position"] = "right"
|
|
|
- if (index === 2) { tmp["offset"] = 80 }
|
|
|
- }
|
|
|
- opt.yAxis.push(tmp)
|
|
|
- opt.series.push({
|
|
|
- name: info.label,
|
|
|
- type: 'line',
|
|
|
- encode: {
|
|
|
- x: 'date',
|
|
|
- y: info.metric
|
|
|
- },
|
|
|
- symbolSize: 6,
|
|
|
- symbol: 'circle',
|
|
|
- smooth: true,
|
|
|
- yAxisIndex: index,
|
|
|
- itemStyle: { color: info.color, borderColor: info.color },
|
|
|
- })
|
|
|
- })
|
|
|
- return opt
|
|
|
-}
|
|
|
+
|
|
|
const changeMetric = () => {
|
|
|
- const opt = buildOption()
|
|
|
- chartObj.setOption(opt, { replaceMerge: ['yAxis', 'series'] })
|
|
|
+ const opt = buildChartOpt(option, metrics.value)
|
|
|
+ chartObj.setOption(opt)
|
|
|
}
|
|
|
+
|
|
|
const resizeChart = () => { chartObj.resize() }
|
|
|
const addResize = () => { window.addEventListener('resize', resizeChart) }
|
|
|
const removeResize = () => { window.removeEventListener('resize', resizeChart) }
|
|
|
|
|
|
+
|
|
|
defineExpose({resizeChart})
|
|
|
|
|
|
</script>
|