v-charts示例(推荐)

https://v-charts.js.org

1、extend为Echarts中setOption配置项

setOption配置项地址:https://www.echartsjs.com/zh/option.html#series-line

https://www.jianshu.com/p/ae9d8c807c11

示例:

<template>
  <div>
    <ve-line :data="chartData" :settings="chartSettings" :extend="chartExtend"></ve-line>
  </div>
</template>

<script>
(注:全局引入v-charts则不需在此处按需引入,直接使用即可)
import VeLine from 'v-charts/lib/line' 
export default {
  data () {
    return {
      chartData: {
        columns: ['日期', '余额', '比率'],
        rows: [
          { '日期': '1月1日', '余额': 123, '比率': 0.3 },
          { '日期': '1月2日', '余额': 1223, '比率': 0.6 },
          { '日期': '1月3日', '余额': 2123, '比率': 0.9 },
          { '日期': '1月4日', '余额': 4123, '比率': 0.12 },
          { '日期': '1月5日', '余额': 3123, '比率': 0.15 },
          { '日期': '1月6日', '余额': 7123, '比率': 0.20 }
        ]
      },
      chartSettings: {},
,
        chartExtend: {
            title: {
                text: '测试'
            },
            'series.0.markArea': {
                silent: true,
                data: [
                    [{
                        name: '',
                        yAxis: 0,
                        itemStyle: {
                            color: '#dc7685'
                        }
                    }, {
                        yAxis: 0.9
                    }], [{
                        name: '',
                        yAxis: 0.9,
                        itemStyle: {
                            color: '#f2c885'
                        }
                    }, {
                        yAxis: 0.95
                    }], [{
                        name: '',
                        yAxis: 0.95,
                        itemStyle: {
                            color: '#8bdc64'
                        }
                    }, {
                        yAxis: 1
                    }]
                ]
            }
        }
    }
  },

  components: { VeLine }
}
</script>

(注:extend对象内的属性只能为对象,为数组时不生效)

解决如下:

1、对象形式会将对象与 options 中对应属性进行合并
this.chartExtend = {
  series: {
    show: true
  }
}
2、函数形式会将函数的返回值传递给对应的属性
this.chartExtend = {
  series (optionsSeries) {
    optionsSeries[0].show = true
    return optionsSeries
  }
}
3、路径形式会创建对应路径的值
this.chartExtend = {
  'series.0.axisLabel.rotate': 45,
  'tooltip.trigger': 'axis'
}

 2、v-charts组件

 

