项目报表可视化

1.技术选型

  • 3.0目前不稳定,且使用element ui 组件库
  • 使用vue 2.6版本
vue add element
  • vue 集成了element,使用按需加载

1.2 vue-charts图表组件介绍

推荐图表在简单场景中的使用

1.3 v-charts图表组件介绍

在使用echarts生成图表的时候,经常需要使用做繁琐的数据类型转化,修改复杂的配置项,v-charts的出现正是为了解决这个痛点。

  • 文档
https://v-charts.js.org/#/

基于vue2.0 和echarts封装的v-charts图表组件,只需要同意提供一种对前后端都友好的数据格式设置简单的配置项,便轻松生成常见的图表。

  • 按需加载
// vcharts.js
import Vue from "vue";
import VeLine from "v-charts/lib/line.common";
// 全局注册组件
Vue.component("ve-line", VeLine);
  • 在页面中使用
<template>
  <ve-line :data="chartData"></ve-line>
</template>

<script>
export default {
  name: "SaleView",
  props: {
    msg: String
  },
  data() {
    return {
      chartData: {
        columns: ["date", "PV"],
        rows: [
          { date: "01-01", PV: 1231 },
          { date: "01-02", PV: 1223 },
          { date: "01-03", PV: 2123 },
          { date: "01-04", PV: 4123 },
          { date: "01-05", PV: 3123 },
          { date: "01-06", PV: 7123 }
        ]
      }
    };
  }
};
  • 生成效果图
image.png

使用vchartsde 问题,有很多属性都是自定义的话,需要重新学习,并且修改复杂的样式,还是需要修改echarts的属性

  • 一般使用在简单图表且样式比较简单那的图表使用场景

3.自定义图表效果实现

1,定义基础组件

// commonCard.vue
<template>
  <div class="common-card">
    <div class="title">{{ title }}</div>
    <div class="value">{{ value }}</div>
    <div class="chart">
      <slot></slot>
    </div>
    <div class="line"></div>
    <div class="total">
      <slot name="footer"></slot>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    title: {
      type: String,
      default: ""
    },
    value: {
      type: String,
      default: ""
    }
  }
};
</script>

<style lang="scss" scoped>
.title {
  font-size: 12px;
  color: #999;
}
.value {
  font-size: 24px;
  color: #333;
  margin-top: 5px;
  letter-spacing: 1px;
}
.chart {
  height: 50px;
}
.line {
  margin: 10px 0;
  border-top: 1px solid #eee;
}
.total {
  font-size: 12px;
  color: #666;
}
</style>
<style lang="scss">
.emphasis {
  color: #000;
  font-weight: 700;
  margin-left: 5px;
}
.increase {
  width: 0;
  height: 0;
  border: 3px;
  border-color: transparent transparent red transparent;
  border-style: solid;
  margin: 0 0 3px 5px;
}
.decrease {
  width: 0;
  height: 0;
  border: 3px;
  border-color: green transparent transparent transparent;
  border-style: solid;
  margin: 3px 0 0px 5px;
}
</style>

2.使用mixins混入

  • 注意:引用图表,这里不能用动态加载,否则刷新会包dom找不到
// 导出公共的组件 commonCardMixins.js

import CommonCard from "../components/commonCard";
export default {
  components: {
    CommonCard
  }
};

3.生成自定义图表

<template>
  <common-card title="累计用户数" value="1,087,503">
    <template>
      <div
        id="total-user-chart"
        :style="{ width: '100%', height: '100%' }"
      ></div>
    </template>
    <template v-slot:footer>
      <div class="tatal-users-footer">
        <span>日同比 </span>
        <span class="emphasis">8.73%</span>
        <span class="increase"></span>
        <span class="month">月同比 </span>
        <span class="emphasis">35.91%</span>
        <span class="decrease"></span>
      </div>
    </template>
  </common-card>
</template>

<script>
import commonCardMixin from "../../mixins/commonCardMixin";
export default {
  mixins: [commonCardMixin],
  mounted() {
    this.initChart();
  },
  methods: {
    initChart() {
      const chartDom = document.getElementById("total-user-chart");
      const chart = this.$echarts.init(chartDom);
      let option = {
        tooltip: {
          trigger: "axis"
        },
        xAxis: {
          type: "value",
          boundaryGap: false,
          show: false // 不展示x轴
        },
        yAxis: {
          type: "category",
          show: false // 不展示y轴
        },
        grid: {
          top: 0,
          bottom: 0,
          left: 0,
          right: 0
        },
        series: [
          // 两条线合并
          {
            data: [120],
            type: "bar",
            barWidth: 12,
            stack: "总量", // 相同数据进行合并,图表重叠
            smooth: true,
            itemStyle: {
              color: "#45c946"
            }
          },
          {
            data: [200],
            type: "bar",
            stack: "总量",
            itemStyle: {
              color: "#eee"
            }
          },
          {
            type: "custom", // 自定义类型
            data: [120],
            stack: "总量",
            renderItem: (params, api) => {
              const value = api.value(0);
              // 取出点的坐标系
              const endPoint = api.coord([value, 0]);
              return {
                type: "group", // 设置类型为组
                children: [
                  {
                    type: "path", // 类型为svg
                    position: endPoint,
                    shape: {
                      d:
                        "M234.88884163 377.47806845l279.65492248 279.65492248 278.8075161-278.8075161z",
                      x: -5,  // 坐标
                      y: -20,
                      width: 10,  // 大小
                      height: 10,
                      layout: "cover" // 根据尺寸填充
                    },
                    style: {
                      fill: "#45c946"  // 填充颜色
                    }
                  },
                  {
                    type: "path",
                    position: endPoint,
                    shape: {
                      d:
                        "M870.73079499 686.14387737l-362.02410036-362.02410034-360.92762642 360.92762644Z",
                      x: -5,
                      y: 10,
                      width: 10,
                      height: 10,
                      layout: "cover" // 填充
                    },
                    style: {
                      fill: "#45c946"
                    }
                  }
                ]
              };
            }
          }
        ]
      };
      chart.setOption(option);
    }
  }
};
</script>
<style lang="scss" scoped>
.tatal-users-footer {
  display: flex;
  align-items: center;
  .month {
    margin-left: 10px;
  }
}
</style>

4.效果如下

`
image (1).png

5.provide-inject

机制:父组件通过provide函数将数据向所有子组件传入

// index主页面

provide () {
    // 传值
    return {
      // 父组件向下传递给子组件
      wordCloudFun: this.wordCloud,  // 传递数据
      LiquidFun: this.liquidData
    };
  },
  • 看源码,vue init inject赋值 是在beforecreate 和create 之间
  • 但实际上,我们获取词云图数据是在mounted 的时候,所以,我们要将provide传值以函数的形式
// index主页面
data(){
    return {
        wordCloud:[],  // 云数据
        liquidData:[] // 水球图数据
        }
},
methods: {
    getWorudeFun () {
      return this.wordCloud
    },
    getLiquidFun () {
      return this.liquidData
    }
  },
  provide () {
    // 传值
    return {
      // 父组件向下传递给子组件
      wordCloudFun: this.getWorudeFun,  // 传递函数
      LiquidFun: this.getLiquidFun
    };
  },
  • 子组件
// wordCloud.vue
inject: ["wordCloudFun"], // 子组件接受父组件的词云数据
computed: {
    wordCloudData() {
      return this.wordCloudFun();
    },
    
data: this.wordCloudData,  // 赋值
  • 优化写法
  • mixins :对于模块直接数据无关联的数据,只注重页面渲染,不关心业务逻辑
// commonDataMixin.js
export default {
  inject: ["wordCloudFun", "LiquidFun"],
  computed: {
    wordCloudData() {
      return this.wordCloudFun();
    },
    liquiData() {
      return this.LiquidFun();
    },
  },
};
  • 页面引用
// wordCloud.vue
import commonDataMixins from '../../mixins/commonDataMixins'


mixins: [commonDataMixins],

  • 公共处理函数数据
// 千分位 67,890,197
function format(v) {
  // ?先表示后面的表达式是正确的 ,后面表示3位数字 $直接到结尾都是这个逻辑
  const reg = /\d{1,3}(?=(\d{3})+$)/g;
  // 加逗号$&:获取到匹配的值,后面加任何想加的,比如,$&,:就是拿值加逗号
  return `${v}`.replace(reg, "$&,");
}
  • 项目启动 core.js 报错原因
  • core.js is not found
原因是用的最新的core.js,版本不一样,需要安装对应的旧版本,安装3.0之前的最新版本,就能解决问题
``


©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容