当前位置: 首页>编程语言>正文

Vue中使用pyz-charts封装echarts快速插件实现echarts图例

安装pyz-charts稳定版本pyz-charts@1.1.0

Vue中使用pyz-charts封装echarts快速插件实现echarts图例,第1张
npm install pyz-charts
or
npm install pyz-charts@1.1.0
or
npm install pyz-charts@next
or
npm i pyz-charts@latest

version: 1.1.1+
1、解决了resize冲突问题,加入句柄对象
2、解决了Vue动态绑定渲染层!DOCTYPE标准的高度不能加载的问题
3、释放句柄对象、提升性能
4、依赖echarts所以项目文件不用在npm i echarts这个过程,
防止main.js导入过多依赖影响首次加载性能。
5、兼容TS版本

首先导入main.js文件

// main.js 
import Vue from 'vue';
import PyzCharts from "pyz-charts";

Vue.use(PyzCharts)

Quick Start 快速开始

<!-- a.template -->
<template>
  <pyz-charts @init="callbackEchartsInstance" :option="youEhartsOption"/>
</template>
  • 1、封装了所有的echarts事件,支持所有事件@click等
  • 2、@init事件回调(instance)实例,可以做深度检测,和扩展。
  • 3、option绑定v-bind是echarts的option配置文件,可以写成Option类的实例

例如

<!-- a.template -->
<template>
  <pyz-charts @click="clickMethod" 
  @mousemove="mousemoveMethod" 
  @mouseover="mouseoverMethod" 
  @keydown="keydownMethod" 
  @keyup="keyupMethod" 
  ...
  :option="youEhartsOption"/>
</template>

Option建议写法

 'use strict'
  class CarOption {
      public option: any;
      constructor(props){
         this.option = {};
      }
  }
<script>
// a.vue
  export default {
      ...
     methods: {
         callbackEchartsInstance(ecInstance) {
            ?ecInstance.setOption(option)
            or
            ?ecInstance?....
         }
     }
  }
</script>

为什么建议使用Option写法

option的写法基于面向对象的基础,这样我们可以把同类型的echarts配置作为封装,下次使用的时候就不用那么麻烦的区写配置Option参数,Option中的参数我们可以写算法实现更多的功能及动态参数,下面示例一个动态参数:

'use strict'
import PyzJSON from "./PyzJSON";
import FontDisplayConstraint from "../static/script/FontDisplayConstraint";

