<template>
  <el-container class="portrait">
    <el-header style="height: auto; padding-top: 1em">
      <el-card>
        <el-form ref="form" size="small" :inline="true" label-width="120px">
          <el-form-item label="选择应用">
            <el-select v-model="appSelect" placeholder="请选择">
              <el-option
                v-for="item in appList"
                :key="item.appid"
                :label="item.name"
                :value="item.appid"
              />
            </el-select>
          </el-form-item>
          <el-form-item style="float: right">
            <el-button type="primary" @click="getData"> 查询 </el-button>
          </el-form-item>
        </el-form>
      </el-card>
    </el-header>
    <el-main>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-card>
            <template #header>
              <span>用户性别分布</span>
            </template>
            <div ref="sex"></div>
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card>
            <template #header>
              <span>用户年龄分布</span>
            </template>
            <div ref="age"></div>
          </el-card>
        </el-col>
      </el-row>
      <br />
      <el-card>
        <template #header>
          <span>用户标签分布</span>
        </template>
        <div ref="tag"></div>
      </el-card>
      <br />
      <el-card>
        <template #header>
          <span>陕西省内用户分布</span>
        </template>

        <el-row :gutter="20">
          <el-col :span="12">
            <div ref="city"></div>
          </el-col>
          <el-col :span="12">
            <el-table :data="tableProData" style="width: 100%">
              <el-table-column prop="category" label="地名" />
              <el-table-column center prop="ct" label="访问人数" />
            </el-table>
          </el-col>
        </el-row>
      </el-card>
      <br />
      <el-row :gutter="20">
        <el-col :span="12">
          <el-card>
            <template #header>
              <span>用户机型分布</span>
            </template>
            <div ref="phone"></div>
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card>
            <template #header>
              <span>APP栏目用户分布</span>
            </template>
            <div ref="category"></div>
          </el-card>
        </el-col>
      </el-row>
      <br />
      <el-row :gutter="20">
        <el-col :span="12">
          <el-card>
            <template #header>
              <span>起点号用户访问排行</span>
            </template>
            <div ref="publisher"></div>
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card>
            <template #header>
              <span>重点节目用户访问排行</span>
            </template>
            <div ref="program"></div>
          </el-card>
        </el-col>
      </el-row>
    </el-main>
  </el-container>
</template>

<script setup>
import {
  getAppList,
  getSexData,
  getAgeData,
  getCityData,
  getTagData,
  getPhoneData,
  getCategoryData,
  getPublisherData,
  getProgramData
} from '@/api/portrait.js';
import { ref, onMounted } from 'vue';

import { createChart, numform, chart } from './tool';
import config from './config';

const appList = ref([]);
const tableProData = ref([]);
const appSelect = ref('');
const sex = ref(null);
const age = ref(null);
const tag = ref(null);
const city = ref(null);
const phone = ref(null);
const category = ref(null);
const publisher = ref(null);
const program = ref(null);

let sexChart = undefined;
let ageChart = undefined;
let tagChart = undefined;
let cityChart = undefined;
let phoneChart = undefined;
let categoryChart = undefined;
let publisherChart = undefined;
let programChart = undefined;

const createSex = (list = []) => {
  if (!sex.value || !list || list.length == 0) return;
  const p = {
    ...config.pieOption
  };
  p.series[0].data = list.map(v => {
    return {
      name: v.category,
      value: v.ct,
      selected: true
    };
  });
  sexChart = createChart(sex.value, sex.value.offsetWidth / 2, p, sexChart);
};

const createAge = (list = []) => {
  if (!age.value || !list || list.length == 0) return;

  const p = {
    ...config.pieOption
  };
  p.series[0].radius = ['40%', '70%'];
  p.series[0].itemStyle = {
    borderRadius: 5,
    borderColor: '#fff',
    borderWidth: 1
  };
  p.series[0].data = list.map(v => {
    return {
      name: v.category,
      value: v.ct,
      selected: true
    };
  });
  ageChart = createChart(age.value, age.value.offsetWidth / 2, p, ageChart);
};

const createTag = (list = []) => {
  if (!tag.value || !list || list.length == 0) return;
  let category = list.map(v => {
    return {
      name: v.category,
      value: v.ct
    };
  });
  let yName = []; // y轴名称
  let bgData = []; // 最大值用作背景显示的数据
  let maxValue = category[0].value; //最大值
  category = category.reverse();
  category.forEach(element => {
    yName.push(element.name);
    bgData.push({
      name: element.name,
      value: maxValue
    });
  });
  const p = {
    ...config.tagOption
  };
  p.xAxis.max = maxValue;
  p.yAxis[0].data = yName;
  p.yAxis[1].data = Array.from(
    { length: yName.length },
    (_, i) => i + 1
  ).reverse();
  p.yAxis[2].data = category;
  p.series[0].data = bgData;
  p.series[1].data = category;
  p.series[2].data = bgData;
  p.series[2].symbolBoundingData = maxValue;
  tagChart = createChart(tag.value, tag.value.offsetWidth / 2, p, tagChart);
};