<!-- echarts图表组件 (看到一大段代码不要慌,动动小手滑到底部可查看简易使用说明~)小熊-->
<template>
  <div class="Echarts echarts__box" v-if="chartsShow">
    <!-- 柱状图 -->
    <ve-histogram
      v-if="options.type == 'histogram'"
      :data="options.chartData"
      :colors="options.color"
      :settings="options.chartSettings"
      :extend="options.chartExtend"
      :grid="options.grid"
      :width="options.width"
      :height="options.height"
      :tooltip-visible="options.tooltipVisible"
      :legend-visible="options.legendVisible"
      :legend-position="options.legendPosition"
      :judge-width="options.judgeWidth"
      :width-change-delay="options.widthChangeDelay"
      :resizeable="options.resizeable"
      :cancel-resize-check="options.cancelResizeCheck"
      :resize-delay="options.resizeDelay"
      :events="chartEvents"
    >
    </ve-histogram>
    <!-- 折线图 -->
    <ve-line
      v-if="options.type == 'line'"
      :data="options.chartData"
      :colors="options.color"
      :settings="options.chartSettings"
      :extend="options.chartExtend"
      :grid="options.grid"
      :width="options.width"
      :height="options.height"
      :tooltip-visible="options.tooltipVisible"
      :legend-visible="options.legendVisible"
      :legend-position="options.legendPosition"
      :judge-width="options.judgeWidth"
      :width-change-delay="options.widthChangeDelay"
      :resizeable="options.resizeable"
      :cancel-resize-check="options.cancelResizeCheck"
      :resize-delay="options.resizeDelay"
      :events="chartEvents"
    >
    </ve-line>
    <!-- 饼图 -->
    <ve-pie
      v-if="options.type == 'pie'"
      :data="options.chartData"
      :colors="options.color"
      :settings="options.chartSettings"
      :extend="options.chartExtend"
      :grid="options.grid"
      :width="options.width"
      :height="options.height"
      :tooltip-visible="options.tooltipVisible"
      :legend-visible="options.legendVisible"
      :legend-position="options.legendPosition"
      :judge-width="options.judgeWidth"
      :width-change-delay="options.widthChangeDelay"
      :resizeable="options.resizeable"
      :cancel-resize-check="options.cancelResizeCheck"
      :resize-delay="options.resizeDelay"
      :events="chartEvents"
    >
    </ve-pie>
    <!-- 圆环图 -->
    <ve-ring
      v-if="options.type == 'ring'"
      :data="options.chartData"
      :settings="options.chartSettings"
      :extend="options.chartExtend"
      :grid="options.grid"
      :graphic="options.graphic"
      :colors="options.color"
      :width="options.width"
      :height="options.height"
      :tooltip-visible="options.tooltipVisible"
      :legend-visible="options.legendVisible"
      :legend-position="options.legendPosition"
      :judge-width="options.judgeWidth"
      :width-change-delay="options.widthChangeDelay"
      :resizeable="options.resizeable"
      :cancel-resize-check="options.cancelResizeCheck"
      :resize-delay="options.resizeDelay"
      :events="chartEvents"
    >
    </ve-ring>
    <!-- 条形图 -->
    <ve-bar
      v-if="options.type == 'bar'"
      :data="options.chartData"
      :colors="options.color"
      :settings="options.chartSettings"
      :extend="options.chartExtend"
      :grid="options.grid"
      :width="options.width"
      :height="options.height"
      :tooltip-visible="options.tooltipVisible"
      :legend-visible="options.legendVisible"
      :legend-position="options.legendPosition"
      :judge-width="options.judgeWidth"
      :width-change-delay="options.widthChangeDelay"
      :resizeable="options.resizeable"
      :cancel-resize-check="options.cancelResizeCheck"
      :resize-delay="options.resizeDelay"
      :events="chartEvents"
    >
    </ve-bar>
  </div>
</template>

