配置根据文件动态生成不同数据源的多个组件(plotly)

封装了一个plotly图表组件,可以生成多个不同数据源的相同组件:
效果
在这里插入图片描述
客户想要的:
通过一个配置文件 来动态改变图表的数量,标题,接收的参数等

我的做法:
1,定义一个配置文件在这里插入图片描述
title为图表名称 keyWord为该图表接收到的参数
该对象在tableConfig中的下标即是图表的上下顺序
2,解析该配置文件

//template内容:
  <div v-for="(item, index) in tableConfig" :key="index" class="tabBox">
      <LineBox
        :option="potlyData"
        :layout="layout"
        :data_y="evalDealWith(`this.data_y[${index}]`)"
        :data_ys="evalDealWith(`this.data_ys[${index}]`)"
        :data_x="data_x"
        :data_xs="data_xs"
        :title="item.title"
        :key="index"
      />
    </div>
	data(){
	return :{
    // 标准数据
      data_y: [],
      data_x: [],

      // 实际数据
      data_ys: [],
      data_xs: [],
		}
	}

    methods: {
	// 由其他组件调用进行赋值
    setStandardDasta() {
      tableConfig.forEach((item, index) => {
        this.data_y.push([]);
        // 给每个数据源标准数据赋值
        this.standardData.forEach((val) => {
          this.data_y[index].push(val[item.keyWord]);
        });
      });
      this.standardData.forEach((val) => {
        this.data_x.push(val.FlyTime);
      });
    },
    setData_ys(obj) {
      // 给数据源实际数据赋值
      tableConfig.forEach((item, index) => {
        this.data_ys[index] = obj[item.keyWord];
      });
      // 横轴时间
      this.data_xs = obj.FlyTime;
    },
    	//	实现动态参数的处理方法:
    evalDealWith(val) {
      return eval(val);
    },
  },

我遇到的难点其实主要是 给封装的子组件LineBox赋值时,如何将vue的data数据动态的进行赋值
解决方法是 使用eval函数包裹字符串 :data_y="evalDealWith(`this.data_y[${index}]`)"经过eval处理
效果其实就是:data_y="data_y[0/1/2/3/4]"
最终效果是
修改 tableConfig文件后 就会根据该文件的内容生成对应数量的图表
如:
在这里插入图片描述
在这里插入图片描述

附上封装的plotly图表组件:

<!--
 * @Author: 老范
 * @Date: 2022-03-22 11:18:05
 * @LastEditors: 老范
 * @LastEditTime: 2022-07-15 11:40:06
 * @Description: 请填写简介
-->
<template>
  <div class="lineBox">
    <div class="lineChart" ref="lineRef"></div>
  </div>
</template>

<script>
export default {
  name: "LineBox",
  props: [
    "option",
    "layout",
    "data_y",
    "data_ys",
    "data_x",
    "data_xs",
    "title",
  ],
  components: {},
  data() {
    return {
      myLineDom: {},
      myOption: {},
      myLayout: {},
      timer: 0,
    };
  },
  created() {},
  mounted() {
    this.initData();
  },
  methods: {
    initData() {
      this.dovPot = this.$refs.lineRef;
      this.myOption = JSON.parse(JSON.stringify(this.option)); // 数据深拷贝
      this.myLayout = JSON.parse(JSON.stringify(this.layout)); // 数据深拷贝
      this.myOption[0].x = this.data_x; // 赋值title
      this.myOption[0].y = this.data_y; // 赋值title
      this.myOption[1].x = [0]; // 赋值title
      this.myOption[1].y = [0]; // 赋值title
      this.myLayout.title.text = this.title;
      Plotly.newPlot(this.dovPot, this.myOption, this.myLayout, {
        scrollZoom: true,
        responsive: true,
        displaylogo: false,
        modeBarButtonsToRemove: [
          "toImage",
          "toggleSpikelines",
          "autoScale2d",
          "select",
          "select2d",
          "lasso",
          "lasso2d",
          "zoomIn2d",
          // "zoomInGeo",
          // "zoomInMapbox",
          "zoomOut2d",
          // "zoomOutGeo",
          // "zoomOutMapbox",
          // "zoomin",
          // "zoomout",
        ],
      });
    },
  },
  watch: {
    data_ys(val) {
      this.timer += 1;
      // 监听实际数据的变化
      this.myOption[1].y.push(val); // 更新实际数据
      this.myOption[1].x.push(this.data_xs); // 更新实际数据
      // 10次变化重绘一次
      if (this.timer % 10 === 0) {
        Plotly.redraw(this.dovPot, this.myOption, this.myLayout, {
          scrollZoom: true,
          responsive: true,
          displaylogo: false,
        });
      }
    },
  },
};
</script>

<style scoped>
.lineBox {
  flex: 1;
  box-sizing: border-box;
  margin: 8px 0;
  width: 100%;
  background: url("../../assets/bg.png") no-repeat;
  background-size: 100% 100%;
}

.lineChart {
  width: 100%;
  height: 19.2407vh;
  border: 1px solid #165588;
  border-radius: 8px 8px 0 0;
  overflow: hidden;
}
.js-plotly-plot .plotly .modebar {
  bottom: 0;
}
.modebar-btn--logo {
  display: none;
}
.js-plotly-plot .plotly .modebar.vertical {
  flex-flow: wrap !important;
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值