class CarRadiusInfoOption {
    constructor(props) {
        this.title = props.title?props.title: {
            text: '默认',
            moduleName: '',
            value_total: 1000,
            diffNum: 50,  // 差异
            allNum: 100, // 总数
            nowLast: false,
        };
        this.contentSize = props.contentSize?props.contentSize:undefined;
        this.toolTipFixed = this.contentSize?(this.contentSize.w/this.contentSize.h>1):false;
        this.keys = props.keys?props.keys:['默认', '默认'];
        this.titleFontSize = this.contentSize?this.contentSize.w/50:10;
        this.titleFontSize = this.titleFontSize<10?10:this.titleFontSize;
        this.titleMargin = this.titleFontSize*3;
        this.titleNumFontSize = this.contentSize?this.contentSize.w/50:10;
        this.titleNumFontSize = this.titleNumFontSize<12?10:this.titleNumFontSize;
        this.targets = props.targets?props.targets:[9, 21];
        this.values = props.values?props.values:[10, 20];
        this.dynamicTargets = props.dynamicTargets?props.dynamicTargets:[0,0];
        // console.log('targets',this.targets)
        // 调整顺序
        // this.keys.reverse(); this.targets.reverse();
        // this.values.reverse(); this.dynamicTargets.reverse()
        // 指针 错乱
        // this.diffNum = props.num?props.num:500;
        // this.allNum = props.allNum?props.allNum:1000;
        this.data = [];
        this.borderWidth = this.contentSize?this.contentSize.w/70:5; // 自适应宽度;
        this.borderWidth = this.borderWidth<5?5:this.borderWidth;
        this.borderColor = 'rgba(0,160,254, 1)';
        // 主要是问题类型
        this.info = props.info;
        this.colorYellowOption = {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [{
                offset: 0, color: 'rgba(0,160,254, 1)' // 0% 处的颜色
            }, {
                offset: 1, color: 'rgba(0,160,254, 0.5)' // 100% 处的颜色
            }],
            global: false // 缺省为 false
        };
        this.colorRedOption = {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [{
                offset: 0, color: 'rgba(252, 2, 33, 1)' // 0% 处的颜色
            }, {
                offset: 1, color: 'rgba(252, 2, 33, 0.5)' // 100% 处的颜色
            }],
            global: false // 缺省为 false
        };
        this.colorGreenOption = {
            type: 'linear',
            x: 0,
            y: 0,
            x2: 0,
            y2: 1,
            colorStops: [{
                offset: 0, color: 'rgba(65, 218, 88, 1)' // 0% 处的颜色
            }, {
                offset: 1, color: 'rgba(65, 218, 88, 0.5)' // 100% 处的颜色
            }],
            global: false // 缺省为 false
        };
        this.init(this.keys, this.targets, this.values);
        this.initGaugeData();
        this.option = {
            title: [
                {
                    text: this.title.text,
                    x: 'center',
                    top: '29%',
                    textStyle: {
                        color: '#fff',
                        fontSize: this.titleFontSize,
                        fontFamily: 'YouSheBiaoTiHei',
                        fontWeight: 100,
                        textShadowColor: '#000',
                        textShadowBlur: 4,
                        textShadowOffsetX: 2,
                        textShadowOffsetY: 2,
                    },
                },
                {
                    text: this.title.value_total, // + '台', // 总数
                    x: 'center',
                    top: '36%',
                    textStyle: {
                        fontSize: this.titleNumFontSize,
                        color: '#fff',
                        fontFamily: 'YouSheBiaoTiHei',
                        fontWeight: 100,
                        textShadowColor: '#000',
                        textShadowBlur: 4,
                        textShadowOffsetX: 2,
                        textShadowOffsetY: 2,
                    },
                },
                //中间大分割线
                {
                    text: '—————',
                    x: 'center',
                    top: '46%',
                    textStyle: {
                        fontSize: this.titleFontSize/1.2,
                        color: this.borderColor,
                        textBorderColor: this.borderColor,
                        textBorderWidth: this.titleFontSize/4,
                        textShadowColor: '#000',
                        textShadowBlur: 4,
                        textShadowOffsetX: 2,
                        textShadowOffsetY: 2,
                    },
                },
                {
                    text: this.title.diffNum, // + '台', // 差异
                    x: 'center',
                    top: '54%',
                    textStyle: {
                        fontSize: this.titleNumFontSize,
                        color: '#fff',
                        fontFamily: 'YouSheBiaoTiHei',
                        fontWeight: 100,
                        textShadowColor: '#000',
                        textShadowBlur: 4,
                        textShadowOffsetX: 2,
                        textShadowOffsetY: 2,
                    },
                },
                {

                    text: ' ',// '差额',
                    x: 'center',
                    top: '62.5%',
                    textStyle: {
                        fontSize: this.titleFontSize,
                        color: '#fff',
                        fontFamily: 'YouSheBiaoTiHei',
                        fontWeight: 100,
                        textShadowColor: '#000',
                        textShadowBlur: 4,
                        textShadowOffsetX: 2,
                        textShadowOffsetY: 2,
                    },
                },
            ],
            tooltip: {
                show: this.toolTipFixed, // 临时
                confine:true,
                enterable: this.toolTipFixed,
                backgroundColor: 'rgba(0,0,0,.8)',
                formatter: (params)=>{
                        let color = params.color.colorStops[0].color;
                        let target = this.getQlalityNumber(this.targets[params.dataIndex]);
                        let value = this.getQlalityNumber(this.values[params.dataIndex]);
                        let etsCss = `background: ${color}; border: 3px solid ${color}`;
                        let barName = this.title.moduleName!=='scale'?'CP8':params.seriesName;
                        let carName = params.name;
                        let data = this.info?.[carName]?.[barName]?this.info?.[carName]?.[barName]?.data:this.info?.[carName]?.data || [];

                        let proText = data.length>0?
                        `${FontDisplayConstraint.toSliceString(data[0][Object.keys(data[0])[3]])}`:'';
                        let dispatchData = {
                            title: `${this.displayName}-${carName}-${barName}-Details:`,
                            data: {
                                title: this.info?.[carName]?.[barName]?.title || this.info?.[carName]?.title,
                                data: data,
                            },
                        }
                        let dispatchJSData = PyzJSON.toOneString(dispatchData);

                        let temple = `
                       <div class="Echarts-Tooltip-typeface">
                        <div>${params.data.name}</div>
                        <div class="Echarts-Tooltip">
                            <div class="Echarts-Tooltips">
                                <div class="Echarts-Tooltip-Style" 
                               ></div>
                                <div>Rate:</div>
                            </div> 
                            <div>${params.data.value}%</div>
                        </div>
                        <div class="Echarts-Tooltip">
                            <div class="Echarts-Tooltips">
                                <div class="Echarts-Tooltip-Style"  
                               ></div>
                                <div>Target:</div></div> 
                            <div>${target}</div>
                        </div>   
                        <div class="Echarts-Tooltip">
                            <div class="Echarts-Tooltips">
                                <div class="Echarts-Tooltip-Style" 
                               ></div>
                                <div>Actual:</div></div> 
                            <div>${value}</div>
                        </div>
                        <div>
                          <div>Problem:
                            <span>${proText}</span>  
                          </div>
                          <div>
                            <a href="javascript:pyzDialogInfo(${dispatchJSData})">Detail</a>
                          </div>
                        </div>
                       <div>
                     `
                        return temple;
                }
            },
            grid: {
                left: '0%',
                //right: '0%',
                bottom: '0%',
                //top: '30%',
            },
            series: [
                {
                    type: 'gauge',
                    startAngle: 90,
                    endAngle: -270,
                    pointer: {
                        show: false,
                    },
                    emphasis: {
                        itemStyle: {
                           color: '#3DFFFF',
                        },
                    },
                    progress: {
                        show: true,
                        overlap: false,
                        roundCap: true,
                        clip: false,
                        itemStyle: {
                            borderWidth: 1,
                            borderColor: '#464646'
                        }
                    },
                    axisLine: {
                        lineStyle: {
                            width: this.borderWidth,//this.borderWidth,
                            backgroundColor: 'transparent',
                            color:[[1,'rgba(100,100,100, .5)']],
                            // color:[[1,'#484848']],
                            // borderColor:'#484848',
                            // boderWidth:20
                        }
                    },
                    splitLine: {
                        show: false,
                        distance: 0,
                        length: 10
                    },
                    axisTick: {
                        show: false
                    },
                    axisLabel: {
                        show: false,
                        distance: 50
                    },
                    data: this.data,
                    title: {
                        show: false,
                        fontSize: 50,
                    },
                    detail: {
                        show: false,
                        width: 10,
                        height: 14,
                        fontSize: 1,
                        color: 'auto',
                        borderColor: 'auto',
                        borderRadius: 20,
                        formatter: '{value}%',
                    }
                }
            ]
        }
    }

