安装pyz-charts稳定版本pyz-charts@1.1.0
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