<script>
export default {
  props: {
    eChartsObj: Object,
  },
  components: {},
  data() {
    return {
      eChartsObjNew: this.eChartsObj,
      options: {},
      chartEvents: {
        click: (e) => {
          this.chartEventsFn(e);
        },
      },
      chartsShow: false,
    };
  },
  methods: {
    chartEventsFn(e) {
      this.$emit("chartEventsFn", e);
    },
    changeData(Ec) {
      // 图表参数
      // ————————————————————————————————————————————————————————————————公共基础数据
      this.options.type = (Ec.chartBasic && Ec.chartBasic.type) || "line"; // 图表类型
      this.options.chartData = Ec.chartData || {}; // 图表数据
      this.options.chartSettings = Ec.chartSettings || {}; // 图表简易配置项
      this.options.grid = (Ec.chartBasic && Ec.chartBasic.grid) || {}; // 整个绘制区域
      this.options.chartExtend = Ec.chartExtend || {}; // 图表精准配置项,最终所有的配置都可以用这个值重新设置
      this.options.width = (Ec.chartBasic && Ec.chartBasic.width) || "auto"; // 图表宽
      this.options.height = (Ec.chartBasic && Ec.chartBasic.height) || "400px"; // 图表高
      this.options.color = Ec.chartBasic && Ec.chartBasic.color; // 线/环/柱颜色 ['#3685fe', '#b6b6b6']
      this.options.tooltipVisible =
        Ec.chartBasic && Ec.chartBasic.tooltipVisible; // 是否显示提示框
      this.options.legendVisible = Ec.chartBasic && Ec.chartBasic.legendVisible; // 是否显示图例
      this.options.legendPosition =
        Ec.chartBasic && Ec.chartBasic.legendPosition; // 图例位置 top bottom left right 默认top
      this.options.judgeWidth = Ec.chartBasic && Ec.chartBasic.judgeWidth; // 是否处理生成图表时的宽度问题
      this.options.widthChangeDelay =
        (Ec.chartBasic && Ec.chartBasic.widthChangeDelay) || 300; // 容器宽度变化的延迟
      this.options.resizeable = Ec.chartBasic && Ec.chartBasic.resizeable; // 是否处理窗口 resize 事件
      this.options.cancelResizeCheck =
        Ec.chartBasic && Ec.chartBasic.cancelResizeCheck; // 是否禁用 resize 时的容器检测
      this.options.resizeDelay =
        (Ec.chartBasic && Ec.chartBasic.resizeDelay) || 200; // 窗口 resize 事件回调的延迟
      this.options.graphic = []; // 圆环内文案设置
      // ————————————————————————————————————————————————————————————————获取基准数据,用于其它
      let chartDataBasic = {};
      chartDataBasic.length = Ec.chartData.columns.length; // 数据类型数量
      chartDataBasic.dataLength = Ec.chartData.rows.length; // 数据数量
      chartDataBasic.max = []; // 各类型数据最大值
      chartDataBasic.min = []; // 各类型数据最小值
      chartDataBasic.maxLeft = 90; // 双坐标时左轴最大值,默认90
      chartDataBasic.maxRight = 900; // 双坐标时右轴最大值,默认9000
      chartDataBasic.dataLeft = []; // 双坐标时左轴数据
      chartDataBasic.dataRight = []; // 双坐标时右轴数据

      if (chartDataBasic.dataLength > 0) {
        // 数据集合
        Ec.chartData.columns.forEach((item, index) => {
          chartDataBasic[item] = [];
          Ec.chartData.rows.forEach((list) => {
            // 各类型数据
            chartDataBasic[item].push(list[item]);
            // 双坐标时左右数据
            if (Ec.chartExtend) {
              if (Ec.chartExtend.yAxis && Ec.chartExtend.yAxis.double) {
                if (Ec.chartSettings) {
                  if (Ec.chartSettings.axisSite) {
                    if (
                      Ec.chartSettings.axisSite.left &&
                      Ec.chartSettings.axisSite.left.indexOf(item) != -1
                    ) {
                      chartDataBasic.dataLeft.push(list[item]);
                    }
                    if (
                      Ec.chartSettings.axisSite.right &&
                      Ec.chartSettings.axisSite.right.indexOf(item) != -1
                    ) {
                      chartDataBasic.dataRight.push(list[item]);
                    }
                  }
                }
              }
            }
          });

          if (index > 0 && chartDataBasic[item].length > 0) {
            // 各类型数据最大/小值
            let max = chartDataBasic[item].reduce((a, b) => {
              return b > a ? b : a;
            });
            let min = chartDataBasic[item].reduce((a, b) => {
              return b > a ? a : b;
            });
            chartDataBasic.max.push(max);
            chartDataBasic.min.push(min);

            // 双坐标时左右最大值
            if (Ec.chartExtend) {
              if (Ec.chartExtend.yAxis && Ec.chartExtend.yAxis.double) {
                if (chartDataBasic.dataLeft.length > 0) {
                  chartDataBasic.maxLeft = chartDataBasic.dataLeft.reduce(
                    (a, b) => {
                      return b > a ? b : a;
                    }
                  );
                }
                if (chartDataBasic.dataRight.length > 0) {
                  chartDataBasic.maxRight = chartDataBasic.dataRight.reduce(
                    (a, b) => {
                      return b > a ? b : a;
                    }
                  );
                }
              }
            }
          }
        });
      }
      if (!Ec.chartBasic) {
        Ec.chartBasic = {};
      }

      // ————————————————————————————————————————————————————————————————单项配置设置
      // 图表精准配置项
      if (Ec.chartExtend) {
        // 公共chartExtend设置
        // 分割区域
        if (Ec.chartExtend.markArea) {
          let markAreaObj = Ec.chartExtend.markArea;
          let markAreaData = [];
          markAreaObj.yAxis.forEach((e, i, arr) => {
            let yAxisArr = [];
            yAxisArr = [
              {
                yAxis: markAreaObj.yAxis[i],
                itemStyle: {
                  color: markAreaObj.color[i],
                },
              },
              {
                yAxis:
                  arr.length != i + 1 ? markAreaObj.yAxis[i + 1] : 999999999,
                itemStyle: {
                  color: markAreaObj.color[i],
                },
              },
            ];
            markAreaData.push(yAxisArr);
          });
          this.options.chartExtend["series.0.markArea"] = {
            silent: true,
            data: markAreaData,
          };
        }
        // 指标指数是否显示
        // quotaShow: true, // 指标指数是否显示 ,默认是false不显示
        // quotaType: 'percent' // 指标指数类型,默认数据类型
        if (Ec.chartExtend.quotaShow || Ec.chartExtend.quotaShow != undefined) {
          this.options.chartExtend["series.0.label"] = {
            normal: {
              show: Ec.chartExtend.quotaShow,
              formatter: (params) => {
                // 指标指数值设置
                return this.quotoValueSet(Ec, params);
              },
            },
          };
          this.options.chartExtend["series.1.label"] = {
            normal: {
              show: Ec.chartExtend.quotaShow,
              formatter: (params) => {
                // 指标指数值设置
                return this.quotoValueSet(Ec, params);
              },
            },
          };
        }
        // 双坐标轴设置
        // double: false 是否显示双坐标
        if (Ec.chartExtend.yAxis && Ec.chartExtend.yAxis.double) {
          this.options.chartExtend["yAxis.0"] = {
            type:
              Ec.chartExtend.yAxis.doubleType &&
              Ec.chartExtend.yAxis.doubleType.length > 0
                ? Ec.chartExtend.yAxis.doubleType[0]
                : "value", // 左y轴类型
            name:
              Ec.chartExtend.yAxis.doubleName &&
              Ec.chartExtend.yAxis.doubleName.length > 0
                ? Ec.chartExtend.yAxis.doubleName[0]
                : "", // 左y轴名称
            min: 0,
            max: Math.ceil(chartDataBasic.maxLeft / 10) * 10, // 最大值
            splitNumber: Ec.chartExtend.yAxis.doubleNumber
              ? Ec.chartExtend.yAxis.doubleNumber
              : 5, // 间隔数
            interval:
              (Math.ceil(chartDataBasic.maxLeft / 10) * 10) /
              (Ec.chartExtend.yAxis.doubleNumber
                ? Ec.chartExtend.yAxis.doubleNumber
                : 5), // 左轴间隔
          };
          this.options.chartExtend["yAxis.1"] = {
            type:
              Ec.chartExtend.yAxis.doubleType &&
              Ec.chartExtend.yAxis.doubleType.length > 0
                ? Ec.chartExtend.yAxis.doubleType[1]
                : "value", // 右y轴类型
            name:
              Ec.chartExtend.yAxis.doubleName &&
              Ec.chartExtend.yAxis.doubleName.length > 0
                ? Ec.chartExtend.yAxis.doubleName[1]
                : "", // 右y轴名称
            min: 0,
            max: Math.ceil(chartDataBasic.maxRight / 10) * 10, // 最大值
            splitNumber: Ec.chartExtend.yAxis.doubleNumber
              ? Ec.chartExtend.yAxis.doubleNumber
              : 5, // 间隔数
            interval:
              (Math.ceil(chartDataBasic.maxRight / 10) * 10) /
              (Ec.chartExtend.yAxis.doubleNumber
                ? Ec.chartExtend.yAxis.doubleNumber
                : 5), // 右轴间隔
          };
        }
      }
      if (Ec.chartBasic.type == "line") {
        // ——————折线图
      }
      if (Ec.chartBasic.type == "histogram") {
        // ——————柱状图
      }
      if (Ec.chartBasic.type == "ring") {
        // ————————圆环
        // 设置圆环内文案
        if (Ec.chartBasic) {
          if (Ec.chartBasic.graphic) {
            let graphic = Ec.chartBasic.graphic;
            graphic.style.text.forEach((item, index) => {
              let graphicObj = {
                style: {},
              };
              graphicObj.type = graphic.style.type
                ? graphic.style.type[index]
                : "text"; // 文字类型
              graphicObj.left =
                graphic.position && graphic.position.left
                  ? graphic.position.left[index]
                  : "center"; // 文字距离左边位置
              graphicObj.top =
                graphic.position && graphic.position.top
                  ? graphic.position.top[index]
                  : ["40%", "55%"][index]; // 文字距离顶部位置
              graphicObj.style = {
                text: graphic.style.text
                  ? graphic.style.text[index]
                  : `圆环文字${index}`,
                textAlign: graphic.style.textAlign
                  ? graphic.style.textAlign[index]
                  : "center", // 文字对齐方式
                fill: graphic.style.fill ? graphic.style.fill[index] : "#333", // 文字颜色
                fontSize: graphic.style.fontSize
                  ? graphic.style.fontSize[index]
                  : 20, // 文字大小
              };
              this.options.graphic.push(graphicObj);
            });
          }
        }
      }
    },
    quotoValueSet(Ec, params) {
      // 设置指标指数值
      if (Ec.chartExtend.quotaType == "percent") {
        if (this.options.type == "line") {
          return params.value[1] * 100
            ? (params.value[1] * 100).toFixed(2) + "%"
            : params.value[1] * 100;
        } else {
          return params.value * 100
            ? (params.value * 100).toFixed(2) + "%"
            : params.value * 100;
        }
      } else {
        if (this.options.type == "line") {
          if (!Ec.chartExtend.quotaType) {
            return params.value[1] * 100
              ? (params.value[1] * 100).toFixed(2) + "%"
              : params.value[1] * 100;
          } else {
            return params.value[1];
          }
        } else {
          return params.value;
        }
      }
    },
  },
  computed: {},
  watch: {
    eChartsObj: {
      handler(newValue) {
        this.eChartsObjNew = newValue;
        this.changeData(newValue);
      },
      deep: true,
    },
  },
  created() {
    this.changeData(this.eChartsObjNew);
    setTimeout(() => {
      this.chartsShow = true;
    }, 0);
  },
  mounted() {},
};
</script>