const createCity = (list = []) => {
  if (!city.value || !list || list.length == 0) return;
  tableProData.value = list;
  let max = -Infinity,
    min = Infinity,
    values = [];
  for (let i = 0; i < list.length; i++) {
    const v = list[i];
    if (v.ct > max) max = v.ct;
    if (v.ct < min) min = v.ct;
    values.push({
      name: v.category,
      value: v.ct
      //   distribution: ((v.ct / t) * 100).toFixed(2) - 0 + '%'
    });
  }

  const p = {
    ...config.cityOption
  };
  p.visualMap.min = min;
  p.visualMap.max = max;
  p.tooltip.formatter = data => {
    if (isNaN(data.value)) return '';
    return `${data.name}<br/>${numform(data.value)}`;
  };
  p.visualMap.text = [max, min];
  p.series[0].data = values;
  cityChart = createChart(city.value, city.value.offsetWidth, p, cityChart);
};

const createPhone = (list = []) => {
  if (!phone.value || !list || list.length == 0) return;
  list = list.reverse();
  const p = {
    ...config.phoneOption
  };
  p.series[0].data = list.map(v => {
    return {
      value: v.ct,
      name: v.category
    };
  });
  phoneChart = createChart(
    phone.value,
    phone.value.offsetWidth / 2,
    p,
    phoneChart
  );
};

const createCategory = (list = []) => {
  if (!category.value || !list || list.length == 0) return;
  list = list.reverse();
  const p = {
    ...config.pieOption
  };

  p.series[0].radius = ['40%', '70%'];
  p.series[0].itemStyle = {
    borderRadius: 5,
    borderColor: '#fff',
    borderWidth: 1
  };
  p.series[0].data = list.map(v => {
    return {
      name: v.category,
      value: v.ct,
      selected: true
    };
  });
  categoryChart = createChart(
    category.value,
    category.value.offsetWidth / 2,
    p,
    categoryChart
  );
};

const createPublisher = (list = []) => {
  if (!publisher.value || !list || list.length == 0) return;
  const keys = [],
    values = [];
  let max = -Infinity;
  for (let i = 0; i < list.length; i++) {
    const v = list[i];
    keys.push(v.category);
    values.push(v.ct);
    if (max < v.ct) max = v.ct;
  }
  const p = {
    ...config.publisherOption
  };
  p.xAxis[0].data = keys;
  p.series[0].data = values;
  p.series[0].itemStyle = {
    normal: {
      borderRadius: [5, 5, 0, 0],
      color: new chart.graphic.LinearGradient(0, 0, 1, 0, [
        {
          offset: 0,
          color: '#8ba6d6'
        },
        {
          offset: 1,
          color: '#a085ee'
        }
      ])
    }
  };
  publisherChart = createChart(
    publisher.value,
    publisher.value.offsetWidth,
    p,
    publisherChart
  );
};

const createProgram = (list = []) => {
  if (!program.value || !list || list.length == 0) return;
  const keys = [],
    values = [];
  let max = -Infinity;
  list = list.reverse();
  for (let i = 0; i < list.length; i++) {
    const v = list[i];
    keys.push(v.category);
    values.push(v.ct);
    if (max < v.ct) max = v.ct;
  }
  const p = {
    ...JSON.parse(JSON.stringify(config.publisherOption))
  };
  p.xAxis[0].data = keys;
  p.series[0].data = values;
  const xAxis = JSON.parse(JSON.stringify(p.xAxis));
  const yAxis = JSON.parse(JSON.stringify(p.yAxis));
  p.yAxis = xAxis;
  p.xAxis = yAxis;
  p.grid = {
    top: '5%',
    left: 5,
    right: 5,
    bottom: '6%',
    containLabel: true
  };
  p.series[0].label.offset = [50, 0];
  p.series[0].label.position = 'right';
  p.series[0].label.align = 'right';
  p.series[0].itemStyle = {
    normal: {
      borderRadius: [0, 5, 5, 0],
      color: new chart.graphic.LinearGradient(0, 0, 1, 0, [
        {
          offset: 0,
          color: '#8ba6d6'
        },
        {
          offset: 1,
          color: '#a085ee'
        }
      ])
    }
  };
  p.series[0].label.formatter = data => {
    if (isNaN(data.value)) return '';
    return numform(data.value);
  };
  programChart = createChart(
    program.value,
    publisher.value.offsetWidth,
    p,
    programChart
  );
};

const getData = () => {
  Promise.all([
    getSexData({ appid: appSelect.value }),
    getAgeData({ appid: appSelect.value }),
    getCityData({ appid: appSelect.value }),
    getTagData({ appid: appSelect.value }),
    getPhoneData({ appid: appSelect.value }),
    getCategoryData({ appid: appSelect.value }),
    getPublisherData({ appid: appSelect.value }),
    getProgramData({ appid: appSelect.value })
  ]).then(list => {
    createSex(list[0]);
    createAge(list[1]);
    createCity(list[2]);
    createTag(list[3]);
    createPhone(list[4]);
    createCategory(list[5]);
    createPublisher(list[6]);
    createProgram(list[7]);
  });
};

onMounted(() => {
  getAppList().then(res => {
    appSelect.value = (res || [])[0].appid;
    appList.value = res || [];
    getData();
  });
});
</script>
