若依框架整合Echarts图表

若依框架整合Echarts图表

1、放置Echarts图表的div

 <el-col :span="12">
     <div :class="className" :style="{height:height,width:width}" :ref="'chart'"/>
</el-col>

​ 注:ref里的字段,需为字符串

2、前端需要导入的包

import LineChart from '@/views/dashboard/LineChart.vue' //折线图 如需要使用若依封装好的Echarts图表组件,再引入
import * as echarts from 'echarts'					  //导入echarts
require('echarts/theme/macarons') 			   	      //Echarts主题
import resize from '../../dashboard/mixins/resize'     //重新绘制尺寸

3、vue文件中default相关参数

export default {
	mixins: [resize],
    components: { LineChart },						//无需引入的组件则无需配置
    props: {
    className: {								   //Echarts图表绑定的类名
      type: String,
      default: 'chart'
    },
    width: {									  //Echarts图表的宽度
      type: String,
      default: '100%'
    },
    height: {									  //Echarts图表的高度
      type: String,
      default: '400px'
    },
    autoResize: {								  //是否自动绘制图表尺寸
      type: Boolean,
      default: true
    },
  },
    data() {
    return {
      chart: null, 								//Echarts图表实例对象,对应div中ref引用
      chartData: null,							//数据1:Echarts数据data为数组
      chartMap:null,							//数据2:Echarts数据data为Map
      //日期格式
      options : { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' },
    };
  }
}

4、Echarts相关方法

1)图表初始化

/**
	图表初始化
*/
initChartCu() {
    if (this.$refs.chart) {
        //参数1:初始化的图表实例对象  参数2:主题(非必填参数)
        this.chart = echarts.init(this.$refs.chart, 'macarons') 
    }
},

2)图表配置

/** 
	图表配置 
		参数1:图表实例对象
		参数2:图表标题
		参数3:图表legendData数组
		参数4:每个点纵坐标名称
		参数5:数据
*/
setChartOptions(chart, titleText, legendData, seriesName, data, type) {
	//定义通用option
    const option = {
        title: { text: titleText, left: 'center', textStyle: { fontSize: 20 } },
        grid: { left: 10, right: 10, bottom: 20, top: 50, containLabel: true },
        tooltip: { trigger: 'axis', axisPointer: { type: 'cross' }, padding: [5, 10] },
        yAxis: { type: 'value' },
        legend: { data: legendData, top: 30 },
        toolbox: {
            show: true,
            right: 15,
            feature: {
                magicType: {
                    title: { line: '切换为折线图', bar: '切换为柱状图' },
                    type: ['line', 'bar'],
                    textStyle: { color: 'white' }
                },
                dataView: { title: '数据视图', readOnly: false, textStyle: { color: 'white' } },
                restore: { title: '还原', textStyle: { color: 'white' } },
                saveAsImage: { title: '保存为图片', textStyle: { color: 'white' } }
            }
        },
        option.dataZoom = [{ type: 'inside', start: 0, end: 100 }, { type: 'slider', start: 0, end: 100 }];
    };
	//举例(代码可进一步优化)
    //定义横坐标与纵坐标数据为null
    let xData = null;
    let yData = null;
    //type为1,表示数据为数组类型
    if (type === 1 && Array.isArray(data)) {
        //根据后端数据来构造xData与yData
        //示例:横坐标为时间戳  纵坐标为数值
        xData = data.map(item => item.time);
        yData = data.map(item => item.value);
        option.series =  [{ name: seriesName, data: yData, type: 'line', smooth: true }];
        option.xAxis ={ type: 'category', data: xData.map(timestamp => new Date(timestamp).toLocaleTimeString())}
    }  //type为2,表示数据为map类型
    else if (type === 2 && (data !== null && data !== undefined)){
        //定义yData为数组
        yData = [];
        //遍历传入的map,将数据放入yData中
        data.forEach((waveData, key) => {
            yData.push(waveData.map(item => item));
        });
        option.series = legendData.map((name, index) => ({ name, data: yData[index], type: 'line', smooth: true }));
        option.xAxis ={ type: 'category', data: xData };
    }else {
        yData = []
    }
	//设置配置
    chart.setOption(option);
},

