|
@@ -0,0 +1,246 @@
|
|
|
+<template>
|
|
|
+ <div class="video" ref="bg">
|
|
|
+ <video
|
|
|
+ ref="video"
|
|
|
+ :controls="false"
|
|
|
+ autoplay
|
|
|
+ @timeupdate="timeupdate"
|
|
|
+ @error="videoerror"
|
|
|
+ @canplay="videoload"
|
|
|
+ :src="props.item.video_url"
|
|
|
+ ></video>
|
|
|
+ <div ref="chartEle"></div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+// @ is an alias to /src
|
|
|
+import { defaultAjax } from '@/api/index';
|
|
|
+import { ref, defineProps, onMounted } from 'vue';
|
|
|
+const video = ref(null);
|
|
|
+const bg = ref(null);
|
|
|
+const chartEle = ref(null);
|
|
|
+const props = defineProps({
|
|
|
+ item: Object,
|
|
|
+});
|
|
|
+import * as echarts from 'echarts';
|
|
|
+let chart = undefined;
|
|
|
+let timeout = undefined;
|
|
|
+let isClick = false;
|
|
|
+onMounted(() => {
|
|
|
+ chart = echarts.init(chartEle.value);
|
|
|
+ chart.resize({
|
|
|
+ height: (bg.value.offsetWidth * 6) / 20,
|
|
|
+ width: bg.value.offsetWidth,
|
|
|
+ });
|
|
|
+
|
|
|
+ chart.on('datazoom', () => {
|
|
|
+ if (isClick) return;
|
|
|
+ isClick = true;
|
|
|
+ if (timeout) clearTimeout(timeout), (timeout = undefined);
|
|
|
+ video.value.pause();
|
|
|
+ timeout = setTimeout(() => {
|
|
|
+ clearTimeout(timeout);
|
|
|
+ timeout = undefined;
|
|
|
+ isClick = false;
|
|
|
+ // 拖拽后的事件
|
|
|
+ video.value.currentTime = chart.getOption().dataZoom[0].startValue;
|
|
|
+ video.value.play();
|
|
|
+ }, 200);
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
+props.item.flow_url &&
|
|
|
+ defaultAjax({
|
|
|
+ url: props.item.flow_url,
|
|
|
+ }).then(r => {
|
|
|
+ console.log(r);
|
|
|
+ draw(r);
|
|
|
+ });
|
|
|
+
|
|
|
+function timeupdate() {
|
|
|
+ // 播放中
|
|
|
+ // console.log('播放中');
|
|
|
+}
|
|
|
+
|
|
|
+function videoerror(err) {
|
|
|
+ console.log('播放错误:', err);
|
|
|
+}
|
|
|
+
|
|
|
+function videoload() {
|
|
|
+ // 可以播放
|
|
|
+ console.log('可以播放', video.value);
|
|
|
+}
|
|
|
+
|
|
|
+function draw(r) {
|
|
|
+ // 绘图
|
|
|
+ const key = Object.keys(r);
|
|
|
+ const value = Object.values(r);
|
|
|
+ const Ir = [],
|
|
|
+ Ic = [],
|
|
|
+ ad = [];
|
|
|
+ let stepNum = 6.8,
|
|
|
+ page = 0;
|
|
|
+ value.map(v => {
|
|
|
+ Ic.push(-1 * v.lc);
|
|
|
+ Ir.push(v.lr);
|
|
|
+ ad.push(v.audienceRating * 100);
|
|
|
+ });
|
|
|
+ let option = {
|
|
|
+ dataZoom: [
|
|
|
+ {
|
|
|
+ maxSpan: 10,
|
|
|
+ minSpan: 5,
|
|
|
+ type: 'slider',
|
|
|
+ brushSelect: false,
|
|
|
+ // zoomLock: false,
|
|
|
+ show: true,
|
|
|
+ realtime: true,
|
|
|
+ start: stepNum * page,
|
|
|
+ end: stepNum * (page + 1),
|
|
|
+ zoomOnMouseWheel: false,
|
|
|
+ height: '30',
|
|
|
+ top: '85%',
|
|
|
+ handleIcon:
|
|
|
+ 'path://M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
|
|
|
+ handleSize: 15,
|
|
|
+ textStyle: {
|
|
|
+ color: '#c5c6cc',
|
|
|
+ },
|
|
|
+ dataBackground: {
|
|
|
+ lineStyle: {
|
|
|
+ color: '#fff',
|
|
|
+ },
|
|
|
+ areaStyle: {
|
|
|
+ color: '#8b51a8',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ xAxis: {
|
|
|
+ data: key,
|
|
|
+ position: 'top',
|
|
|
+ silent: false,
|
|
|
+ axisLabel: {
|
|
|
+ interval: 'auto',
|
|
|
+ color: '#000',
|
|
|
+ rotate: '-90',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {
|
|
|
+ scale: false,
|
|
|
+ nameGap: 6,
|
|
|
+ inverse: false,
|
|
|
+ name: '流入流出',
|
|
|
+ nameLocation: 'start',
|
|
|
+ splitArea: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ color: '#000',
|
|
|
+ formatter: function (value) {
|
|
|
+ let v = value;
|
|
|
+ if (v < 0) v *= -1;
|
|
|
+ return v;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ axisTick: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ nameTextStyle: {
|
|
|
+ color: '#000',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ scale: true,
|
|
|
+ nameGap: 6,
|
|
|
+ type: 'value',
|
|
|
+ name: '收视率%',
|
|
|
+ nameLocation: 'start',
|
|
|
+ splitLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ axisTick: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ color: '#000',
|
|
|
+ },
|
|
|
+ nameTextStyle: {
|
|
|
+ color: '#000',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ grid: {
|
|
|
+ left: 50,
|
|
|
+ right: 50,
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: '流入',
|
|
|
+ type: 'bar',
|
|
|
+ yAxisIndex: 0,
|
|
|
+ stack: 'one',
|
|
|
+ data: Ir,
|
|
|
+ sampling: 'lttb',
|
|
|
+ emphasis: {
|
|
|
+ focus: 'series',
|
|
|
+ },
|
|
|
+ itemStyle: {
|
|
|
+ color: '#df5a5a',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '流出',
|
|
|
+ type: 'bar',
|
|
|
+ yAxisIndex: 0,
|
|
|
+ sampling: 'lttb',
|
|
|
+ stack: 'one',
|
|
|
+ data: Ic,
|
|
|
+ emphasis: {
|
|
|
+ focus: 'series',
|
|
|
+ },
|
|
|
+ itemStyle: {
|
|
|
+ color: '#6ab581',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '收视率%',
|
|
|
+ type: 'line',
|
|
|
+ yAxisIndex: 1,
|
|
|
+ smooth: true,
|
|
|
+ showSymbol: false,
|
|
|
+ data: ad,
|
|
|
+ lineStyle: {
|
|
|
+ width: 1,
|
|
|
+ color: '#50abfd',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ option && chart.setOption(option);
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.video {
|
|
|
+ padding: 0.5em;
|
|
|
+
|
|
|
+ video {
|
|
|
+ width: 100%;
|
|
|
+ max-width: 720px;
|
|
|
+ margin: 0 auto;
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|