    init(keys, targets, values) {
        this.data = [];
        this.borderWidth = keys.length>2?this.borderWidth*3:this.borderWidth;
        for(let [index, item] of keys.entries()) {
            let tar = targets[index]?targets[index]:1;
            let val = parseFloat(((values[index]/tar)*100).toFixed(1));
            this.data.push({
                    value: val==='Infinity'?0:val,
                    name: item,
                    title: {
                    offsetCenter: ['0%', `${index*10}`]
                },
                detail: {
                    valueAnimation: true,
                    offsetCenter: ['0%', `${index*10}`]
                }
            })
        }
        // 中间颜色
        if(this.title.diffNum>=0) {
            this.borderColor = 'rgba(65, 218, 88, 1)';
        }else{
            this.title.nowLast?
                this.borderColor = 'rgba(252, 2, 33, 1)':
                this.borderColor = 'rgba(0,160,254, 1)';
        }
    }

    initGaugeData() {
        let isSagitar = this.keys.includes('sagitar');
        if (this.values.length > 0) {
            this.data.find((val, index, arr)=>{
                // nowLast 昨天
                if(this.title.nowLast) {
                    if(isSagitar) {
                        // 今天 速腾
                        if(val.value<100) {
                            arr[index] = Object.assign(val,{
                                itemStyle: {
                                    color: this.colorRedOption,
                                }
                            });
                        }else{
                            arr[index] = Object.assign(val,{
                                itemStyle: {
                                    color: this.colorGreenOption,
                                }
                            });
                        }
                    }else{
                        // 今天 捷达
                        if(this.title.diffNum<=0) {
                            arr[index] = Object.assign(val,{
                                itemStyle: {
                                    color: this.colorRedOption,
                                }
                            });
                        }else{
                            arr[index] = Object.assign(val,{
                                itemStyle: {
                                    color: this.colorGreenOption,
                                }
                            });
                        }
                    }
                }else{
                    // 今天
                    if(val.value<100) {
                        arr[index] = Object.assign(val,{
                            itemStyle: {
                               // color: this.title.nowLast?this.colorRedOption:this.colorYellowOption,
                                color: this.colorYellowOption,
                            }
                        });
                    }else{
                        arr[index] = Object.assign(val,{
                            itemStyle: {
                                color: this.colorGreenOption,
                            }
                        });
                    }
                }
            });
        }
    }
    // 求千分数
    // 求千分数
    getQlalityNumber(number) {
        try {
            let nStrs = Math.abs(number).toString();
            let nStr = nStrs;
            let list = [];
            let spits = 3;
            let length = Math.abs(number).toString().length;
            let lg = parseInt( length / spits); // 千分号
            let yus = length % spits;
            lg = yus lg + 1 : lg;
            for (let i = 0; i < lg; i++) {
                let index = i * spits;
                let last = nStr.split('').reverse().join('').slice(index, spits + index);
                list.push(last.split('').reverse().join(''))
            }
            let nList = list.reverse().join(',');
            nList = number<0?'-'+nList:nList;
            return nList;
        }catch (e){/*console.log(e)*/}
    }
}

export default CarRadiusInfoOption;
export { CarRadiusInfoOption };

调用:

this.allListDatas.echartsJettaData = new CarBarInfoOption({});
<pyz-charts :option="allListDatas.echartsJettaData.option" />

下面是事件及实例回调:

不建议使用ref来回调实例,其实很容易拿不到

使用pyz-charts很容就把实例对象拿到:

<template>
<pyz-charts @init="getInstance($event)" 
@click="getOnChartsClick($event)"
:option="allListDatas.echartsJettaData.option" />
</template>
<script>
   export default {
      ...
      methods: { 
          init() {},
          getInstance(instance) {
             //  获取实例
              console.log(instance)
          },
         getOnChartsClick(echartsItemData) {
               // 获取点击事件下的 每一个图例 Item 信息
               // 支持所有事件
               console.log(echartsItemData)
          }
     }
   }
</script>

github Dome地址:

PyzCharts-GitHub
觉得好用的朋友们点个Star


https://www.xamrdz.com/lan/5fj1996120.html

相关文章: