|
@@ -0,0 +1,272 @@
|
|
|
+import { defineComponent, nextTick, onMounted, ref, shallowRef } from 'vue'
|
|
|
+import styles from './index.module.less'
|
|
|
+import * as echarts from 'echarts/core'
|
|
|
+import {
|
|
|
+ LineChart
|
|
|
+ // LineSeriesOption
|
|
|
+} from 'echarts/charts'
|
|
|
+// import { PieChart } from 'echarts/charts'
|
|
|
+import {
|
|
|
+ TitleComponent,
|
|
|
+ // 组件类型的定义后缀都为 ComponentOption
|
|
|
+ // TitleComponentOption,
|
|
|
+ TooltipComponent,
|
|
|
+ // TooltipComponentOption,
|
|
|
+ GridComponent,
|
|
|
+ // 数据集组件
|
|
|
+ DatasetComponent,
|
|
|
+ // DatasetComponentOption,
|
|
|
+ // 内置数据转换器组件 (filter, sort)
|
|
|
+ // TransformComponent,
|
|
|
+ LegendComponent,
|
|
|
+ ToolboxComponent,
|
|
|
+ DataZoomComponent
|
|
|
+} from 'echarts/components'
|
|
|
+import { LabelLayout } from 'echarts/features'
|
|
|
+import { CanvasRenderer } from 'echarts/renderers'
|
|
|
+
|
|
|
+// 注册必须的组件
|
|
|
+echarts.use([
|
|
|
+ TitleComponent,
|
|
|
+ TooltipComponent,
|
|
|
+ GridComponent,
|
|
|
+ DatasetComponent,
|
|
|
+ // TransformComponent,
|
|
|
+ LabelLayout,
|
|
|
+ // UniversalTransition,
|
|
|
+ CanvasRenderer,
|
|
|
+ // PieChart,
|
|
|
+ ToolboxComponent,
|
|
|
+ LegendComponent,
|
|
|
+ DataZoomComponent,
|
|
|
+ LineChart
|
|
|
+])
|
|
|
+
|
|
|
+const lineChartOption = (params: {
|
|
|
+ xAxisData: any
|
|
|
+ seriesData: any
|
|
|
+ colors: {
|
|
|
+ lineColor?: string
|
|
|
+ startColor?: string
|
|
|
+ endColor?: string
|
|
|
+ unit?: string
|
|
|
+ }
|
|
|
+}) => {
|
|
|
+ return {
|
|
|
+ title: {
|
|
|
+ text: '单位:' + (params.colors.unit || '人'),
|
|
|
+ textStyle: {
|
|
|
+ color: '#777777',
|
|
|
+ fontSize: 13,
|
|
|
+ fontWeight: 400
|
|
|
+ }
|
|
|
+ },
|
|
|
+ legend: { show: false },
|
|
|
+ emphasis: { lineStyle: { width: 2 } },
|
|
|
+ xAxis: {
|
|
|
+ boundaryGap: false,
|
|
|
+ data: params.xAxisData,
|
|
|
+ type: 'category',
|
|
|
+ axisLine: { lineStyle: { color: '#8C8C8C' } },
|
|
|
+ lineStyle: { color: '#F2F2F2' }
|
|
|
+ },
|
|
|
+ color: [
|
|
|
+ params.colors.lineColor || '#2DC7AA'
|
|
|
+ // '#FF6079'
|
|
|
+ // '#2DC7AA',
|
|
|
+ // '#FF602C',
|
|
|
+ // '#91DD1C',
|
|
|
+ // '#FFA92C',
|
|
|
+ // '#BE7E2E',
|
|
|
+ // '#1C96DD',
|
|
|
+ // '#D22CFF',
|
|
|
+ // '#FF3C3C',
|
|
|
+ // '#1AEE3E',
|
|
|
+ // '#00c9ff'
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ lineStyle: { width: 1 },
|
|
|
+ data: params.seriesData,
|
|
|
+ symbol: 'circle',
|
|
|
+ name: '购买次数',
|
|
|
+ type: 'line',
|
|
|
+ areaStyle: {
|
|
|
+ color: {
|
|
|
+ type: 'linear',
|
|
|
+ x: 0,
|
|
|
+ y: 0,
|
|
|
+ x2: 0,
|
|
|
+ y2: 1,
|
|
|
+ colorStops: [
|
|
|
+ {
|
|
|
+ offset: 0,
|
|
|
+ color: params.colors.startColor || 'rgba(45, 199, 170, 0.23)'
|
|
|
+ // 0% 处的颜色
|
|
|
+ },
|
|
|
+ {
|
|
|
+ offset: 1,
|
|
|
+ // 100% 处的颜色
|
|
|
+ color: params.colors.endColor || 'rgba(45, 199, 170, 0)'
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ emphasis: { lineStyle: { width: 1 } }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ grid: {
|
|
|
+ bottom: '3%',
|
|
|
+ containLabel: true,
|
|
|
+ left: '3%',
|
|
|
+ right: '5%',
|
|
|
+ top: '40'
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ trigger: 'axis',
|
|
|
+ confine: true,
|
|
|
+ formatter: function (params: any) {
|
|
|
+ return params[0].name
|
|
|
+ },
|
|
|
+ backgroundColor: '#FF6079',
|
|
|
+ borderWidth: 0,
|
|
|
+ borderRadius: 24,
|
|
|
+ padding: [1, 4],
|
|
|
+ textStyle: {
|
|
|
+ color: '#FFFFFF',
|
|
|
+ fontSize: 12
|
|
|
+ }
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value',
|
|
|
+ splitLine: {
|
|
|
+ axisLine: { lineStyle: { color: '#8C8C8C' } },
|
|
|
+ lineStyle: { color: ['#f2f2f2'], type: 'dashed' }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ dataZoom: [{ type: 'inside', throttle: 100 }],
|
|
|
+ toolbox: { feature: { saveAsImage: { show: false } } }
|
|
|
+ }
|
|
|
+}
|
|
|
+export default defineComponent({
|
|
|
+ name: 'eChats-model',
|
|
|
+ props: {
|
|
|
+ list: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ type: {
|
|
|
+ type: String as PropType<'TIME' | 'NUM'>,
|
|
|
+ default: 'TIME'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ setup(props, { emit }) {
|
|
|
+ const chartId = 'eChart_' + Date.now() + props.type
|
|
|
+ const color = props.type === 'NUM' ? '#FF955D' : '#2DC7AA'
|
|
|
+ const statisticCounts = ref({
|
|
|
+ time: '',
|
|
|
+ browseCount: 0,
|
|
|
+ buyCount: 0
|
|
|
+ })
|
|
|
+ let myChart: echarts.ECharts
|
|
|
+
|
|
|
+ nextTick(() => {
|
|
|
+ myChart = echarts.init(document.getElementById(chartId) as HTMLDivElement)
|
|
|
+ })
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ nextTick(() => {
|
|
|
+ myChart.clear()
|
|
|
+ lineChartOption &&
|
|
|
+ myChart.setOption(
|
|
|
+ lineChartOption({
|
|
|
+ xAxisData: [
|
|
|
+ '01月',
|
|
|
+ '02月',
|
|
|
+ '03月',
|
|
|
+ '04月',
|
|
|
+ '05月',
|
|
|
+ '06月',
|
|
|
+ '07月',
|
|
|
+ '08月',
|
|
|
+ '09月',
|
|
|
+ '10月',
|
|
|
+ '11月',
|
|
|
+ '12月'
|
|
|
+ ],
|
|
|
+ seriesData: [
|
|
|
+ '0',
|
|
|
+ '0',
|
|
|
+ '0',
|
|
|
+ '0',
|
|
|
+ '0',
|
|
|
+ '0',
|
|
|
+ '0',
|
|
|
+ '2',
|
|
|
+ '0',
|
|
|
+ '8',
|
|
|
+ '10',
|
|
|
+ '0'
|
|
|
+ ],
|
|
|
+ colors: {
|
|
|
+ lineColor: color,
|
|
|
+ startColor:
|
|
|
+ props.type === 'NUM'
|
|
|
+ ? 'rgba(255, 149, 93, 0.23)'
|
|
|
+ : 'rgba(45, 199, 170, 0.23)',
|
|
|
+ endColor:
|
|
|
+ props.type === 'NUM'
|
|
|
+ ? 'rgba(255, 149, 93, 0)'
|
|
|
+ : 'rgba(45, 199, 170, 0)',
|
|
|
+ unit: props.type === 'NUM' ? '人' : '分钟'
|
|
|
+ }
|
|
|
+ })
|
|
|
+ )
|
|
|
+ myChart.on('highlight', function (params: any) {
|
|
|
+ const batch = params.batch || []
|
|
|
+ const options: any = myChart.getOption()
|
|
|
+ batch.forEach((item: any) => {
|
|
|
+ const batchIndex = item.dataIndex
|
|
|
+
|
|
|
+ const browseCount = options.series[0].data[batchIndex]
|
|
|
+ const buyCount = options.series[1].data[batchIndex]
|
|
|
+ statisticCounts.value = {
|
|
|
+ browseCount,
|
|
|
+ buyCount
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+ })
|
|
|
+ return () => (
|
|
|
+ <div class={styles.eChartSection}>
|
|
|
+ <div class={styles.eChartTitle}>
|
|
|
+ <div class={styles.left}>
|
|
|
+ <div class={styles.item} style={{ '--color': color } as any}>
|
|
|
+ {/* <span class={styles.line}></span> */}
|
|
|
+ {props.type === 'NUM' ? (
|
|
|
+ <>
|
|
|
+ <span class={styles.text}>{statisticCounts.value.time} 练习人数</span>
|
|
|
+ <span class={styles.num}>
|
|
|
+ {statisticCounts.value.browseCount}人
|
|
|
+ </span>
|
|
|
+ </>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ <span class={styles.text}>{statisticCounts.value.time} 练习时长</span>
|
|
|
+ <span class={styles.num}>
|
|
|
+ {statisticCounts.value.browseCount}
|
|
|
+ </span>
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class={styles.eChart}>
|
|
|
+ <div id={chartId} style="width: 100%; height: 100%;"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+})
|