|
@@ -3,17 +3,26 @@ import type { EChartsOption } from 'echarts/types/dist/shared'
|
|
|
import axiosInstance from '@/utils/axios/axiosInstance.ts'
|
|
|
import type { ResponseInfo } from '@/types/res.ts'
|
|
|
import type { QueryInfo } from '@/types/table.ts'
|
|
|
+import { generateUniqueColors } from '@/utils/common'
|
|
|
+
|
|
|
+interface AdChartItem {
|
|
|
+ name: string
|
|
|
+ value: number
|
|
|
+ sumType0: number
|
|
|
+ sumType1: number
|
|
|
+ sumType2: number
|
|
|
+}
|
|
|
|
|
|
interface BarChartInfo {
|
|
|
labelList: string[]
|
|
|
- valueList: any[]
|
|
|
+ valueList: number[]
|
|
|
+ sumType0List: number[]
|
|
|
+ sumType1List: number[]
|
|
|
+ sumType2List: number[]
|
|
|
}
|
|
|
|
|
|
interface ChartInfo {
|
|
|
- PieChart: Array<{
|
|
|
- name: string
|
|
|
- value: number
|
|
|
- }>
|
|
|
+ PieChart: AdChartItem[]
|
|
|
BarChart: BarChartInfo
|
|
|
}
|
|
|
|
|
@@ -24,81 +33,23 @@ export function useTableChart(
|
|
|
chartNeedFields: Array<string>,
|
|
|
isPie: Ref<boolean>
|
|
|
) {
|
|
|
- const pieChartOptions = computed<EChartsOption>(() => {
|
|
|
- return {
|
|
|
- tooltip: {
|
|
|
- trigger: 'item'
|
|
|
- },
|
|
|
- legend: {
|
|
|
- top: '5%',
|
|
|
- left: 'center'
|
|
|
- },
|
|
|
- series: [
|
|
|
- {
|
|
|
- name: '',
|
|
|
- type: 'pie',
|
|
|
- radius: ['40%', '70%'],
|
|
|
- avoidLabelOverlap: false,
|
|
|
- itemStyle: {
|
|
|
- borderRadius: 10,
|
|
|
- borderColor: '#fff',
|
|
|
- borderWidth: 2
|
|
|
- },
|
|
|
- label: {
|
|
|
- show: false,
|
|
|
- position: 'center'
|
|
|
- },
|
|
|
- emphasis: {
|
|
|
- label: {
|
|
|
- show: true,
|
|
|
- fontSize: 40,
|
|
|
- fontWeight: 'bold'
|
|
|
- }
|
|
|
- },
|
|
|
- labelLine: {
|
|
|
- show: false
|
|
|
- },
|
|
|
- data: chartInfo.value.PieChart
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- const barChartOptions = computed<EChartsOption>(() => {
|
|
|
- const barChartInfo = chartInfo.value.BarChart
|
|
|
- return {
|
|
|
- xAxis: {
|
|
|
- type: 'category',
|
|
|
- data: barChartInfo.labelList
|
|
|
- },
|
|
|
- yAxis: {
|
|
|
- type: 'value'
|
|
|
- },
|
|
|
- series: [
|
|
|
- {
|
|
|
- data: barChartInfo.valueList,
|
|
|
- type: 'bar'
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
const chartInfo = ref<ChartInfo>({
|
|
|
PieChart: [],
|
|
|
BarChart: {
|
|
|
labelList: [],
|
|
|
- valueList: []
|
|
|
+ valueList: [],
|
|
|
+ sumType0List: [],
|
|
|
+ sumType1List: [],
|
|
|
+ sumType2List: []
|
|
|
}
|
|
|
})
|
|
|
|
|
|
const updateChartData = async () => {
|
|
|
- // 如果没有筛选,则提示.根据chartNeedFields来
|
|
|
if (chartNeedFields.length > 0) {
|
|
|
const hasFilter = chartNeedFields.every((item) => {
|
|
|
return queryFormData.value[item] === ''
|
|
|
})
|
|
|
if (hasFilter) {
|
|
|
- // ElMessage.warning('请选择筛选条件')
|
|
|
const tip = filterInfo
|
|
|
.filter((item) => {
|
|
|
return chartNeedFields.includes(item.name as any)
|
|
@@ -114,11 +65,9 @@ export function useTableChart(
|
|
|
|
|
|
const params = {} as any
|
|
|
Object.assign(params, queryFormData.value)
|
|
|
- // TODO 时间范围问题
|
|
|
if (queryFormData.value.createTime) {
|
|
|
params.createTime = queryFormData.value.createTime
|
|
|
.map((item: any) => {
|
|
|
- // 日期转时间戳
|
|
|
return new Date(item).getTime().toString()
|
|
|
})
|
|
|
.join(',')
|
|
@@ -133,12 +82,19 @@ export function useTableChart(
|
|
|
const data = res.data as Array<{
|
|
|
name: string
|
|
|
count: number
|
|
|
+ sumType0: number
|
|
|
+ sumType1: number
|
|
|
+ sumType2: number
|
|
|
}> | null
|
|
|
+
|
|
|
if (!data) {
|
|
|
chartInfo.value.PieChart = []
|
|
|
chartInfo.value.BarChart = {
|
|
|
labelList: [],
|
|
|
- valueList: []
|
|
|
+ valueList: [],
|
|
|
+ sumType0List: [],
|
|
|
+ sumType1List: [],
|
|
|
+ sumType2List: []
|
|
|
}
|
|
|
} else {
|
|
|
const isAllZero = data.every((item) => item.count === 0)
|
|
@@ -146,23 +102,313 @@ export function useTableChart(
|
|
|
chartInfo.value.PieChart = []
|
|
|
chartInfo.value.BarChart = {
|
|
|
labelList: [],
|
|
|
- valueList: []
|
|
|
+ valueList: [],
|
|
|
+ sumType0List: [],
|
|
|
+ sumType1List: [],
|
|
|
+ sumType2List: []
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
- chartInfo.value.PieChart = data.map((item) => {
|
|
|
- return {
|
|
|
- name: item.name,
|
|
|
- value: item.count
|
|
|
- }
|
|
|
- })
|
|
|
+
|
|
|
+ chartInfo.value.PieChart = data.map((item) => ({
|
|
|
+ name: item.name,
|
|
|
+ value: item.count,
|
|
|
+ sumType0: item.sumType0 || 0,
|
|
|
+ sumType1: item.sumType1 || 0,
|
|
|
+ sumType2: item.sumType2 || 0
|
|
|
+ }))
|
|
|
chartInfo.value.BarChart = {
|
|
|
labelList: data.map((item) => item.name),
|
|
|
- valueList: data.map((item) => item.count)
|
|
|
+ valueList: data.map((item) => item.count),
|
|
|
+ sumType0List: data.map((item) => item.sumType0 || 0),
|
|
|
+ sumType1List: data.map((item) => item.sumType1 || 0),
|
|
|
+ sumType2List: data.map((item) => item.sumType2 || 0)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ const pieChartOptions = computed<EChartsOption>(() => {
|
|
|
+ const colors = generateUniqueColors(chartInfo.value.PieChart.length)
|
|
|
+ return {
|
|
|
+ color: colors,
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'item',
|
|
|
+ formatter: (params: any) => {
|
|
|
+ const data = chartInfo.value.PieChart[params.dataIndex]
|
|
|
+ const seriesName = params.seriesName
|
|
|
+ let value = 0
|
|
|
+ if (seriesName === '未播放') {
|
|
|
+ value = data.sumType0
|
|
|
+ } else if (seriesName === '未看完') {
|
|
|
+ value = data.sumType1
|
|
|
+ } else if (seriesName === '已看完') {
|
|
|
+ value = data.sumType2
|
|
|
+ }
|
|
|
+ return `${data.name}: ${value}`
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ legend: {
|
|
|
+ type: 'scroll',
|
|
|
+ orient: 'vertical',
|
|
|
+ right: 10,
|
|
|
+ top: 20,
|
|
|
+ bottom: 20
|
|
|
+ // top: '8%',
|
|
|
+ // left: 'center',
|
|
|
+ // itemGap: 35,
|
|
|
+ // textStyle: {
|
|
|
+ // fontSize: 14
|
|
|
+ // },
|
|
|
+ // padding: [0, 50]
|
|
|
+ },
|
|
|
+ grid: [
|
|
|
+ { left: '5%', top: '35%', width: '25%', height: '60%' },
|
|
|
+ { left: '37.5%', top: '35%', width: '25%', height: '60%' },
|
|
|
+ { left: '70%', top: '35%', width: '25%', height: '60%' }
|
|
|
+ ],
|
|
|
+ title: [
|
|
|
+ {
|
|
|
+ text: '未播放',
|
|
|
+ left: '17.5%',
|
|
|
+ top: '18%',
|
|
|
+ textAlign: 'center',
|
|
|
+ textStyle: {
|
|
|
+ fontSize: 16,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '未看完',
|
|
|
+ left: '50%',
|
|
|
+ top: '18%',
|
|
|
+ textAlign: 'center',
|
|
|
+ textStyle: {
|
|
|
+ fontSize: 16,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '已看完',
|
|
|
+ left: '82.5%',
|
|
|
+ top: '18%',
|
|
|
+ textAlign: 'center',
|
|
|
+ textStyle: {
|
|
|
+ fontSize: 16,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '未播放',
|
|
|
+ type: 'pie',
|
|
|
+ radius: ['30%', '45%'],
|
|
|
+ center: ['15%', '55%'],
|
|
|
+ avoidLabelOverlap: true,
|
|
|
+ itemStyle: {
|
|
|
+ borderRadius: 10,
|
|
|
+ borderColor: '#fff',
|
|
|
+ borderWidth: 2
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'outside',
|
|
|
+ formatter: '{b}:{c}',
|
|
|
+ fontSize: 12,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ // lineHeight: 20,
|
|
|
+ // minMargin: 25
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ fontSize: 16,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ show: true,
|
|
|
+ length: 15,
|
|
|
+ length2: 15
|
|
|
+ },
|
|
|
+ data: chartInfo.value.PieChart.map((item) => ({
|
|
|
+ name: item.name,
|
|
|
+ value: item.sumType0
|
|
|
+ }))
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '未看完',
|
|
|
+ type: 'pie',
|
|
|
+ radius: ['30%', '45%'],
|
|
|
+ center: ['45%', '55%'],
|
|
|
+ avoidLabelOverlap: true,
|
|
|
+ itemStyle: {
|
|
|
+ borderRadius: 10,
|
|
|
+ borderColor: '#fff',
|
|
|
+ borderWidth: 2
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'outside',
|
|
|
+ formatter: '{b}:{c}',
|
|
|
+ fontSize: 12,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ // lineHeight: 20
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ fontSize: 16,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ show: true,
|
|
|
+ length: 15,
|
|
|
+ length2: 15
|
|
|
+ },
|
|
|
+ data: chartInfo.value.PieChart.map((item) => ({
|
|
|
+ name: item.name,
|
|
|
+ value: item.sumType1
|
|
|
+ }))
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '已看完',
|
|
|
+ type: 'pie',
|
|
|
+ radius: ['30%', '45%'],
|
|
|
+ center: ['75%', '55%'],
|
|
|
+ avoidLabelOverlap: true,
|
|
|
+ itemStyle: {
|
|
|
+ borderRadius: 10,
|
|
|
+ borderColor: '#fff',
|
|
|
+ borderWidth: 2
|
|
|
+ },
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'outside',
|
|
|
+ formatter: '{b}:{c}',
|
|
|
+ fontSize: 12,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ // lineHeight: 20
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ fontSize: 16,
|
|
|
+ fontWeight: 'bold'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ show: true,
|
|
|
+ length: 15,
|
|
|
+ length2: 15
|
|
|
+ },
|
|
|
+ data: chartInfo.value.PieChart.map((item) => ({
|
|
|
+ name: item.name,
|
|
|
+ value: item.sumType2
|
|
|
+ }))
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ const barChartOptions = computed<EChartsOption>(() => {
|
|
|
+ const barChartInfo = chartInfo.value.BarChart
|
|
|
+ const colors = generateUniqueColors(barChartInfo.labelList.length)
|
|
|
+ return {
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ axisPointer: {
|
|
|
+ type: 'shadow',
|
|
|
+ label: {
|
|
|
+ show: true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ data: barChartInfo.labelList,
|
|
|
+ axisLabel: {
|
|
|
+ interval: 30,
|
|
|
+ // rotate: 30,
|
|
|
+ // width: 80, // 增加标签宽度
|
|
|
+ overflow: 'truncate' // 过长时显示省略号
|
|
|
+ }
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'log',
|
|
|
+ min: 1,
|
|
|
+ axisLabel: {
|
|
|
+ formatter: (value: number) => value.toLocaleString()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ dataZoom: [
|
|
|
+ {
|
|
|
+ show: true,
|
|
|
+ start: 94,
|
|
|
+ end: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 'inside',
|
|
|
+ start: 94,
|
|
|
+ end: 100
|
|
|
+ },
|
|
|
+ {
|
|
|
+ show: true,
|
|
|
+ yAxisIndex: 0,
|
|
|
+ filterMode: 'empty',
|
|
|
+ width: 30,
|
|
|
+ height: '80%',
|
|
|
+ showDataShadow: false,
|
|
|
+ left: '93%'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ color: colors,
|
|
|
+ grid: {
|
|
|
+ top: '12%',
|
|
|
+ left: '1%',
|
|
|
+ right: '10%',
|
|
|
+ containLabel: true
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '未播放',
|
|
|
+ data: barChartInfo.sumType0List.map((v) => v), // 处理 0 值
|
|
|
+ type: 'bar',
|
|
|
+
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'top',
|
|
|
+ formatter: '{c}'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '未看完',
|
|
|
+ data: barChartInfo.sumType1List.map((v) => v),
|
|
|
+ type: 'bar',
|
|
|
+
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'top',
|
|
|
+ formatter: '{c}'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '已看完',
|
|
|
+ data: barChartInfo.sumType2List.map((v) => v),
|
|
|
+ type: 'bar',
|
|
|
+
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ position: 'top',
|
|
|
+ formatter: '{c}'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
const chartOptions = computed(() => {
|
|
|
const pieChartInfo = chartInfo.value.PieChart.length ?? null
|
|
|
const barChartInfo = chartInfo.value.BarChart.valueList.length ?? null
|