123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450 |
- <template>
- <div class="live" style="padding-bottom: 1em">
- <table class="local_table">
- <tr>
- <td
- v-if="baseData.peopel_time !== -1"
- @click="() => showDetail('peopel_time')"
- >
- 直播观看人次
- <!-- <div class="showD">?</div> -->
- </td>
- <td v-if="baseData.peopel_time !== -1">
- {{ baseData.peopel_time | formatnum }}
- </td>
- <td
- v-if="baseData.msg_count !== -1"
- @click="() => showDetail('msg_count')"
- >
- 直播评论数
- <!-- <div class="showD">?</div> -->
- </td>
- <td v-if="baseData.msg_count !== -1">
- {{ baseData.msg_count | formatnum }}
- </td>
- </tr>
- <tr>
- <td
- v-if="baseData.avg_user_count !== -1"
- @click="() => showDetail('avg_user_count')"
- >
- 平均在线人数
- <!-- <div class="showD">?</div> -->
- </td>
- <td v-if="baseData.avg_user_count !== -1">
- {{ baseData.avg_user_count | formatnum }}
- </td>
- <td
- v-if="baseData.total_fans_count !== -1"
- @click="() => showDetail('total_fans_count')"
- >
- 新增粉丝数
- <!-- <div class="showD">?</div> -->
- </td>
- <td v-if="baseData.total_fans_count !== -1">
- {{ baseData.total_fans_count | formatnum }}
- </td>
- </tr>
- <tr>
- <td
- v-if="baseData.turn_rate !== -1"
- @click="() => showDetail('turn_rate')"
- >
- 转粉率
- <!-- <div class="showD">?</div> -->
- </td>
- <td v-if="baseData.turn_rate !== -1">
- {{ baseData.turn_rate | formatnum }}
- </td>
- <td
- v-if="baseData.total_fans_count !== -1"
- @click="() => showDetail('total_fans_count')"
- >
- 最大在线人数
- <!-- <div class="showD">?</div> -->
- </td>
- <td v-if="baseData.total_fans_count !== -1">
- {{ baseData.total_fans_count | formatnum }}
- </td>
- </tr>
- </table>
- <div v-if="gender.length" class="title">观众性别分布</div>
- <canvas
- v-if="gender.length"
- id="audienceSex"
- class="canvas"
- :width="client.width"
- :height="client.height"
- ></canvas>
- <div class="title">观众地域分布</div>
- <div
- id="audienceRegion"
- ref="audienceRegion"
- class="canvas"
- :style="{width: client.width + 'px', height: client.height + 'px'}"
- ></div>
- <!-- <canvas
- id="audienceRegion"
- ref="audienceRegion"
- class="canvas"
- :width="client.width"
- :height="client.height"
- ></canvas> -->
- <div v-if="RealTimeTraffic.peopleList.length" class="title">实时流量</div>
- <canvas
- v-if="RealTimeTraffic.peopleList.length"
- id="RealTimeTraffic"
- class="canvas"
- :width="client.width"
- :height="client.height"
- ></canvas>
- <div v-if="RealTimePersonTime.peopleList.length" class="title">
- 观看人次
- </div>
- <canvas
- v-if="RealTimePersonTime.peopleList.length"
- id="RealTimePersonTime"
- class="canvas"
- :width="client.width"
- :height="client.height"
- ></canvas>
- <div v-if="LikeTheTrend.peopleList.length" class="title">点赞走势</div>
- <canvas
- v-if="LikeTheTrend.peopleList.length"
- id="LikeTheTrend"
- class="canvas"
- :width="client.width"
- :height="client.height"
- ></canvas>
- </div>
- </template>
- <style scoped>
- .live {
- height: 100%;
- overflow-y: scroll;
- }
- .showD {
- display: inline-block;
- width: 1.1em;
- height: 1.1em;
- text-align: center;
- line-height: 1.15em;
- border-radius: 50%;
- border: 1px solid #1989fa;
- color: #1989fa;
- display: none;
- }
- </style>
- <script>
- import { getlive } from "@/api/getList.js";
- import filters from "@/utils/filters/index";
- import F2 from "@antv/f2/lib/index-all";
- // import DataSet from "@antv/data-set";
- import mapJSON from "./mapJSON.js";
- import { Dialog } from "vant";
- import "vant/lib/dialog/style";
- import * as echarts from "echarts";
- export default {
- components: {},
- props: {
- title: {
- type: String,
- value: "",
- },
- season: {
- type: String,
- value: 1,
- },
- },
- data() {
- return {
- colors: {},
- initCanvas: {
- audienceSex: undefined,
- account: undefined,
- },
- baseData: {},
- client: {
- width: 0,
- height: 0,
- },
- gender: [],
- RealTimeTraffic: { title: "实时流量", peopleList: [] },
- RealTimePersonTime: { title: "观看人次", peopleList: [] },
- LikeTheTrend: { title: "点赞走势", peopleList: [] },
- };
- },
- created() {
- let title = decodeURIComponent(this.title);
- let clientWidth = document.body.clientWidth || 0;
- this.client = {
- width: clientWidth,
- height: (clientWidth / 16) * 9,
- };
- getlive({
- topic: title,
- platform: "douyin",
- season: this.season,
- }).then(res => {
- let oriData = res || {};
- let trend = oriData.trend || {};
- let RealTimeTraffic = {
- title: "实时流量",
- peopleList: [],
- };
- let RealTimePersonTime = {
- title: "观看人次",
- peopleList: [],
- };
- let LikeTheTrend = {
- title: "点赞走势",
- peopleList: [],
- };
- // 趋势图数据
- for (let i = 0; i < (trend.webcastTrendList || []).length; i++) {
- const v = (trend.webcastTrendList || [])[i];
- let time = v.crawl_date.split(" ")[1] || "";
- v.user_count !== undefined &&
- RealTimeTraffic.peopleList.push({
- value: v.user_count || 0,
- time: time,
- });
- v.stats_total_user !== undefined &&
- RealTimePersonTime.peopleList.push({
- value: v.stats_total_user || 0,
- time: time,
- });
- v.like_count !== undefined &&
- LikeTheTrend.peopleList.push({
- value: v.like_count || 0,
- time: time,
- });
- }
- // 基础数据
- let core_date = oriData.core_data || {};
- this.baseData = {
- msg_count: oriData.webcastMessageList
- ? oriData.webcastMessageList.count || 0
- : 0,
- like_count: core_date.like_count || 0,
- total_fans_count: core_date.add_fans_count || 0,
- peopel_time: (trend.user || {}).stats_total_user || 0,
- avg_user_count: core_date.avg_user_count || 0,
- max_user_count: core_date.max_user_count || 0,
- turn_rate: (core_date.turn_rate || 0) * 100,
- };
- // 来源城市
- let city = oriData.city || [];
- for (let i = 0; i < city.length; i++) {
- const element = city[i] || {};
- for (let o = 0; o < mapJSON.features.length; o++) {
- const item = mapJSON.features[o];
- if (item.properties.name === element.key) {
- item.properties.value = ((element.rate * 100).toFixed(1) - 0);
- break;
- }
- }
- }
- // 性别比
- let gender = [];
- let oriGender = oriData.gender || [];
- for (let i = 0; i < oriGender.length; i++) {
- const v = oriGender[i];
- gender.push({
- name: v.key == "1" ? "男" : "女",
- percent: v.count,
- a: "1",
- });
- }
- this.gender = gender;
- this.RealTimeTraffic = RealTimeTraffic;
- this.RealTimePersonTime = RealTimePersonTime;
- this.LikeTheTrend = LikeTheTrend;
- this.$nextTick(() => {
- this.cake(gender);
- RealTimeTraffic.peopleList.length &&
- this.line(RealTimeTraffic.peopleList, "RealTimeTraffic");
- RealTimePersonTime.peopleList.length &&
- this.line(RealTimePersonTime.peopleList, "RealTimePersonTime");
- LikeTheTrend.peopleList.length &&
- this.line(LikeTheTrend.peopleList, "LikeTheTrend");
- this.map();
- });
- });
- },
- methods: {
- cake(list) {
- const chart = new F2.Chart({
- id: "audienceSex",
- pixelRatio: window.devicePixelRatio,
- });
- chart.source(list, {
- percent: {
- formatter: function formatter(val) {
- return val * 100 + "%";
- },
- },
- });
- chart.tooltip(false);
- chart.coord("polar", {
- transposed: true,
- radius: 0.75,
- });
- chart.legend(false);
- chart.axis(false);
- // 添加饼图文本
- chart.pieLabel({
- sidePadding: 40,
- label1: function label1(data, color) {
- return {
- text: data.name + ":" + filters.formatNum(data.percent) + "人",
- fill: color,
- };
- },
- });
- chart
- .interval()
- .position("a*percent")
- .color("name", ["#13C2C2", "#2FC25B", "#FACC14", "#F04864", "#8543E0"])
- .adjust("stack")
- .style({
- lineWidth: 1,
- stroke: "#fff",
- lineJoin: "round",
- lineCap: "round",
- })
- .animate({
- appear: {
- duration: 1200,
- easing: "bounceOut",
- },
- });
- chart.render();
- this.initCanvas.audienceSex = chart;
- },
- line(list, id) {
- const chart = new F2.Chart({
- id,
- pixelRatio: window.devicePixelRatio,
- });
- chart.source(list, {
- time: {
- tickCount: 3,
- range: [0, 1],
- },
- value: {
- tickCount: 5,
- min: 0,
- },
- });
- chart.axis("time", {
- label: function label(text, index, total) {
- const textCfg = {};
- if (index === 0) {
- textCfg.textAlign = "left";
- } else if (index === total - 1) {
- textCfg.textAlign = "right";
- }
- return textCfg;
- },
- });
- chart.axis("value", {
- label: function label(text) {
- return { text: filters.formatNum(text) };
- },
- });
- chart.tooltip({
- showTitle: true,
- });
- chart
- .area()
- .position("time*value")
- .color("l(90) 0:#1890FF 1:#f7f7f7")
- .shape("smooth");
- chart
- .line()
- .position("time*value")
- .color("#1890FF")
- .shape("smooth")
- .size(0.5);
- chart.render();
- },
- map() {
- let myChart = echarts.init(this.$refs.audienceRegion);
- window.onresize = myChart.resize;
- echarts.registerMap("china", mapJSON);
- let data = mapJSON.features.map(v => {
- return {
- name: v.properties.name,
- value: v.properties.value,
- };
- });
- data = data.sort((a, b) => {
- return b.value - a.value;
- });
- myChart.setOption({
- tooltip: {
- show: true,
- triggerOn: "click",
- formatter: "{c}%",
- },
- visualMap: {
- show: false,
- min: 0,
- max: data[0].value,
- inRange: {
- color: ["rgba(0,0,0,.0)", "yellow"],
- },
- },
- series: [
- {
- type: "map",
- mapType: "china",
- geoIndex: 0,
- zoom: 1.25,
- label: {
- show: false,
- },
- itemStyle: {
- normal: {
- borderColor: "#76acff", //每个区域的边框色
- areaColor: "rgba(118,172,255, 0)", //区域背景色
- },
- },
- data,
- },
- ],
- });
- },
- showDetail(key) {
- let val = "",
- nameText = "";
- let list = this.$parent.$parent.$parent.$parent.config || [];
- for (let i = 0; i < list.length; i++) {
- const v = list[i];
- if (key !== v.name || v.topic_id !== this.baseData.topic_id) continue;
- val = v.value;
- nameText = v.content_desc;
- break;
- }
- if (!val) return;
- Dialog.alert({
- confirmButtonText: "关闭",
- title: this.$route.query.title + "-" + nameText,
- message: val,
- confirmButtonColor: "#1989fa",
- messageAlign: "left",
- theme: "round-button",
- });
- },
- },
- };
- </script>
|