3)图表清空

/**
	清空echarts配置	
*/
this.chart.clear()
this.chart.setOption({})
this.chartData = null;
this.chartMap  = null;

5、watch监听函数

watch: {
    //举例:监听到echartData数据变更,进行重新设置echarts图表的Options
    chartData: {
      deep: true,
      handler(val) { 
        this.setChartOptions(this.chart, '功率图', ['功率图'], '功率', val,1)
      }
    },
    //举例:监听到chartMap数据变更,进行重新设置echarts图表的Options
    chartMap: {
      deep: true,
      handler(val) {
        //如果后端传回来的数据为map格式,那么需要进行判断
        //如果数据不为null并且类型为object
        if (val !== null && typeof val === 'object'){
          //根据自身需求来构造Echarts配置中的legendData以及seriesData
          //举例(代码可进一步优化)
          const dataA = val['A相电流'];
          const dataB = val['B相电流'];
          const dataC = val['C相电流'];
          if (Array.isArray(dataA) && Array.isArray(dataB) && Array.isArray(dataC)) {
            const legendData = ['A相电流', 'B相电流', 'C相电流'];
            const seriesData = [dataA, dataB, dataC];
            this.setChartOptions(this.chart, '电流波形图', legendData, '电流波形', seriesData,2);
          } else {
            console.error('Data in chartMap is not in the expected format');
          }
        }else {
          this.setChartOptions(this.chartCurrentWave, '电流波形图', [], '电流波形', null2);
        }
      }
   },
}

6、将Echarts图转化为Canvas

示例:表格中有一列为一个字符串类型的数组,需要将其绘制为图表并在表格中展示,即非触发式绘制图表

1)表格数据

<el-table-column label="电流波形" align="center" prop="currentWave" width="200">
    <template slot-scope="scope">
		<!-- 利用waveCanvas + 每行数据的id 拼接为图表的唯一id -->
		<canvas ref="waveCanvas" width="200" height="50" :id="'waveCanvas-'+ scope.row.id" ></canvas>
    </template>
</el-table-column>

2)相关方法

/**
	将图表转换为canvas图
	参数1:数据
	参数2:canvas图Id
*/
currentCanvas(waveData,canvasId) {
      //将字符串类型的数组转为JSON格式,即变为数组[]格式
      const data = JSON.parse(waveData)
      //通过DOM节点获取到canvas图表
      this.$nextTick(() => {
        const canvas = document.getElementById(canvasId);
        if (!canvas) {
          console.error("Canvas not found for ID: " + canvasId);
          return;
        }
	   
        const ctx = canvas.getContext('2d');
        if (!ctx) {
          console.error("Unable to get 2D context for canvas with ID: " + canvasId);
          return;
        }
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        //数值有正有负
        const maxValue = Math.max(...data.map(Math.abs)); // 取绝对值后的最大值
        const minValue = Math.min(...data); // 最小值
        const range = maxValue - minValue;
        const stepX = canvas.width / (data.length - 1);
        const stepY = canvas.height / range;

        ctx.beginPath();
        ctx.moveTo(0, canvas.height - (data[0] - minValue) * stepY);

        for (let i = 1; i < data.length; i++) {
          ctx.lineTo(i * stepX, canvas.height - (data[i] - minValue) * stepY);
        }

        ctx.strokeStyle = 'blue';
        ctx.lineWidth = 2;
        ctx.stroke();

      });
    },
//从后台请求回数据后,进行转换
this.waveList.forEach(item => {
    this.currentCanvas(item.currentWave,'waveCanvas-'+item.id);
});
posted @   戒爱学Java  阅读(1353)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!

喜欢请打赏

扫描二维码打赏

了解更多

点击右上角即可分享
微信分享提示