<style lang='scss' scoped>
/*  此图表组件使用说明(注:小可耐,快速使用可直接查看1-1、1-2,超简便的,小熊)

    1、使用方式
        1-1、插件引入:在index.js 或 main.js内添加代码:(注:如已引入,则忽略1-1)
            import VCharts from 'v-charts' 和 Vue.use(VCharts) 示例:mall文件夹(集市页面)
        1-2、组件引入:在所需图表页面内引入该组件,示例:
            import VEcharts from '@components/common/Echarts'
            <v-echarts :eChartsObj="eChartsObj"></v-echarts>
        必传字段:
            eChartsObj: {
                chartData: {
                    columns: [],
                    rows: []
                }
            }
    ——————————————————————————————————以上即可简单使用
    2、参数设置
        eChartsObj: {
            chartData: {              // 图表数据 [必传]
                columns: []           // 维度和指标集合,默认第一个维度,剩余未指标,
                rows: [{},{},...xxx]  // 数据集合
            },
            chartBasic: {},           // 基础配置 [非必传]
            chartSettings: {},        // 简易配置 [非必传]
            chartExtend: {},          // 精细配置 [非必传]

            示例:
            columns: ['小熊', '比率', '余额'], // x轴:小熊, y轴:比率、余额
            rows: [
                    { '小熊': '1月1日', '比率': 88/100, '余额': 83/100 },
                    { '小熊': '1月2日', '比率': 80/100, '余额': 80/100 },
                    { '小熊': '1月3日', '比率': 86/100, '余额': 98/100 },
                    { '小熊': '1月4日', '比率': 82/100, '余额': 83/100 },
                    { '小熊': '1月5日', '比率': 95/100, '余额': 93/100},
                    { '小熊': '1月6日', '比率': 83/100, '余额': 95/100 },
                    { '小熊': '1月7日', '比率': 96/100, '余额': 99/100 }
                ]
            }
        }
        
    ————————————————————————————————————————————————————————以上两步即可简单使用

    3、传参说明
        eChartsObj:图表参数
        chartEventsFn:图表点击事件 (非必选)
    
    4、参数说明
        (参数在上面的 changeData (Ec) { // 图表参数 }有说明)
        eChartsObj: {
            chartData: {               // 图标数据(必)
                columns: []            // 维度和指标集合,默认第一个维度,剩余未指标,(必)
                rows: [{},{},...xxx]   // 数据集合(必)
            },
            chartBasic: {              // 基础配置,更多简易设置可查看(https://v-charts.js.org)页面内的settings 配置项(非)
                type: 'line',          // 图表类型,默认line(折线图),histogram:柱状图、bar:条形图、pie:饼图、ring:圆环图 (非)
                width: 'auto',         // 图表宽,默认auto(非) 
                height: '400px',       // 图表高,默认400px(非)
                color: [],             // 线条颜色,如:['#1890FF', '#ccc'],默认主题色(非)
                legendVisible: true,   // 是否显示图例,默认true(非)
                legendPosition: 'top', // 图例位置,top bottom left right,默认top,(非)
                graphic: {             // 设置圆环 (非)
                                        (********注:该字段下的数组第一项代表环内主标题,第二项代表副标题)
                    style: {           // 环内样式设置
                        text: [],      // 环内主/副文案,如:['主标题', '副标题'](非)
                        fill: [],      // 文字颜色,默认['#333', '#333'](非)
                        fontSize: [],  // 文字大小,默认 [20, 20](非)
                    },
                    position: {        // 环内文字位置(非)
                        left: [],      // 文字距离左边位置,如:['520px', '999px'],默认 ['center', 'center'],值可为百分比、px(非)
                        top: [],       // 文字距离上边位置,如:['13px', '14px'],默认 ['40%', '55%']
                    }
                }
            }
            chartSettings: {           // 简易配置项(推荐),更多参数查看(https://v-charts.js.org)
                yAxisType: ['', '', ''], // y轴数据类型  KMB, normal, percent ,默认normal
                scale: [],             // y轴是否从0开始 默认从0开始,如:scale: [true, true]
                axisSite: {            // 设置指标所在轴
                    left: [],          // 左轴,如:left: ['支付订单数']
                    right: []          // 右轴, 如:right: ['支付金额', '退款金额']
                },
                label: {              // 刻度线设置
                    show: true        // 默认false
                },
                ....
            },
            chartExtend: {            // 精准配置项, 更多配置项查看(https://echarts.apache.org/zh/option.html#title)(非)
                title: {(非)
                    text: '图表标题'(非)
                },
                quotaShow: false,     // 是否显示指标指数,默认false(非)
                quotaType: 'percent', // 指标指数类型,默认 percent 百分比(非),默认空值 '',即文本
                markArea: {           // 分割区域(非)
                    yAxis: [],        // 分割块,如:[0, 0.9, 90]->表示 0-0.9、0.9-90、90-最大值,三个区域 (非)
                    color: [],        // 分割块颜色,如:['#f2c7c0', '#f9de9d', '#daf4e6'](非)
                },
                yAxis: {              // 设置Y轴(非)
                    double: false,    // 是否启用双坐标轴, 默认false(注:true时需设置chartSettings.axisSite)(非)
                    doubleName: [],   // 设置左右坐标轴名称, 默认不设置(非)
                    doubleType: [],   // 设置左右坐标轴类型,默认 'value'(非)
                    doubleNumber: 5   // 间隔数, 默认 5
                },
                ...
            },
            ... // 更多配置项查看(https://v-charts.js.org/#/props)
        } 
    5、事件(按需添加)
        @chartEventsFn:图表点击事件
    6、示例
        全局文件中搜索 @components/common/Echarts,可查看更多具体示例
    7、使用的插件
        npm i v-charts echarts -S
  */
</style>

 

posted @ 2023-11-17 16:36  忙着可爱呀~  阅读(853)  评论(0)    收藏  举报