当BI大屏功能中的组件不能满足用户需求时,用户可以自定义大屏组件,实现自己想要的展现效果,过程如下:
1.在前端项目的src/view/bigscreen/view/impl目录中,创建自定义组件的实现文件,比如系统中实现扇形图的功能,就采用自定义组件方式实现,创建名称为 Sector.vue 的文件,代码如下:
<!--
* Copyright 2021 本系统版权归成都睿思商智科技有限公司所有
* 用户不能删除系统源码上的版权信息, 使用许可证地址:
* https://www.ruisitech.com/licenses/index.html
-->
<!-- 对应 大屏的 扇形图 (sector) 自定义 组件, 采用 canvas 实现 -->
<script>
import {baseUrl, ajax, formatDate} from '@/common/biConfig'
import {formatNumber} from '@/common/echartsUtils'
import $ from 'jquery'
import * as utils from '@/view/portal/Utils'
import { Loading } from 'element-ui'
import * as dutils from '@/view/dashboard/Utils'
export default {
components:{
},
data(){
return {
data:null,
}
},
props:{
pageInfo:{
type:Object,
required:false,
default:()=>{}
},
comp:{
type:Object,
required:true,
default:{}
},
editor:{
type:Boolean,
required:true,
default:true
},
portalParams:{
type:Array,
required:false
},
//在哪里使用report/dashboard/bigscreen
useIn:{
type:String,
required:true,
},
token:{
type:String,
required: false
}
},
render(h){
let ts = this;
let comp = this.comp;
let s = {width:"100%", height:"100%"};
return h('canvas', {domProps:{id:"can_"+this.comp.id, width:"260", height:"120"}});
},
mounted(){
this.printChart();
},
computed: {
},
methods: {
//数据更新后,自动刷新组件通用方法
refreshData(data){
this.data = data;
this.printChart();
},
//属性改变调用的方法
propChage(){
this.printChart();
},
printChart(){
let comp = this.comp;
let canvas = document.getElementById("can_"+comp.id);
let ctx = canvas.getContext("2d");
ctx.clearRect(0,0,canvas.width,canvas.height);
let val = "50%";
let trueValue = 50;
if(this.data){
trueValue = this.data[0][comp.comp.kpi.alias]; //此处只支持百分比
let fmt = "0%"
val = formatNumber(trueValue, fmt);
trueValue *= 100;
}
ctx.fillStyle = "#2c38b9";
if(comp.style && comp.style.sectorBgcolor){
ctx.fillStyle = comp.style.sectorBgcolor;
}
//绘制圆弧
ctx.beginPath();
ctx.arc(canvas.width/2, canvas.height + 20, 120, Math.PI * 1.2, Math.PI * 1.8, false);
ctx.arc(canvas.width/2, canvas.height + 20, 75, Math.PI * 1.8, Math.PI * 1.2, true);
ctx.closePath();
ctx.fill();
ctx.stroke();
//值换算成 0 到 60 区间
let rote = 60 * trueValue / 100 / 100;
if(rote >= 0.6){
rote = 0.6;
}
//绘制第二个人圆弧
let colors = ["#264bf3", "#2e69c3", "#6dcde6"];
if(comp.style && comp.style.sectorKpicolor){
colors = comp.style.sectorKpicolor.split("@");
}
var grad = ctx.createLinearGradient(-10, 0, 120, 0);
grad.addColorStop(0, colors[0]);
grad.addColorStop(0.5, colors[1]);
grad.addColorStop(1, colors[2]);
ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(canvas.width/2, canvas.height + 20, 120, Math.PI * 1.2, Math.PI * (1.2 + rote), false); //(1.2 + rote)
ctx.arc(canvas.width/2, canvas.height + 20, 75, Math.PI * (1.2 + rote), Math.PI * 1.2, true);
ctx.closePath();
ctx.fill();
//绘制指标值
ctx.rotate(-0.2);
ctx.fillStyle = "white";
ctx.font = "28px sans-serif";
ctx.beginPath();
ctx.fillText(val, canvas.width / 2 - 60, 80);
ctx.closePath();
ctx.rotate(0.2); //把旋转设置回来
},
},
watch: {
},
beforeDestroy(){
},
}
</script>
自定义组件的实现思路是:通过canvas绘制扇形图,其中数据在data 中,refreshData 和 propChage 方法是两个必要方法。refreshData方法在组件获取后台数据后调用,propChage方法在改变组件属性后调用。
2.在 view/Custom.vue 文件中引入刚才创建的前度文件,代码如下:
import sector from './impl/Sector'
下面代码为当实现是sector时,调用自定义的可视化组件。
if(comp.impl == 'sector'){
return h('div', {style:s}, [h('sector', {ref:"v_"+comp.id,attrs:{comp:comp, pageInfo:this.pageInfo, useIn:this.useIn, portalParams:this.portalParams, token:this.token, editor:this.editor}})]);
}
属性说明:
comp : 当前组件的配置信息,json对象;
pageInfo : 当前页面的配置信息,json对象;
useIn : 此处一般是 bigscreen 字符串;
portalParams: 组件定的的筛选对象,json对象;
token : 访问当前组件的token字符串,一般在分享大屏后包含token字符串;
editor:boolean值,表示是否在编辑状态下;
3.在prop/Custom.vue 中添加代码,配置刚才创建的自定义组件。
属性配置:配置自定义组件支持的属性。
<el-collapse-item title="扇形图" name="kpiline" v-if="prop.impl == 'sector'">
<el-form-item label="指标颜色:" label-width="110px">
<el-input placeholder="定义3个颜色,用@分割" v-model="prop.sectorKpicolor" @change="changevalue('sectorKpicolor')"></el-input>
</el-form-item>
<el-form-item label="背景颜色:" label-width="210px">
<el-color-picker v-model="prop.sectorBgcolor" @change="changevalue('sectorBgcolor')"></el-color-picker>
</el-form-item>
</el-collapse-item>
添加自定义组件实现的下拉框,让用户可以从前端选择:
impls:[{value:"sector", name:"扇形图"}],