<template>
    <div class="echart_content">
        <div class="is_show_all" v-if="showCheckBox">
            <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate"  @change="ToggleChangeAll" >
                显示全部
            </el-checkbox>
        </div>
        <div ref="line_chart" class="chart_box" :style="{height:reportHeight || '400px'}"></div>
    </div>
</template>
<script>
import _ from 'lodash'
import * as echarts from 'echarts';

export default {
    name: "lineChart",//折线图组件
    data() {
        return {
            echart: null,//图标实例

            checkAll: true,//是否显示全部
            isIndeterminate: false,
            legendSelected: {},//图例选中状态
            legenSelectList: [],//选择的图例
            legenAllList:this.title,//所有的图例数据

        }
    },

    props: {
        gridRight: {
            type: Number,
            default: 0,
        },//grid右间距
        gridTop: {
            type: [Number,String],
            default: '',
        },
        legendWidth: {
            type: [Number,String],
            default: 'auto',
        },
        showCheckBox: {
            type: Boolean,
            default: true,
        },//是否显示全部按钮
        extraText: {
            type: Boolean,
            default: true,
        },//是否占比

        datax: {
            type: Array,
            default: function () {
                return ['G10', 'G9', 'G8', 'G7', 'G6', 'G5', 'G4', 'G3', 'G2', 'G1'];
            }
        },//x轴数据
        datay: {
            type: Array,
            default: function () {
                return [
                   

                ];
            }
        },//y轴数据

        tooltipData:{
            type: Array,
            default: function () {
                return [];
            }
        },//悬浮弹窗的数据
        colors: {
            type: Array,
            default: function () {
                return this.$global.getScorePerformanceAnalysis();
            }
        },//柱状图颜色
        unit: {
            type: String,
            default: ''
        },//单位
        title: {
            type: Array,
            default: ()=>[]
        },//图例标题
        // isSetMarkNumber:{
        //     type: Boolean,
        //     default: false
        // },//是否设置辅助线label值
        markNumber: {
            type: Array,
            default: ()=>[]
        },//辅助线位置值 

        isSmooth: {
            type: Boolean,
            default: false
        },//是否是曲线图

        // showMarkLine: {
        //     type: Boolean,
        //     default: false
        // },//是否显示辅助线平均值

        showBackground:{
            type:Boolean,
            default:true,
        },//是否显示背景阴影  默认显示

        isShowLabel:{
            type:Boolean,
            default:false,
        },//是否显示柱状图label  默认显示
        labelColor:{
            type: String,
            default:'',
        },//柱状图label 颜色
        showMarkPoint:{
            type: Boolean,
            default:false,
        },//是否显示气泡图  默认不显示

        legendList:{
            type: Array,
            default: () => [],
        },//默认显示的图例数据  

        yInverse:{
            type:Boolean,
            default:false,
        },//y轴是否反序

        updateKey:{
            type:Number,
            default:0
        },
        gridLeft:{
            type:Number,
            default:20
        },
        fontSize:{//字体大小
            type:[Number,String],
            default:''
        },
        fontColor:{
            type:String,
            default:''
        },
        reportHeight:{//报告高度
            type:String,
            default:''
        }

    },
    watch: {


        legendList()
        {
            this.LoadEchart();
        },//重新加载图表
        updateKey()
        {
            this.LoadEchart();
        },//重新加载图表

        datay: {
            handler: 'LoadEchart',
            deep: true,
        },//数值变化时重新加载图表
    },
    created() {
        window.addEventListener('resize', this.HandleResize);//创建时增加监听窗口变化事件
    },
    beforeDestroy() {
        // 组件销毁移除监听 防止内存泄漏
        window.removeEventListener('resize', this.HandleResize);
        this.echart.dispose(); // 销毁之前的实例
    },
    mounted() 
    {
     
        this.LoadEchart();//初始化图表
        this.HandleResize()
    },
    methods: {
        markLine(index){
            return this.markNumber.length ? {
                data: [{
                    type: 'average',
                    name: '平均值',
                    yAxis: this.markNumber.length?this.markNumber[index]:null//Y 值为给定值的标记线
                }],
                label: {
                    position:"end",
                    formatter: (params)=>{
                        if(this.markNumber.length){
                            return this.markNumber[index]
                        }else{
  
                            return params.value//' {c}'
                        }
                    }// 显示平均值数值
                },
                lineStyle: {
                    type: 'dashed', // 虚线样式
                    color: this.colors[index]// 线条颜色
                }
            } : {}
        },
        //加载echarts
        LoadEchart() 
        {
            
            // 简化图例选中列表的初始化
            this.legenSelectList = this.legendList.length > 0 
                ? [...this.legendList] 
                : []; //
            
            this.legenAllList = [...this.title];
           
            if (this.echart) {
                this.echart.dispose(); // 销毁之前的实例
            }
            //devicePixelRatio: 2   2表示每个逻辑像素对应 2 个物理像素。这会进一步提高图表的清晰度，适用于更高分辨率的屏幕  解决高分辨率显示器文字模糊的问题
            this.echart = echarts.init(this.$refs.line_chart, { devicePixelRatio: 2 });//获取echarts容器  如果组件同一个页面多处使用 这里不能用id获取实例
            
            // 图例选中状态初始化
            this.legendSelected = {};
            this.title.forEach((name, index) => {
                this.legendSelected[name] = this.legenSelectList.includes(name);
            });
            
            // 更新全选状态
            this.checkAll = this.legenSelectList.length === this.legenAllList.length;
            this.isIndeterminate = this.legenSelectList.length > 0 && 
                                this.legenSelectList.length < this.legenAllList.length;
           

            console.log("打印this.isIndeterminate",this.isIndeterminate);
            const maxValue = Math.max(...this.datay.flat());
            const minValue=Math.min(...this.datay.flat());
            const hideTick = minValue < 0 || this.yInverse;//是否隐藏刻度线 最小值小于0  或者反序y轴的时候隐藏刻度线
            // console.log("打印最小值",minValue);
            // 获取当前显示图例对应数据中的最大值
            const visibleSeriesIndices = this.legenSelectList.map(name => this.title.indexOf(name));
            const visibleData = visibleSeriesIndices
                .filter(index => index !== -1)
                .map(index => this.datay[index]);

            // const maxValue = visibleData.reduce((max, series) => {
            //     const seriesMax = Math.max(...series);
            //     return seriesMax > max ? seriesMax : max;
            // }, -Infinity);
            
            // const yAxisMax =  Math.ceil((maxValue+2) / 5) * 5;//向上取整到5的倍数
            // console.log("打印最大值",maxValue);
            const extraText=this.extraText?"占比":""
            const dataCount=this.datax.length;
            // if(maxValue<10)
            // {
            //     maxValue=9
            // }
            //计算每个x轴的宽度 
            let totalWidth = this.$refs.line_chart.clientWidth;
            let singleSeriesWidth = (totalWidth - 100)/dataCount;
            // console.log("打印x轴宽度",singleSeriesWidth);
            let gridTop= this.showMarkPoint ? 45 : 20;
            // 无图例 默认20  有图例 70
            if(this.title.length>0)
            {
                gridTop=70;
            }
            let option = {

                tooltip: {
                    trigger: 'axis',

                    axisPointer: {
                        type: 'line', // 指示器类型，cross 表示交叉指示线
                        // lineStyle: {
                        //     color: 'red',
                        //     width: 2,
                        //     type: 'dashed'
                        // },
                        // crossStyle: {
                        //     color: '#999', // 交叉线颜色
                        //     width: 1,      // 交叉线宽度
                        //     type: 'dashed' // 交叉线样式
                        // }
                    },

                    renderModel: 'html',//使用html渲染模式
                    confine: true,//是否将 tooltip 框限制在图表的区域内。
                    extraCssText: 'border-radius: 4px;padding:5px 0px 5px 5px;white-space:normal;word-warp:break-word;max-width: 400px;', // 设置最大宽度和高度
                    enterable: true,
                    formatter: (params) => {
                        // console.log(params);
                        
                        // console.log("打印this.tooltipData",this.tooltipData);
                       
                            let tooltip = `<div class='tooltip_content'>`;
                            let title = params[0].name;
                            tooltip += `<div class='tooltip_title'>${title}</div>`;
                            params.forEach((item, index) => {
                                // console.log("打印item",item);
                                let name = item.seriesName;
                                let rate = item.value+this.unit;//占比
                                if(this.tooltipData.length>0)
                                {
                                    let tooltipItem=this.tooltipData?.[item.seriesIndex]?.[item.dataIndex] || '';
                                    tooltip += `<div class='tooltip_student'>
                                        <div class='tooltip_line_icon' style='background:${item.color}'></div>
                                        <div class='tooltip_student_name'>
                                             ${tooltipItem.name}：${tooltipItem.value}
                                        </div></div>`;
                                }
                                else{
                                    tooltip += `<div class='tooltip_student'><div class='tooltip_line_icon' style='background:${item.color}'></div><div class='tooltip_student_name'>${name}${extraText}：${rate || '-'}</div></div>`;
                                }
                                
                            })
                            tooltip += `</div>`;
                            return tooltip;
                        
                        
                        
                    },
                },
                legend: {
                    show: this.title.length ? true : false,//是否显示图例
                    left: this.showCheckBox ? "110px" : "0px",//图例距左边距离  有显示全部的 默认110px
                    width:this.legendWidth,
                    itemGap: 20,//图例间距
                    itemHeight: 10,//图例的高度
                    itemWidth: 25,//图例的宽度

                    
                    data: this.title,
                    textStyle: {
                        fontSize: 12, 
                        color: "#333",
                        lineHeight: 30,
                    },
                    selectedMode: true,//允许图例切换显示
                    selected: this.legendSelected, // 绑定图例选中状态
                    type:'scroll',//启用图例滚动  翻页功能
                    pageIconColor: '#999', // 翻页按钮默认颜色
                    pageIconInactiveColor: '#ccc', // 翻页按钮禁用状态颜色
                    pageButtonItemGap: 5, // 分页按钮与图例的间距
                    pageButtonPosition: 'end', // 分页按钮显示在右侧
                    orient: 'horizontal', // 图例横向排列（也可以设为 'vertical'）
                    alignTo: 'none',//alignTo 可以用于图例 (legend) 的配置项，决定图例如何对齐到其他元素。常见的值包括 'left', 'right', 'center' 等。
                    // icon:'emptyCircle',//标记类型 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow', 'none'
                },
                grid: {
                    left: this.gridLeft,
                    right: this.gridRight,
                    top: this.gridTop || gridTop,
                    bottom:0,
                    containLabel: true, //用于控制网格区域是否包含坐标轴的标签  true 可以确保所有标签都能完整显示，不会被裁剪。
                },
                xAxis: {
                    type: 'category',
                    data: this.datax,
                    boundaryGap: true,
                    triggerEvent: true,

                    axisTick: {
                        alignWithLabel: true,//不然刻度线跟随标签对齐
                        // show: !this.yInverse,            // 显示刻度线
                        show:!hideTick,
                        inside: false,         // 刻度线朝外（默认是朝内）
                        length: 8,             // 刻度线长度
                        // lineStyle: {
                        //     color: "#E4E7ED",       // 刻度线颜色
                        //     width: 1             // 线宽
                        // },
                        // color:'#E4E7ED'
                    },
                    axisLine:{
                        show:!this.yInverse,
                    },
                    axisLabel: {
                        interval: 0,//0 显示所有刻度
                        rotate: singleSeriesWidth < 60 ? 45 : 0,
                        fontSize: this.fontSize?this.fontSize:14,
                        color: this.fontColor || "#666",
                        fontWeight: 400,
                        formatter:function(value) {
                            
                            //一个文字的长度大概约16.6  按16算
              
                            const valueWidth = value.length*14;
                            // console.log("lineChart打印字的大概宽度",valueWidth);
                            // console.log("打印singleSeriesWidth",singleSeriesWidth);
                            if(valueWidth>singleSeriesWidth)
                            {
                               
                                    //单系列宽度小于50 倾斜显示
                                    if(singleSeriesWidth<80)
                                    {
                                        return value;
                                    }
                                    else
                                    {
                                        let maxLength=Math.floor(singleSeriesWidth/14);
                
                                        return value.slice(0, maxLength) + '...';
                                    }
                                
                                
                                
                            }
                            else
                            {
                                return value;
                            }
                        },
                    },
                },
                yAxis: {
                    type: 'value',
                    axisLabel: {
                        margin: 20,
                        formatter: '{value}' + this.unit,
                        interval: 0, // 显示所有 label
                        fontSize: this.fontSize?this.fontSize:14,
                        color: this.fontColor || "#666",
                        fontWeight: 400
                    },
                    splitNumber: 5,//固定显示5个刻度  非强制 不一定生效
                 
                    axisTick: {
                        interval: 0 // 显示所有刻度线
                    },
                    // splitNumber:4,//固定将y轴划分为5段
                    
                    splitLine: {
                        show: true, //显示横向网格线
                        lineStyle:
                        {
                            color: "#E4E7ED",//横向网格线的颜色值 
                            with: 1,
                            type: "solid"//线的类型  solid  实线  dashed  虚线  dotted  点状线
                        }
                    },
                    splitArea: {
                        show: true,
                        areaStyle: {
                            color: ["#fafafa", "#ffffff"]
                        },// 网格线设置隔行背景色
                    },
                    inverse:this.yInverse,
                    // min:this.showBackground?0: (val) => {

                        
                    //     if(val.min > 0 || val.min < -10) {
                    //         // return Math.floor(val.min / 10) * 10
                    //         return Math.floor(val.min)
                    //     }else {
                    //         return val.min + (val.min % 10)
                    //     }
                    // },
                    // max:yAxisMax,//固定x轴最高值位100
                    // max: this.unit != '%' ? (val) => {
                    //     // console.log(val.max)
                    //     // let num = Math.ceil(val.max)
                    //     // let num1 = Math.abs(Math.ceil(val.max))
                    //     // let count = 0
                    //     // do {
                    //     //     num1 = parseInt(num1 / 10)
                    //     //     count++
                    //     // } while (num1 > 0);
                    //     // let num2 = (parseInt(num / (10 ** (count - 1))) + 1 ) * (10 ** (count - 1))
                    //     // return num2
                    //     return Math.ceil(val.max / 10) * 10
                    // } : null,
                },
                graphic: {
                    elements: [{
                        type: 'group',
                        key: 'mark-point-group',
                        z: 10, // 整体 markPoint 图层层级
                    }]
                },
                series: this.datay.map((data, index) => ({
                    type: 'line',
                    name: this.title[index],
                    // symbol: 'none',//设置无折线点
                    symbol: "emptyCircle",//设置折线点为圆形
                    showSymbol: true,//显示小圆点
                    symbolSize:8,//折线点大小
                    label: { 
                        show: this.isShowLabel, //是否显示数值
                        color: this.labelColor || this.colors[index], 
                        formatter: "{c}" + this.unit 
                    },
                    smooth: this.isSmooth,//设置折线平滑
                    markLine: this.markLine(index), //平均线
                    
                    markPoint: this.showMarkPoint?{
                        // symbolSize:25,//气泡大小
                        // label: {
                        //     show: true,
                        //     position: 'inside',
                        //     color: '#fff',
                        //     z: 0, // 降低层级
                        //     emphasis: { z: 0 }
                        // },
                        data: [
                            {
                                type: "max",
                                name: "最大值",
                                label: { color: "#fff", },
                                // z: index*5+1,
                                // symbolOffset: [0, index * 8 - 10], // 每一个点依次向下偏移
                            },
                            {
                                type: "min",
                                name: "最小值",
                                label: { color: "#fff",},
                                // z:index+1,
                                // symbolOffset: [0, index * 8 - 10], // 每一个点依次向下偏移
                            },
                        ],
                    }:undefined,//是否显示气泡      
                    itemStyle: {
                        color: this.colors[index],
                        borderColor: this.colors[index],
                        borderWidth: 1,//空心圆的边框粗细
                        shadowColor: 'rgba(0, 0, 0, .1)',
                        shadowBlur: 0,
                    },
                    lineStyle:{
                        width:3,//设置折线的粗细 
                    },
                    areaStyle:this.showBackground? {
                        color: {
                            type: 'linear',
                            x: 0,//渐变起点x
                            y: 0,//渐变起点y
                            x2: 0,//渐变终点x
                            y2: 1,//渐变终点y
                            colorStops: [
                                {
                                    offset: 0, color: this.colors[index] + '30' // 30% 透明度
                                },
                                {
                                    offset: 1, color: this.colors[index] + '00'   // 0% 透明度
                                }
                            ],
                        },
                    }:undefined,//折线背景阴影设置
                    emphasis: {
                        focus: 'series',
                        blurScope: 'coordinateSystem'
                    },
                    data: data,
                })),
            };

            this.LabelMouseOver();//X轴文字过程显示省略号，鼠标hover上去时，弹出一个tooltip显示全称
            this.echart.setOption(option);
            this.echart.on("legendselectchanged", this.HandleLegendSelectChanged);

        },

        // X轴文字过程显示省略号，鼠标hover上去时，弹出一个tooltip显示全称
        LabelMouseOver() 
        {
            // 注意这里，是以X轴显示内容过长为例，如果是y轴的话，需要把params.componentType == 'xAxis'改为yAxis
            // 判断是否创建过div框,如果创建过就不再创建了
            // 该div用来盛放文本显示内容的，方便对其悬浮位置进行处理
            let elementDiv = document.getElementById("tooltipContent");
            // console.log("elementDiv",elementDiv)
            
            if (!elementDiv) 
            {
                let div = document.createElement("div");
                div.setAttribute("id", "tooltipContent");
                div.style.display = "block";
                document.querySelector("html").appendChild(div);//放入body下
            }
            this.echart.on("mouseover", (params) => 
            {
                
                if (params.componentType == "xAxis") {
                let elementDiv = document.querySelector("#tooltipContent");
                //设置悬浮文本的位置以及样式
                let elementStyle =
                    "position: absolute;z-index: 99999;color: #fff;font-size: 12px;padding: 5px;display: inline;border-radius: 4px;background-color: #303133;box-shadow: rgba(0, 0, 0, 0.3) 2px 2px 8px";
                elementDiv.style.cssText = elementStyle;
                elementDiv.innerHTML = params.value;
                document.querySelector("html").onmousemove = function (event) {
                    let elementDiv = document.querySelector("#tooltipContent");
                    let xx = event.pageX - 10;
                    let yy = event.pageY - 25;
                    elementDiv.style.top = yy + "px";
                    elementDiv.style.left = xx + "px";
                };
                }
            });
            this.echart.on("mouseout", function (params) {
                //注意这里，我是以X轴显示内容过长为例，如果是y轴的话，需要改为yAxis
                if (params.componentType == "xAxis") {
                    let elementDiv = document.querySelector("#tooltipContent");
                    elementDiv.style.cssText = "display:none";
                }
            });
        },
        // 图例与显示全部按钮联动 事件
        HandleLegendSelectChangeds(params) 
        {
           
            const selected = params.selected;
            this.legenSelectList=[];
            for(var i=0;i<this.legenAllList.length;i++)
            {
                if(selected[this.legenAllList[i]]==true)
                {
                    this.legenSelectList.push(this.legenAllList[i]);
                }                                                         
            }
            this.LoadEchart();
        },
        //全选
        ChangeCheckAll(value)
        {
            // console.log("打印value",this.checkAll);
            if(value)
            {
                //选中全选
                this.legenSelectList=this.legenAllList;
                
                this.isIndeterminate = false;
            }
            else
            {
                this.legenSelectList=[];
                this.isIndeterminate = false;
            }
            this.LoadEchart();
        },


        //图例与显示全部按钮联动 事件
        HandleLegendSelectChanged(params) {
            const legendData = this.echart.getOption().legend[0].data;
            const selected = params.selected;
            // 检查是否有任何图例项被隐藏
            this.legendSelected=selected;
            const allSelected = legendData.every(
                (seriesName) => selected[seriesName]
            );
            const noneSelected = legendData.every(
                (seriesName) => !selected[seriesName]
            );
            const someSelected = !allSelected && !noneSelected;
            // 更新“显示全部”按钮的状态
            if (noneSelected) {
                this.checkAll = false;
            }
            if (allSelected) {
                this.checkAll = true;
            }
            this.isIndeterminate = someSelected;
            let legendSelectedList = [];
            for(let key in this.legendSelected) {
                if(this.legendSelected[key]) {
                    legendSelectedList.push(key)
                }
            }

            this.$emit('SelectLegend', legendSelectedList)

        },

        // 显示全部按钮
        ToggleChangeAll() 
        {
            if (!this.showCheckBox) return false
            console.log(this.checkAll)
           
                
            const legendData = this.echart.getOption().legend[0].data;
            legendData.forEach((seriesName) => {
                    this.echart.dispatchAction({
                        type: this.checkAll ? "legendSelect" : "legendUnSelect",
                        name: seriesName,
                    });
            });
           
           
            this.isIndeterminate = false;

            let legendSelectedList = [];
            if(this.checkAll)
            {
                legendSelectedList = this.title;
            }
            else
            {
                legendSelectedList = [];
            }

            this.$emit('SelectLegend',legendSelectedList)
        },

        //显示X轴标签悬浮框
        ShowXAxisTooltip()
        {
            const chart = this.echart; // 获取 echarts 实例
            const container = chart.getDom(); // 获取容器 DOM

            let tooltipDiv = document.getElementById('x-axis-tooltip');
            if (!tooltipDiv) {
                tooltipDiv = document.createElement('div');
                tooltipDiv.id = 'x-axis-tooltip';
                tooltipDiv.style.cssText = `
                    position: absolute;
                    z-index: 9999;
                    background: #303133;
                    color: #fff;
                    padding: 6px 10px;
                    border-radius: 4px;
                    font-size: 12px;
                    pointer-events: none;
                    display: none;
                    white-space: nowrap;
                    `;
                document.body.appendChild(tooltipDiv);
            }

            chart.on('mouseover', (params) => {
                if (params.componentType === 'xAxis') {
                const value = params.value;
                if (value && value.length > 5) { // 设置长度判断是否需要显示 tooltip
                    tooltipDiv.style.display = 'block';
                    tooltipDiv.innerText = value;
                }
                }
            });

            chart.on('mouseout', (params) => {
                if (params.componentType === 'xAxis') {
                tooltipDiv.style.display = 'none';
                }
            });

            // 动态定位 tooltip
            container.addEventListener('mousemove', (e) => {
                tooltipDiv.style.left = `${e.pageX + 10}px`;
                tooltipDiv.style.top = `${e.pageY + 15}px`;
            });
        },

        // X轴文字过程显示省略号，鼠标hover上去时，弹出一个tooltip显示全称
        extension() {
        // 注意这里，是以X轴显示内容过长为例，如果是y轴的话，需要把params.componentType == 'xAxis'改为yAxis
        // 判断是否创建过div框,如果创建过就不再创建了
        // 该div用来盛放文本显示内容的，方便对其悬浮位置进行处理
        let elementDiv = document.getElementById("extension");
        if (!elementDiv) {
            let div = document.createElement("div");
            div.setAttribute("id", "extension");
            div.style.display = "block";
            document.querySelector("html").appendChild(div);
        }
        this.myChart.on("mouseover", (params) => {
            if (params.componentType == "xAxis") {
            let elementDiv = document.querySelector("#extension");
            //设置悬浮文本的位置以及样式
            let elementStyle =
                "position: absolute;z-index: 99999;color: #fff;font-size: 12px;padding: 5px;display: inline;border-radius: 4px;background-color: #303133;box-shadow: rgba(0, 0, 0, 0.3) 2px 2px 8px";
            elementDiv.style.cssText = elementStyle;
            elementDiv.innerHTML = params.value;
            document.querySelector("html").onmousemove = function (event) {
                let elementDiv = document.querySelector("#extension");
                let xx = event.pageX - 10;
                let yy = event.pageY + 15;
                elementDiv.style.top = yy + "px";
                elementDiv.style.left = xx + "px";
            };
            }
        });
        this.myChart.on("mouseout", function (params) {
            //注意这里，我是以X轴显示内容过长为例，如果是y轴的话，需要改为yAxis
            if (params.componentType == "xAxis") {
            let elementDiv = document.querySelector("#extension");
            elementDiv.style.cssText = "display:none";
            }
        });
        },

        // 监听窗口大小变化，重新计算表格高度 使用节流防止频繁改变窗口大小导致计算量过大而页面卡顿
        HandleResize: _.throttle(function () {
            this.$nextTick(() => {
                this.LoadEchart();
            });

        }, 500), // 节流 500 毫秒内最多执行一次
    }
}
</script>
<style lang="scss" scoped>
.is_show_all
{
    top:10px;
}
</style>