echarts自定义组件

图1
在这里插入图片描述
图2
在这里插入图片描述
图3
在这里插入图片描述
图4
在这里插入图片描述
图5
在这里插入图片描述

图6
在这里插入图片描述
图7
在这里插入图片描述
图8
在这里插入图片描述
图9
在这里插入图片描述
图10
在这里插入图片描述
图11
在这里插入图片描述
图12
在这里插入图片描述

柱状图1

组件:

<template>
  <div :id="ids" style="width: 100%; height: 100%" class="barHeight"></div>
</template>
<script>
import * as echarts from 'echarts'

export default {
  props: {
    chartData: {
      default: function () {
        return []
      }
    },
    ids: {
      // id
      type: String,
      default: 'echartsbar'
    },
    fontColor: {
      // 字体颜色
      type: String,
      default: '#89949F'
    },
    yLine: {
      // x轴分割线
      default: false
    },
    unit: {
      // 单位
      default: function () {
        return '人'
      }
    },
    unitName: {
      default: function () {
        return '单位: '
      }
    },
    barWidth: {
      default: 16
    },
    theme: {
      default: function () {
        return ['#00c6ff', '#006cff']
      }
    }
  },
  data() {
    return {
      mychart: null
    }
  },
  mounted() {
    this.mychart = echarts.init(document.getElementById(this.ids))
  },
  watch: {
    chartData: {
      handler() {
        this.$nextTick(() => {
          if (this.chartData && this.chartData.length > 0) {
            this.drawChart()
          }
        })
      },
      deep: true, // 深度监听,可监听到对象、数组的变化
      immediate: true // 立刻执行
    }
  },
  methods: {
    drawChart() {
      // 绘制图表
      const _this = this
      const option = {
        title: {
          show: false
        },
        grid: {
          left: 30,
          right: 20,
          top: 30,
          bottom: 0,
          containLabel: true
        },
        tooltip: {
          trigger: 'axis',
          formatter: function (data) {
            let html = ''
            html = '<div class="toolTips">'
            for (let i = 0; i < data.length; i++) {
              html += `<div style="font-size: 12px;color: #fff">${data[i].name}: ${data[i].value} ${_this.unit}</div>`
            }
            html += '</div>'
            return html
          },
          backgroundColor: '#487892',
          borderWidth: 0,
          padding: [3, 5]
        },
        xAxis: [
          {
            type: 'category',
            data: this.chartData.map((item) => item.name),
            axisLabel: {
              color: this.fontColor,
              fontSize: 12
            },
            axisTick: {
              show: false
            },
            axisLine: {
              lineStyle: {
                color: 'rgba(135,142,148,0.5)'
              }
            }
          }
        ],
        yAxis: {
          type: 'value',
          name: this.unitName + this.unit,
          nameTextStyle: {
            fontSize: 12,
            color: this.fontColor
          },
          splitNumber: 5,
          position: 'left',
          axisTick: {
            show: false
          },
          splitLine: {
            show: this.yLine,
            lineStyle: {
              color: 'rgba(153, 153, 153, 0.3)'
            }
          },
          axisLine: {
            show: false
          },
          axisLabel: {
            color: this.fontColor,
            fontSize: 12
          }
        },
        series: [
          {
            type: 'bar',
            label: {
              show: true,
              position: 'top',
              color: '#fff'
            },
            data: this.chartData.map((item) => Number(item.num)),
            barWidth: this.barWidth,
            itemStyle: {
              normal: {
                barBorderRadius: 2,
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  {
                    offset: 0,
                    color: this.theme[0]
                  },
                  {
                    offset: 1,
                    color: this.theme[1]
                  }
                ])
              }
            }
          }
        ]
      }
      this.mychart.clear()
      this.mychart.setOption(option, true)
    }
  }
}
</script>
<style scoped></style>

调用:

<EchartsBar
              v-if="data.length"
              style="height: 260px"
              class="mt-4"
              unitName="含沙量: "
              unit="kg/m³"
              ids="sediment1"
              :yLine="true"
              :chartData="data"
              :theme="['#2AA0FF', 'rgba(0, 0, 0, 0)']"
            ></EchartsBar>

数据:

data =  [
          {
            name: '玉林',
            num: 0.458
          },
          {
            name: '玉松',
            num: 0.363
          },
          {
            name: '希让',
            num: 0.421
          },
          {
            name: '黄河头道拐',
            num: 4.6
          },
          {
            name: '金沙江溪洛渡',
            num: 1.72
          }
        ]

效果:
在这里插入图片描述

柱状图2

组件:

<template>
  <div :id="baseConfig.ids" style="width: 100%; height: 100%"></div>
</template>
<script>
export default {
  props: {
    data: {
      default: function() {
        return [];
      }
    },
    baseConfig: {
      default: function() {
        return {
          ids: "EchartsBar",
          title: "",
          unit: "人"
        };
      }
    },
    showLabel: {
      default: true
    },
    barWidth: {
      default: 12
    },
    barClick: {
      type: Function
    },
    yNamePadding: {
      default: function() {
        return [0, 0, 10, -30];
      }
    },
    gridLeft: {
      //盒子左边距
      default() {
        return 30;
      }
    }
  },
  data() {
    return {
      mychart: null,
      color: ["#88d4ff", "#3a89ff"]
    };
  },
  mounted() {
    this.mychart = this.$echarts.init(
      document.getElementById(this.baseConfig.ids)
    );
    this.drawChart();
  },
  watch: {
    data: {
      //深度监听,可监听到对象、数组的变化
      handler() {
        this.$nextTick(() => {
          this.drawChart();
        });
      },
      deep: true
    }
  },
  methods: {
    drawChart() {
      const CubeLeft = new this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0
        },
        buildPath: (ctx, shape) => {
          const xAxisPoint = shape.xAxisPoint;
          const c0 = [shape.x, shape.y];
          const c1 = [shape.x - this.barWidth, shape.y - 4];
          const c2 = [xAxisPoint[0] - this.barWidth, xAxisPoint[1] - 4];
          const c3 = [xAxisPoint[0], xAxisPoint[1]];
          ctx
            .moveTo(c0[0], c0[1])
            .lineTo(c1[0], c1[1])
            .lineTo(c2[0], c2[1])
            .lineTo(c3[0], c3[1])
            .closePath();
        }
      });
      const CubeRight = new this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0
        },
        buildPath: (ctx, shape) => {
          const xAxisPoint = shape.xAxisPoint;
          const c1 = [shape.x - this.barWidth / 4, shape.y];
          const c2 = [xAxisPoint[0] - this.barWidth / 4, xAxisPoint[1]];
          const c3 = [xAxisPoint[0] + this.barWidth / 2, xAxisPoint[1] - 4];
          const c4 = [shape.x + this.barWidth / 2, shape.y - 4];
          ctx
            .moveTo(c1[0], c1[1])
            .lineTo(c2[0], c2[1])
            .lineTo(c3[0], c3[1])
            .lineTo(c4[0], c4[1])
            .closePath();
        }
      });
      const CubeTop = new this.$echarts.graphic.extendShape({
        shape: {
          x: 0,
          y: 0
        },
        buildPath: (ctx, shape) => {
          // 逆时针 角 y 负数向上  X 负数向左
          const c1 = [shape.x - this.barWidth / 4, shape.y + 4];
          const c2 = [shape.x + this.barWidth / 2, shape.y - 4];
          const c3 = [shape.x - this.barWidth / 4, shape.y - 4];
          const c4 = [shape.x - this.barWidth, shape.y - 4];
          ctx
            .moveTo(c1[0], c1[1])
            .lineTo(c2[0], c2[1])
            .lineTo(c3[0], c3[1])
            .lineTo(c4[0], c4[1])
            .closePath();
        }
      });
      new this.$echarts.graphic.registerShape("CubeLeft", CubeLeft);
      new this.$echarts.graphic.registerShape("CubeRight", CubeRight);
      new this.$echarts.graphic.registerShape("CubeTop", CubeTop);

      let TData = this.data.map(item => Number(item.num));
      let diffNum = Math.max(...TData) / 3;
      let dataShadow = [];
      for (var i = 0; i < this.data.length; i++) {
        dataShadow.push(((Math.max(...TData) + diffNum) * 100) / 100);
      }
      let option = {
        title: {
          show: false
        },
        grid: {
          left: this.gridLeft,
          right: 20,
          top: 40,
          bottom: this.data.length > 4 ? 10 : 5,
          containLabel: true
        },
        tooltip: {
          formatter: "{b}: {c}" + this.baseConfig.unit
        },
        xAxis: [
          {
            type: "category",
            data: this.data.map(item => item.name),
            triggerEvent: true,
            axisLabel: {
              formatter: function(value) {
                var res = value;
                if (res.length > 6) {
                  res = res.substring(0, 5) + "...";
                }
                return res;
              },
              fontFamily: "时尚中黑简体",
              interval: 0,
              rotate: this.data.length > 3 ? 15 : 0,
              color: "rgba(255,255,255,.8)",
              fontSize: 14,
              align: "center",
              padding: this.data.length > 3 ? [30, 0, 0, -24] : [0, 0, 0, -24]
            },
            axisTick: {
              show: false
            },
            axisLine: {
              lineStyle: {
                color: "rgba(135,142,148,0.5)"
              }
            }
          }
        ],
        yAxis: {
          type: "value",
          name: "单位(" + this.baseConfig.unit + ")",
          nameTextStyle: {
            fontSize: 14,
            color: "#9ca2a8",
            padding: this.yNamePadding
          },
          scale: false,
          axisLabel: {
            color: "#a0a5ab",
            fontSize: 14
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: "rgba(255,255,255,.1)"
            }
          },
          axisLine: {
            show: false
          },
          axisTick: {
            show: false
          }
        },
        dataZoom: [
          {
            show: !!(this.data.length > 4),
            start: 0,
            end: this.data.length > 4 ? 30 : 100,
            height: 10,
            bottom: 8,
            textStyle: {
              color: "#e2e2e2"
            },
            borderColor: "#e2e2e2",
            handleIcon:
              "M512 512m-208 0a6.5 6.5 0 1 0 416 0 6.5 6.5 0 1 0-416 0Z M512 192C335.264 192 192 335.264 192 512c0 176.736 143.264 320 320 320s320-143.264 320-320C832 335.264 688.736 192 512 192zM512 800c-159.072 0-288-128.928-288-288 0-159.072 128.928-288 288-288s288 128.928 288 288C800 671.072 671.072 800 512 800z",
            handleColor: "#aab6c6",
            handleSize: 16,
            handleStyle: {
              borderColor: "#aab6c6",
              shadowBlur: 4,
              shadowOffsetX: 1,
              shadowOffsetY: 1,
              shadowColor: "#e5e5e5"
            }
          },
          {
            type: "inside",
            realtime: true
          }
        ],
        series: [
          {
            type: "custom",
            zlevel: 2,
            renderItem: (params, api) => {
              const location = api.coord([api.value(0), api.value(1)]);
              return {
                type: "group",
                children: [
                  {
                    type: "CubeLeft",
                    shape: {
                      api,
                      xValue: api.value(0),
                      yValue: api.value(1),
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0])
                    },
                    style: {
                      fill: new this.$echarts.graphic.LinearGradient(
                        0,
                        0,
                        0,
                        1,
                        [
                          {
                            offset: 0.4,
                            color: "#93D884"
                          },
                          {
                            offset: 1,
                            color: "rgba(0,0,0,0)"
                          }
                        ]
                      )
                    }
                  },
                  {
                    type: "CubeRight",
                    shape: {
                      api,
                      xValue: api.value(0),
                      yValue: api.value(1),
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0])
                    },
                    style: {
                      fill: new this.$echarts.graphic.LinearGradient(
                        0,
                        0,
                        0,
                        1,
                        [
                          {
                            offset: 0.4,
                            color: "#3FBB70" // 顶部
                          },
                          {
                            offset: 1,
                            color: "rgba(0,0,0,0)" // 底部
                          }
                        ]
                      )
                    }
                  },
                  {
                    type: "CubeTop",
                    shape: {
                      api,
                      xValue: api.value(0),
                      yValue: api.value(1),
                      x: location[0],
                      y: location[1],
                      xAxisPoint: api.coord([api.value(0), 0])
                    },
                    style: {
                      fill: new this.$echarts.graphic.LinearGradient(
                        0,
                        0,
                        0,
                        1,
                        [
                          {
                            offset: 0,
                            color: "#cbec8a"
                          },
                          {
                            offset: 1,
                            color: "#cbec8a"
                          }
                        ]
                      )
                    }
                  }
                ]
              };
            },
            data: TData
          },
          {
            type: "bar",
            label: {
              normal: {
                show: true,
                position: "top",
                distance: 10,
                fontSize: 16,
                color: "#97af58"
              }
            },
            barWidth: this.barWidth,
            itemStyle: {
              color: "transparent"
            },
            data: TData
          },
          {
            type: "bar",
            itemStyle: {
              borderColor: "rgba(151,175,88,0.5)",
              color: "rgba(0,0,0,0)"
            },
            barWidth: this.barWidth * 2.4,
            barGap: "-155%",
            tooltip: {
              show: false
            },
            cursor: "default",
            data: dataShadow,
            animation: false
          }
        ]
      };
      this.mychart.setOption(option);
      if (this.barClick) {
        let timer = null;
        //防止重复触发点击事件
        if (this.mychart._$handlers.click) {
          this.mychart._$handlers.click.length = 0;
        }
        this.mychart.on("click", params => {
          if (!timer) {
            timer = setTimeout(() => {
              console.log(this.data[0]);
              timer = null;
            }, 100);
          }
        });
      }
    }
  }
};
</script>

调用:

<EchartsBar
            :gridLeft="0"
            :yNamePadding="[0, 0, 10, 0]"
            :data="data"
            :baseConfig="{
              ids: 'EchartsBarinvestmentPlanning',
              title: '',
              unit: '亿元'
            }"
          ></EchartsBar>

数据:

data = [
        {
          name: "近期",
          num: 650
        },
        {
          name: "中期",
          num: 1200
        },
        {
          name: "远期",
          num: 1600
        }
      ]

效果:
在这里插入图片描述

柱状图3

组件:

<template>
  <div style="width: 100%; height: 100%" class="relative">
    <e-charts :option="options" ref="echarts" />
  </div>
</template>
<script>
import ECharts from '@/components/echarts/ECharts.vue'

export default {
  components: {
    ECharts
  },
  props: {
    data: {
      default: function () {
        return [
          {
            name: '区域1',
            value: 10
          },
          {
            name: '区域2',
            value: 20
          }
        ]
      }
    },
    theme: {
      default: function () {
        return ['#2ACAFF', '#0074C5']
      }
    },
    barWidth: {
      default: 15
    },
    showShadow: {
      default: true
    },
    unit: {
      default: ''
    }
  },
  data() {
    return {
      options: {}
    }
  },
  watch: {
    data: {
      handler() {
        this.initCharts()
      },
      deep: true
    }
  },
  mounted() {
    this.initCharts()
  },
  computed: {
    axisData() {
      return this.data.map((item) => {
        return item.name
      })
    },
    valueArr() {
      return this.data.map((item) => {
        return Number(item.value)
      })
    }
  },
  methods: {
    // 绘制图表
    async initCharts() {
      const instance = await this.$refs.echarts.wait()
      const option = {
        title: {
          show: false
        },
        grid: {
          left: 0,
          right: 10,
          top: 30,
          bottom: 20,
          containLabel: true
        },
        tooltip: {
          backgroundColor: '#000',
          borderWidth: 0,
          padding: [3, 5],
          textStyle: {
            color: '#fff'
          },
          formatter: '{b}: {c}' + this.unit
        },
        xAxis: [
          {
            type: 'category',
            data: this.axisData,
            axisLabel: {
              color: '#fff',
              fontSize: 14
            },
            axisTick: {
              show: false
            },
            axisLine: {
              lineStyle: {
                color: 'rgba(255,255,255,0.2)'
              }
            }
          }
        ],
        yAxis: {
          type: 'value',
          splitNumber: 3,
          splitLine: true,
          scale: true,
          axisLabel: {
            color: '#fff',
            fontSize: 16
          },
          axisLine: {
            lineStyle: {
              color: 'rgba(255,255,255,0.2)'
            }
          }
        },
        series: [
          {
            type: 'bar',
            data: this.valueArr,
            barMaxWidth: this.barWidth,
            barWidth: this.barWidth,
            showBackground: this.showShadow,
            backgroundStyle: {
              color: 'rgba(255, 255, 255, 0.05)'
            },
            itemStyle: {
              normal: {
                barBorderRadius: 2,
                color: new instance.echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  {
                    offset: 0,
                    color: this.theme[0]
                  },
                  {
                    offset: 1,
                    color: this.theme[1]
                  }
                ])
              }
            },
            label: {
              normal: {
                show: this.showShadow,
                position: 'top',
                color: '#fff',
                fontSize: '16px'
              }
            }
          }
        ]
      }
      this.options = option
    }
  }
}
</script>
<style scoped></style>

调用:

<EchartsBar :data="data" />

数据:

data = [
        {
          name: '区域1',
          value: 10
        },
        {
          name: '区域2',
          value: 20
        },
        {
          name: '区域3',
          value: 30
        },
        {
          name: '区域4',
          value: 2
        },
        {
          name: '区域5',
          value: 0
        },
        {
          name: '区域6',
          value: 8
        }
      ]

效果:
在这里插入图片描述

柱状图4

组件:

<template>
  <div style="width: 100%; height: 100%" class="flex flex-col justify-between">
    <div v-for="(item, index) of dataList" :key="index">
      <template v-if="item.title">
        <div class="progress_title mb-2">{{ item.title }}</div>
        <div class="progress_box flex">
          <div class="progress_bar">
            <div
              class="progress_innerBar"
              :style="{
                width:
                  (item.isProportion
                    ? item.value
                    : (item.value / total) * 100) + '%'
              }"
            ></div>
          </div>
          <div class="progress_value">
            {{ item.value }} <span v-if="item.isProportion">%</span>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    dataList: {
      type: Array,
      default: function () {
        return []
      }
    }
  },
  data() {
    return {
      total: 0
    }
  },
  mounted() {
    this.dataList.forEach((item) => {
      this.total += Number(item.value)
    })
  }
}
</script>

<style lang="scss">
.progress_title {
  font-size: 14px;
  font-weight: 500;
  color: #ffffff;
}

.progress_box {
  .progress_bar {
    width: calc(100% - 40px);
    height: 14px;
    background: rgba(0, 212, 224, 0);
    border: 1px solid rgba(0, 0, 0, 0.5);
    margin-right: 15px;
    box-shadow: 0 0 5px #fff inset;

    .progress_innerBar {
      height: 12px;
      background: url(/assets/images/common/pro_inner.png);
    }
  }

  .progress_value {
    width: 40px;
    flex-shrink: 0;
    height: 11px;
    font-size: 14px;
    font-weight: bold;
    color: #19d0f0;
    line-height: 10px;
  }
}
</style>

调用:

<HtProcess :dataList="data" />

数据:

data = [
        {
          title: '2022年资金缺口总数',
          value: 81
        },
        {
          title: '2022年预计投资总额',
          value: 810
        },
        {
          title: '已投资总额',
          value: 270
        },
        {
          title: '总投资额',
          value: 1578
        }
      ]

pro_inner.png
在这里插入图片描述

效果:
在这里插入图片描述

柱状图+折线图

组件:

<template>
  <div style="width: 100%; height: 100%" class="relative">
    <e-charts :option="options" ref="echarts" />
  </div>
</template>

<script>
import ECharts from '@/components/echarts/ECharts.vue'

export default {
  components: {
    ECharts
  },
  props: {
    chartData: {
      type: Object,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return {
          unit: '单位: 万元',
          xData: ['01月', '02月'],
          barLegend: ['第一产业', '第二产业', '第三产业'],
          barData: [
            {
              value1: 2.0,
              value2: 2.6,
              value3: 2.6
            },
            {
              value1: 4.9,
              value2: 5.9,
              value3: 2.6
            }
          ],
          lineLegend: ['生产总值'],
          lineData: [
            {
              value1: 4.9
            }
          ]
        }
      }
    },
    barColorList: {
      type: Array,
      default: function () {
        return ['#177BE1', '#05EDEA', '#0DE58C', '#F8B551']
      }
    },
    lineColorList: {
      type: Array,
      default: function () {
        return ['#F8B551', '#177BE1']
      }
    },
    barWidth: {
      default: 10
    }
  },
  data() {
    return {
      options: {}
    }
  },
  watch: {
    chartData: {
      handler() {
        this.initCharts()
      },
      deep: true
    }
  },
  methods: {
    async initCharts() {
      // const instance = await this.$refs.echarts.wait()
      const _this = this
      const colorList = _this.barColorList
      _this.options = {
        color: colorList,
        grid: {
          left: '60px',
          right: '20px',
          bottom: '50px'
        },
        tooltip: {
          trigger: 'axis',
          backgroundColor: '#000',
          borderWidth: 0,
          padding: [3, 5],
          textStyle: {
            color: '#fff'
          }
        },
        legend: {
          data: [..._this.chartData.barLegend, ..._this.chartData.lineLegend], // 动态处理
          textStyle: {
            color: '#fff'
          }
        },
        xAxis: [
          {
            type: 'category',
            data: _this.chartData.xData,
            axisTick: {
              show: false
            },
            axisLabel: {
              color: '#fff',
              fontSize: 14
            }
          }
        ],
        yAxis: [
          {
            type: 'value',
            name: '单位: ' + _this.chartData.unit, // 动态处理
            nameTextStyle: {
              color: '#fff',
              fontSize: 14
            },
            axisLabel: {
              color: '#fff',
              fontSize: 16
            },
            splitLine: {
              lineStyle: {
                color: 'rgba(255, 255, 255, 0.05)'
              }
            }
          }
        ],
        series: [
          ..._this.chartData.barLegend.map((item, index) => {
            return {
              name: item, // 动态处理
              type: 'bar',
              barWidth: _this.barWidth,
              data: _this.barValueArr('value' + (index + 1)) // 动态处理
            }
          }),
          ..._this.chartData.lineLegend.map((item, index) => {
            return {
              name: item, // 动态处理
              type: 'line',
              smooth: true,
              showSymbol: false,
              itemStyle: {
                color: _this.lineColorList[index]
              },
              data: _this.lineValueArr('value' + (index + 1)) // 动态处理
            }
          })
        ]
      }
    },
    barValueArr(value) {
      return this.chartData.barData.map((item) => Number(item[value]))
    },
    lineValueArr(value) {
      return this.chartData.lineData.map((item) => Number(item[value]))
    }
  },
  mounted() {
    this.initCharts()
  }
}
</script>

<style></style>

调用:

<EchartsBarLine :chartData="data" />

数据:

data = {
        unit: '万元',
        barLegend: ['第一产业', '第二产业', '第三产业'],
        lineLegend: ['生产总值'],
        xData: [
          '乐山市',
          '市中区',
          '沙湾区',
          '五通桥区',
          '金口河区',
          '键为县',
          '井研县',
          '夹江县',
          '峨边彝族自治区',
          '马边彝族自治区'
        ],
        barData: [
          {
            value1: 1570,
            value2: 1545,
            value3: 3534
          },
          {
            value1: 2420,
            value2: 3324,
            value3: 2434
          },
          {
            value1: 3230,
            value2: 5432,
            value3: 6434
          },
          {
            value1: 3352,
            value2: 2353,
            value3: 5334
          },
          {
            value1: 1329,
            value2: 2515,
            value3: 5334
          },
          {
            value1: 5678,
            value2: 7943,
            value3: 3434
          },
          {
            value1: 6368,
            value2: 3423,
            value3: 5434
          },
          {
            value1: 6616,
            value2: 9865,
            value3: 2534
          },
          {
            value1: 2778,
            value2: 6334,
            value3: 6344
          },
          {
            value1: 7519,
            value2: 5615,
            value3: 6534
          }
        ],
        lineData: [
          {
            value1: 5570
          },
          {
            value1: 2420
          },
          {
            value1: 4230
          },
          {
            value1: 3352
          },
          {
            value1: 1329
          },
          {
            value1: 5678
          },
          {
            value1: 6368
          },
          {
            value1: 7616
          },
          {
            value1: 2778
          },
          {
            value1: 3519
          }
        ]
      }

效果:
在这里插入图片描述

折线图1

组件:

<template>
  <div class="echarts-line" :id="ids"></div>
</template>

<script>
import * as echarts from 'echarts'

export default {
  props: {
    legendChecked: {
      // 图例
      default: true
    },
    ids: {
      // id
      type: String,
      default: 'echartsline'
    },
    fontColor: {
      // 字体颜色
      type: String,
      default: '#89949F'
    },
    yLine: {
      // x轴分割线
      default: false
    },
    chartData: {
      // echarts·数据
      default: function () {
        return []
      }
    },
    // Y轴单位
    Yunit: {
      type: Boolean,
      default: true
    },
    theme: {
      default: function () {
        return ['#3da4fe', '#23cef2', '#65b664', '#00FDCB']
      }
    }
  },
  watch: {
    chartData: {
      // 深度监听,可监听到对象、数组的变化
      handler() {
        this.$nextTick(() => {
          if (this.chartData && this.chartData.length > 0) {
            this.dataValue(this.chartData)
          }
        })
      },
      deep: true, // 深度监听,可监听到对象、数组的变化
      immediate: true // 立刻执行
    }
  },
  data() {
    return {}
  },
  mounted() {},
  methods: {
    dataValue(newVal) {
      if (newVal && newVal.length > 0) {
        const seriesConfig = []
        const Yconfig = []
        const unit = []
        for (let i = 0; i < newVal.length; i++) {
          if (newVal[i].areaStyle) {
            const obj = {
              type: 'line',
              name: newVal[i].name,
              data: newVal[i].yData,
              smooth: newVal[i].smooth ? newVal[i].smooth : false,
              showSymbol: newVal[i].showSymbol ? newVal[i].showSymbol : false,
              lineStyle: {
                color: newVal[i].lineColor
              },
              areaStyle: {
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  {
                    offset: 0,
                    color: newVal[i].areaColor
                  },
                  {
                    offset: 1,
                    color: 'rgba(0,0,0,0)'
                  }
                ])
              }
            }
            if (i === 1) {
              obj.yAxisIndex = 1
            }
            seriesConfig.push(obj)
            if (this.Yunit) {
              Yconfig.push({
                type: 'value',
                name:
                  (newVal.length > 1 ? newVal[i].name : '单位') +
                  ':' +
                  newVal[i].unit,
                nameTextStyle: {
                  fontSize: 12,
                  color: this.fontColor
                },
                splitNumber: 5,
                axisTick: {
                  show: false
                },
                splitLine: {
                  show: this.yLine,
                  lineStyle: {
                    color: 'rgba(153, 153, 153, 0.3)'
                  }
                },
                axisLine: {
                  show: false
                },
                axisLabel: {
                  color: this.fontColor,
                  fontSize: 12
                }
              })
            } else {
              Yconfig.push({
                type: 'value',
                nameTextStyle: {
                  fontSize: 12,
                  color: this.fontColor
                },
                splitNumber: 5,
                axisTick: {
                  show: false
                },
                splitLine: {
                  show: this.yLine,
                  lineStyle: {
                    color: 'rgba(153, 153, 153, 0.3)'
                  }
                },
                axisLine: {
                  show: false
                },
                axisLabel: {
                  color: this.fontColor,
                  fontSize: 12
                }
              })
              Yconfig[0].name = '(m³/s)'
            }

            unit.push(newVal[i].unit)
          } else {
            seriesConfig.push({
              type: 'line',
              name: newVal[i].name,
              data: newVal[i].yData,
              smooth: newVal[i].smooth ? newVal[i].smooth : false,
              symbolSize: newVal[i].showSymbol ? newVal[i].showSymbol : false,
              lineStyle: {
                color: newVal[i].lineColor
              }
            })
            Yconfig.push({
              type: 'value',
              name: newVal[i].name + ':' + newVal[i].unit,
              nameTextStyle: {
                fontSize: 12,
                color: this.fontColor
              },
              splitNumber: 5,
              axisTick: {
                show: false
              },
              splitLine: {
                show: this.yLine,
                lineStyle: {
                  color: '#e5e5e5'
                }
              },
              axisLine: {
                show: false
              },
              axisLabel: {
                color: this.fontColor,
                fontSize: 12
              }
            })
            unit.push(newVal[i].unit)
          }
        }
        this.setEcharts(seriesConfig, Yconfig, newVal[0].xData, unit)
      }
    },
    setEcharts(series, Yconfig, dataAxis, unit) {
      let legend = []
      if (this.legendChecked) {
        legend = this.chartData.map((data, i) => {
          return {
            name: data.name,
            icon: 'roundRect',
            itemStyle: series[i].lineStyle
          }
        })
      } else {
        legend = []
      }
      const myChart = echarts.init(document.getElementById(this.ids))
      const option = {
        color: this.theme,
        tooltip: {
          trigger: 'axis',
          formatter: function (data) {
            if (!data.length) return
            if (data.length > 1) {
              let html = ''
              html = `<div class="toolTips"><div style="font-size: 12px;color: #fff">${data[0].axisValue}</div>`
              for (let i = 0; i < data.length; i++) {
                html += `<div style="font-size: 12px;color: #fff">${series[i].name}: ${data[i].value} ${unit[i]}</div>`
              }
              html += '</div>'
              return html
            } else {
              return `<div class="toolTips"><div style="font-size: 12px;color: #fff">${data[0].axisValue}: ${data[0].value} ${unit[0]}</div></div>`
            }
          },
          backgroundColor: '#487892',
          borderWidth: 0,
          padding: [3, 5],
          axisPointer: {
            lineStyle: {
              color: '#299acb'
            }
          }
        },
        legend: {
          top: 0,
          right: 'center',
          width: 240,
          data: legend,
          itemWidth: 15,
          itemHeight: 5,
          show: true,
          selectedMode: false,
          textStyle: {
            color: this.fontColor
          }
        },
        xAxis: {
          type: 'category',
          data: dataAxis,
          boundaryGap: false,
          axisTick: {
            show: true,
            inside: true
          },
          splitLine: {
            show: false
          },
          axisLine: {
            lineStyle: {
              color: 'rgba(135,142,148,0.5)'
            }
          },
          axisLabel: {
            color: this.fontColor,
            fontSize: 12
          }
        },
        yAxis: Yconfig,
        grid: {
          left: 20,
          right: 35,
          top: this.legendChecked ? 30 : 30,
          bottom: 0,
          containLabel: true
        },
        series: series
      }
      myChart.clear()
      myChart.setOption(option, true)
    }
  }
}
</script>

<style scoped lang="scss">
.echarts-line {
  width: 100%;
  height: 100%;
}
</style>

调用:

<EchartsLine
              v-if="data"
              style="height: 190px"
              class="mt-4"
              ids="waterflow"
              :legendChecked="true"
              :chartData="data"
            ></EchartsLine>

数据:

{
    "title":"ML",
    "data":[
        {
            "lineColor":"#00FDCB",
            "areaStyle":true,
            "smooth":true,
            "areaColor":"rgba(0,253,203,0.2)",
            "xData":[
                "03-10 18:00",
                "03-10 19:00",
                "03-10 20:00",
                "03-10 21:00",
                "03-10 22:00",
                "03-10 23:00",
                "03-11 00:00",
                "03-11 01:00",
                "03-11 02:00",
                "03-11 03:00",
                "03-11 04:00",
                "03-11 05:00",
                "03-11 06:00",
                "03-11 07:00",
                "03-11 08:00",
                "03-11 09:00",
                "03-11 10:00",
                "03-11 11:00",
                "03-11 12:00",
                "03-11 13:00",
                "03-11 14:00",
                "03-11 15:00",
                "03-11 16:00",
                "03-11 17:00"
            ],
            "yData":[
                "2925.51",
                "2925.51",
                "2925.50",
                "2925.49",
                "2925.48",
                "2925.47",
                "2925.46",
                "2925.45",
                "2925.47",
                "2925.49",
                "2925.53",
                "2925.58",
                "2925.62",
                "2925.65",
                "2925.67",
                "2925.67",
                "2925.66",
                "2925.65",
                "2925.63",
                "2925.61",
                "2925.58",
                "2925.57",
                "2925.55",
                "2925.55"
            ],
            "name":"水位",
            "unit":"m"
        },
        {
            "lineColor":"#00E5FF",
            "areaStyle":true,
            "smooth":true,
            "areaColor":"rgba(0,229,255,0.2)",
            "xData":[
                "03-10 18:00",
                "03-10 19:00",
                "03-10 20:00",
                "03-10 21:00",
                "03-10 22:00",
                "03-10 23:00",
                "03-11 00:00",
                "03-11 01:00",
                "03-11 02:00",
                "03-11 03:00",
                "03-11 04:00",
                "03-11 05:00",
                "03-11 06:00",
                "03-11 07:00",
                "03-11 08:00",
                "03-11 09:00",
                "03-11 10:00",
                "03-11 11:00",
                "03-11 12:00",
                "03-11 13:00",
                "03-11 14:00",
                "03-11 15:00",
                "03-11 16:00",
                "03-11 17:00"
            ],
            "yData":[
                345,
                345,
                341,
                337,
                333,
                329,
                325,
                321,
                329,
                337,
                353,
                374,
                392,
                406,
                415,
                415,
                410,
                406,
                396,
                387,
                374,
                370,
                362,
                362
            ],
            "name":"流量",
            "unit":"m³/s"
        }
    ]
}

效果:
在这里插入图片描述

饼状图1

组件:

<template>
  <div :id="ids" class="echarts-pie"></div>
</template>
<script>
import * as echarts from 'echarts'

export default {
  props: {
    chartData: {
      type: Number,
      default: 0
    },
    ids: {
      // id
      type: String,
      default: 'echartspie'
    },
    fontColor: {
      // 字体颜色
      type: String,
      default: '#fff'
    },
    theme: {
      // 主题色
      type: String,
      default: '89949F'
    },
    unit: {
      // 单位
      default: function () {
        return '个'
      }
    }
  },
  data() {
    return {
      mychart: null
    }
  },
  mounted() {
    this.mychart = echarts.init(document.getElementById(this.ids))
  },
  watch: {
    chartData: {
      handler() {
        this.$nextTick(() => {
          this.drawChart()
        })
      },
      deep: true, // 深度监听,可监听到对象、数组的变化
      immediate: true // 立刻执行
    }
  },
  methods: {
    drawChart() {
      // 绘制图表
      const _this = this
      const option = {
        backgroundColor: 'rgba(255, 255, 255, 0)',
        title: {
          show: false
        },
        series: [
          {
            type: 'liquidFill',
            radius: '80%',
            center: ['50%', '50%'],
            data: [0.3, 0.3], // data个数代表波浪数
            backgroundStyle: {
              color: 'rgb(255,255,255,0.2)'
            },
            // 修改波浪颜色
            color: [_this.theme, 'rgb(255,255,255,0.2)'],
            label: {
              normal: {
                formatter: `${this.chartData} (${this.unit})`,
                textStyle: {
                  fontSize: 14,
                  color: this.fontColor
                }
              }
            },
            outline: {
              show: false
            }
          },
          {
            type: 'pie',
            center: ['50%', '50%'],
            radius: ['90%', '93%'],
            hoverAnimation: false,
            data: [
              {
                name: '',
                value: 300,
                labelLine: {
                  show: false
                },
                itemStyle: {
                  color: _this.theme
                }
              },
              {
                // 画中间的图标
                name: '',
                value: 3,
                labelLine: {
                  show: false
                },
                itemStyle: {
                  normal: {
                    borderColor: _this.theme,
                    borderWidth: 3
                  }
                }
              },
              {
                // 画剩余的刻度圆环
                name: '',
                value: 97,
                itemStyle: {
                  color: 'rgba(255, 255, 255, 0.3)'
                },
                label: {
                  show: false
                },
                labelLine: {
                  show: false
                }
              }
            ]
          }
        ]
      }
      this.mychart.clear()
      this.mychart.setOption(option, true)
    }
  }
}
</script>
<style scoped lang="scss">
.echarts-pie {
  width: 100%;
  height: 100%;
}
</style>

调用:

<EchartsPie
                    chartData="42"
                    ids="realtime1"
                    theme="#FF8A00"
                    style="height: 100px"
                  >
                  </EchartsPie>

效果:
在这里插入图片描述

饼状图2

组件:

// 有线条支出名字的饼图
<template>
  <div class="chart-pie">
    <div :id="ids" class="echarts-content"></div>
  </div>
</template>

<script>
export default {
  components: {},
  props: {
    ids: {
      default: "echartsPieCircle"
    },
    data: {
      default: function() {
        return []; // [{name: "18岁以下",num: 0},{name: "18岁以下",num: 0}]  数据格式
      }
    },
    title: {
      default: ""
    },
    unit: {
      default: "人"
    },
    split: {
      default: 2
    },
    isShowLegend: {
      default: true
    },
    colorList: {
      default: [
        "#28d1dc",
        "#33dfb5",
        "#487892",
        "#8cc0fc",
        "#7c9d70",
        "#3b7e48"
      ]
    },
    isShowLegendName: {
      default: true
    }
  },
  data() {
    return {
      total: 0,
      lengedNumber: []
    };
  },
  mounted() {
    this.initPie();
  },
  watch: {
    data: {
      //深度监听,可监听到对象、数组的变化
      handler() {
        this.$nextTick(() => {
          if (this.data.length) {
            this.initPie();
          }
        });
      },
      deep: true
    }
  },
  methods: {
    initPie() {
      var datas = this.data;
      this.total = 0;
      var lenged = [];
      var data = [];
      if (datas && datas.length > 0) {
        datas.forEach(item => {
          this.total += item.num;
          lenged.push(item.name);
        });
      }
      for (var i = 0; i < datas.length; i++) {
        data.push({
          value: datas[i].num,
          name: datas[i].name,
          unit: datas[i].unit || "",
          itemStyle: {
            normal: {
              borderWidth: 1,
              borderColor: this.colorList[i]
            }
          }
        });
        if (datas.length > 1) {
          data.push({
            value: this.total / 100,
            tooltip: {
              show: false
            },
            name: "",
            itemStyle: {
              normal: {
                label: {
                  show: false
                },
                labelLine: {
                  lineStyle: {
                    color: "rgba(255, 255, 255, 0.3)"
                  },
                  smooth: 0.2,
                  length: 30,
                  length2: 20
                },
                color: "rgba(0, 0, 0, 0)",
                borderColor: "rgba(0, 0, 0, 0)",
                borderWidth: 0
              }
            }
          });
        }
      }
      var seriesOption = [
        {
          name: "",
          type: "pie",
          clockWise: false,
          radius: [
            (document.getElementById(this.ids).clientHeight * 3) / 8 - 4,
            (document.getElementById(this.ids).clientHeight * 3) / 8 + 6
          ],
          hoverAnimation: false,
          itemStyle: {
            normal: {
              label: {
                show: true,
                // align: 'center',
                // padding: [-30, -1],
                // height: 30,
                // rotate: -90,
                // verticalAlign: 'middle',
                lineHeight: 60
                // formatter (v) {
                //   let text = Math.round(v.percent) + '%' + '' + v.name
                //   if (text.length <= 8) {
                //     return text;
                //   } else if (text.length > 8 && text.length <= 16) {
                //     return text = `${text.slice(0, 8)}\n${text.slice(8)}`
                //   } else if (text.length > 16 && text.length <= 24) {
                //     return text = `${text.slice(0, 8)}\n${text.slice(8, 16)}\n${text.slice(16)}`
                //   } else if (text.length > 24 && text.length <= 30) {
                //     return text = `${text.slice(0, 8)}\n${text.slice(8, 16)}\n${text.slice(16, 24)}\n${text.slice(24)}`
                //   } else if (text.length > 30) {
                //     return text = `${text.slice(0, 8)}\n${text.slice(8, 16)}\n${text.slice(16, 24)}\n${text.slice(24, 30)}\n${text.slice(30)}`
                //   }
                // },
              },
              labelLine: {
                length: 20,
                length2: 10,
                show: true
              }
            }
          },
          data: data
        }
      ];
      var option = {
        color: this.colorList,
        title: {
          show: false
        },
        graphic: {
          elements: [
            {
              type: "image",
              z: 3,
              style: {
                width:
                  (document.getElementById(this.ids).clientHeight * 3) / 3 - 14,
                height:
                  (document.getElementById(this.ids).clientHeight * 3) / 3 - 14,
                image: "/img/echarts/circle.png"
              },
              left: "center",
              top: "center",
              position: [100, 100]
            },
            {
              type: "text",
              top: (document.getElementById(this.ids).clientHeight * 3) / 9,
              left: "center",
              style: {
                text: this.total,
                textAlign: "center",
                fill: "#fff",
                font: '24px "trends"'
              }
            },
            {
              type: "group",
              top: document.getElementById(this.ids).clientHeight / 1.8,
              left: "center",
              style: {
                textAlign: "center"
              },
              children: [
                {
                  type: "text",
                  left: -10,
                  style: {
                    text: this.title,
                    fill: "#fff",
                    font: '16px "trends"'
                  }
                }
              ]
            }
          ]
        },
        tooltip: {
          confine: true,
          formatter: "{b}: {c}"
        },
        legend: {
          show: false
        },
        toolbox: {
          show: false
        },
        series: seriesOption
      };
      let myChart = this.$echarts.init(document.getElementById(this.ids));
      myChart.setOption(option);
      //计算百分比
      this.lengedNumber = this.data.map(item =>
        ((item.num / this.total) * 100).toFixed(2)
      );
      let count = 0;
      for (let i = 0; i < this.lengedNumber.length - 1; i++) {
        count += Number(this.lengedNumber[i]) * 100;
      }
      this.lengedNumber[this.lengedNumber.length - 1] =
        (10000 - Number(count)) / 100;
    }
  }
};
</script>
<style scoped lang="less">
.chart-pie {
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  align-items: center;
  margin-top: 10px;
  box-sizing: border-box;

  .echarts-content {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
  }
}
</style>

调用:

<EchartsPieHasLine
              :isShowLegendName="false"
              :data="data"
              :title="'总数'"
              :unit="'家'"
              :colorList="
                data.map(colorItem => {
                  return colorItem.color;
                })
              "
            ></EchartsPieHasLine>

数据:

data = [
        {
          name: "高等院校用地",
          num: 0.28,
          color: "#cd78c1"
        },
        {
          name: "商业设施用地",
          num: 0.02,
          color: "#ce1610"
        },
        {
          name: "中小学用地",
          num: 0.03,
          color: "#b77be0"
        },
        {
          name: "农业用地",
          num: 0.09,
          color: "#a0c4b9"
        },
        {
          name: "公园绿地",
          num: 0.01,
          color: "#91a3b4"
        },
        {
          name: "工业用地",
          num: 0.07,
          color: "#b8c658"
        },
        {
          name: "二类居住用地",
          num: 0.02,
          color: "#abbc86"
        },

        {
          name: "公用设施用地",
          num: 0.05,
          color: "#139ac8"
        },
        {
          name: "服务设施用地",
          num: 0.01,
          color: "#c5aeae"
        },
        {
          name: "医疗卫生用地",
          num: 0.1,
          color: "#cb8396"
        }
      ]

circle.png
在这里插入图片描述
效果:
在这里插入图片描述

饼状图3

组件:

<template>
  <div class="chart-pie">
    <div
      :id="ids"
      class="echarts-content"
      :style="{ width: isShowLegend ? '45%' : '100%' }"
    ></div>
    <ul
      class="echarts-legend"
      :style="{ display: isShowLegend ? 'flex' : 'none' }"
    >
      <li v-for="(item, idx) in data" :key="item.name">
        <div
          class="legend-box"
          :style="{ backgroundColor: colorList[idx] }"
        ></div>
        <el-tooltip
          v-if="isShowLegendName"
          class="item"
          effect="dark"
          :content="item.name"
          placement="left-start"
        >
          <div class="legend-name">{{ item.name }}</div>
        </el-tooltip>
        <span class="legend-scale" v-if="!!item.num"
          ><i>{{ item.num }}</i></span
        >
        <span class="legend-scale" v-else
          ><i>{{ item.num }}</i
          >%</span
        >
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  components: {},
  props: {
    ids: {
      default: "echartsPieCircle"
    },
    data: {
      default: function() {
        return []; // [{name: "18岁以下",num: 0},{name: "18岁以下",num: 0}]  数据格式
      }
    },
    title: {
      default: ""
    },
    unit: {
      default: "人"
    },
    split: {
      default: 2
    },
    isShowLegend: {
      default: true
    },
    colorList: {
      default: function() {
        return [
          "#28d1dc",
          "#33dfb5",
          "#487892",
          "#8cc0fc",
          "#7c9d70",
          "#3b7e48"
        ];
      }
    },
    isShowLegendName: {
      default: true
    }
  },
  data() {
    return {
      total: 0,
      lengedNumber: []
    };
  },
  mounted() {
    this.initPie();
  },
  watch: {
    data: {
      //深度监听,可监听到对象、数组的变化
      handler() {
        this.$nextTick(() => {
          if (this.data.length) {
            this.initPie();
          }
        });
      },
      deep: true
    }
  },
  methods: {
    initPie() {
      var datas = this.data;
      this.total = 0;
      var lenged = [];
      var data = [];
      if (datas && datas.length > 0) {
        datas.forEach(item => {
          this.total += item.num;
          lenged.push(item.name);
        });
      }
      for (var i = 0; i < datas.length; i++) {
        data.push({
          value: datas[i].num,
          name: datas[i].name,
          unit: datas[i].unit || "",
          itemStyle: {
            normal: {
              borderWidth: 1,
              borderColor: this.colorList[i]
            }
          }
        });
        if (datas.length > 1) {
          data.push({
            value: this.total / 100,
            tooltip: {
              show: false
            },
            name: "",
            itemStyle: {
              normal: {
                label: {
                  show: false
                },
                labelLine: {
                  show: false
                },
                color: "rgba(0, 0, 0, 0)",
                borderColor: "rgba(0, 0, 0, 0)",
                borderWidth: 0
              }
            }
          });
        }
      }
      var seriesOption = [
        {
          name: "",
          type: "pie",
          clockWise: false,
          radius: [
            (document.getElementById(this.ids).clientHeight * 3) / 8 - 4,
            (document.getElementById(this.ids).clientHeight * 3) / 8 + 6
          ],
          hoverAnimation: false,
          itemStyle: {
            normal: {
              label: {
                show: false
              },
              labelLine: {
                length: 30,
                length2: 100,
                show: false
              }
            }
          },
          data: data
        }
      ];
      var option = {
        color: this.colorList,
        title: {
          show: false
        },
        graphic: {
          elements: [
            {
              type: "image",
              z: 3,
              style: {
                width:
                  (document.getElementById(this.ids).clientHeight * 3) / 3 - 14,
                height:
                  (document.getElementById(this.ids).clientHeight * 3) / 3 - 14,
                image: "/img/echarts/circle.png"
              },
              left: "center",
              top: "center",
              position: [100, 100]
            },
            {
              type: "text",
              top: (document.getElementById(this.ids).clientHeight * 3) / 9,
              left: "center",
              style: {
                text: this.total,
                textAlign: "center",
                fill: "#fff",
                font: '24px "trends"'
              }
            },
            {
              type: "group",
              top: document.getElementById(this.ids).clientHeight / 1.8,
              left: "center",
              style: {
                textAlign: "center"
              },
              children: [
                {
                  type: "text",
                  left: -10,
                  style: {
                    text: this.title,
                    fill: "#fff",
                    font: '16px "trends"'
                  }
                }
              ]
            }
          ]
        },
        tooltip: {
          confine: true,
          formatter: "{b}: {c}"
        },
        legend: {
          show: false
        },
        toolbox: {
          show: false
        },
        series: seriesOption
      };
      let myChart = this.$echarts.init(document.getElementById(this.ids));
      myChart.setOption(option);
      //计算百分比
      this.lengedNumber = this.data.map(item =>
        ((item.num / this.total) * 100).toFixed(2)
      );
      let count = 0;
      for (let i = 0; i < this.lengedNumber.length - 1; i++) {
        count += Number(this.lengedNumber[i]) * 100;
      }
      this.lengedNumber[this.lengedNumber.length - 1] =
        (10000 - Number(count)) / 100;
    }
  }
};
</script>
<style scoped lang="less">
.chart-pie {
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  align-items: center;
  margin-top: 10px;
  box-sizing: border-box;

  .echarts-content {
    width: 45%;
    height: 100%;
    position: absolute;
    left: 0;
  }

  .echarts-legend {
    position: absolute;
    left: 47%;
    width: 55%;
    height: 100%;
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    justify-content: space-around;

    li {
      width: 100%;
      display: flex;
      line-height: 20px;
      height: 20px;
      background: url("/img/echarts/legend-box.png") no-repeat;
      background-size: 100% 100%;
      padding: 0 5px;

      .legend-box {
        width: 3px;
        height: 22px;
        margin-top: -1px;
      }

      .legend-name {
        color: #89949f;
        font-size: 14px;
        margin: 0 15px 0 8px;
        // width: 82px;
        // overflow: hidden;
        // white-space: nowrap;
        // text-overflow: ellipsis;
      }

      .legend-scale {
        right: 10px;
        position: absolute;
        color: #89949f;

        i {
          display: inline-block;
          width: 70px;
          color: #fff;
          font-style: normal;
          font-family: 时尚中黑简体;
          text-align: right;
          font-size: 18px;
          margin-right: 10px;
        }
      }
    }
  }
}
</style>

调用:

<EchartsPie
            :data="data"
            :title="'项目总数'"
            :unit="'亿元'"
          ></EchartsPie>

数据:

data = [
        {
          name: "已签约",
          num: 6
        },
        {
          name: "洽谈中",
          num: 5
        },
        {
          name: "签约目标",
          num: 8
        }
      ]

效果:
在这里插入图片描述

饼状图4

组件:

<template>
  <div style="width: 100%; height: 100%" class="relative">
    <e-charts :option="options" ref="echarts" />
  </div>
</template>

<script>
import ECharts from '@/components/echarts/ECharts.vue'
export default {
  components: {
    ECharts
  },
  props: {
    data: {
      type: Array,
      // 对象或数组默认值必须从一个工厂函数获取
      default: function () {
        return [
          { name: '克莱因壶', value: 3.5 },
          { name: '投资最重要的事', value: 2.8 }
        ]
      }
    },
    colorList: {
      type: Array,
      default: function () {
        return [
          '#2dea9c',
          '#00ffff',
          '#eec700',
          '#b9b9b9',
          '#009ff1',
          '#ff0000'
        ]
      }
    }
  },
  watch: {
    data(newVal) {
      this.initCharts()
    }
  },
  data() {
    return {
      options: {}
    }
  },
  methods: {
    async initCharts() {
      // const instance = await this.$refs.echarts.wait()
      const _this = this
      const colorList = _this.colorList
      const giftImageUrl = '/assets/images/echarts/bg.png'
      _this.options = {
        color: colorList,
        title: {
          text: '',
          left: 'center',
          textStyle: {
            color: '#fff',
            fontSize: 16
          }
        },
        graphic: {
          elements: [
            {
              type: 'group',
              left: 'center',
              top: 'center',
              children: [
                {
                  type: 'image',
                  style: {
                    image: giftImageUrl,
                    width: 180,
                    height: 180
                  },
                  left: 'center',
                  top: 'center'
                }
              ]
            }
          ]
        },
        series: {
          type: 'pie',
          radius: [40, 60],
          left: 'center',
          width: 320,
          // itemStyle: {
          //   borderColor: '#fff',
          //   borderWidth: 1
          // },
          label: {
            alignTo: 'edge',
            formatter: '{name|{b}}\n{time|{c} }',
            minMargin: 5,
            edgeDistance: 10,
            lineHeight: 15,
            color: '#fff',
            rich: {
              time: {
                fontSize: 16,
                color: '#fff'
              }
            }
          },
          labelLine: {
            length: 15,
            length2: 0,
            maxSurfaceAngle: 80
          },
          data: _this.data
        }
      }
    }
  },
  mounted() {
    this.initCharts()
  }
}
</script>

<style></style>

调用:

<EchartsPie :data="data" />

数据:

data = [
        {
          name: '居住用地',
          value: 3.5
        },
        {
          name: '其他土地',
          value: 2.8
        },
        {
          name: '交通运输用地',
          value: 1.7
        },
        {
          name: '林地',
          value: 1.4
        },
        {
          name: '草地',
          value: 0.5
        },
        {
          name: '公共服务用地',
          value: 3.8
        }
      ]

bg.png
在这里插入图片描述

效果:
在这里插入图片描述

饼状图5

组件:

<template>
  <div style="width: 100%; height: 100%" class="relative">
    <e-charts :option="options" ref="echarts" />
  </div>
</template>
<script>
import ECharts from '@/components/echarts/ECharts.vue'

export default {
  components: {
    ECharts
  },
  props: {
    showLegend: {
      default: true
    },
    colorList: {
      default: function () {
        return ['#1ccfb8', '#007fd3', '#5e8bac', '#016f85', '#34c0e0']
      }
    },
    data: {
      default: function () {
        return [
          {
            value: 5,
            name: '智慧城市'
          },
          {
            value: 31,
            name: '自然资源'
          },
          {
            value: 9,
            name: '智慧电力'
          },
          {
            value: 35,
            name: '智慧交通'
          },
          {
            value: 20,
            name: '智慧应急'
          }
        ]
      }
    }
  },
  data() {
    return {
      options: {}
    }
  },
  watch: {
    data() {
      this.initCharts()
    }
  },
  mounted() {
    this.initCharts()
  },
  methods: {
    // 绘制图表
    async initCharts() {
      const colorList = this.colorList
      var giftImageUrl = '/assets/images/echarts/bg.png'
      var option = {
        title: {
          show: false
        },
        tooltip: {
          trigger: 'item',
          backgroundColor: '#000',
          borderWidth: 0,
          padding: [3, 5],
          textStyle: {
            color: '#fff'
          },
          formatter: function (data) {
            if (data.data.unit === '%') {
              return data.name + ':' + data.value + ' ' + data.data.unit || ''
            } else {
              return data.name + ':' + data.percent + '%'
            }
          }
        },
        graphic: {
          elements: [
            {
              type: 'group',
              left: 'center',
              top: 'center',
              children: [
                {
                  type: 'image',
                  style: {
                    image: giftImageUrl,
                    width: 100,
                    height: 100
                  },
                  left: 'ceenter',
                  top: 'center'
                }
              ]
            }
          ]
        },
        legend: {
          orient: 'horizontal',
          type: 'scroll',
          height: 100,
          bottom: 0,
          x: 'center',
          itemHeight: 10,
          itemWidth: 10,
          textStyle: {
            color: '#fff'
          },
          show: this.showLegend
        },
        calculable: true,
        grid: {
          containLabel: true,
          left: 30,
          right: 30
        },
        series: [
          {
            name: '半径模式',
            type: 'pie',
            radius: [20, 74],
            center: ['50%', '50%'],
            roseType: 'area',
            data: this.data,
            startAngle: 90,
            color: colorList,
            labelLine: {
              normal: {
                show: true,
                length: 5,
                length2: 5,
                lineStyle: {
                  width: 1
                }
              }
            },
            label: {
              normal: {
                alignTo: 'edge',
                margin: 0,
                color: '#fff',
                textBorderWidth: 0,
                formatter: (data) => {
                  if (data.data.unit) {
                    return (
                      '{d|' +
                      data.data.name +
                      '\n}{c|' +
                      data.data.value +
                      '}{b|' +
                      data.data.unit +
                      '}' +
                      '\n\n'
                    )
                  } else {
                    return (
                      '{d|' +
                      data.data.name +
                      '\n}{c|' +
                      data.data.value +
                      '}{b|}'
                    )
                  }
                },
                rich: {
                  b: {
                    fontSize: 14,
                    padding: [-27, 4, 5, 5],
                    color: 'rgba(255,255,255,.7)'
                  },
                  d: {
                    fontSize: 16,
                    padding: [-20, 0, 0, 0],
                    lineHeight: 24
                  },
                  c: {
                    fontSize: 18,
                    padding: [-30, 0, 0, 5],
                    lineHeight: 24
                  }
                }
              }
            }
          }
        ]
      }
      this.options = option
    }
  }
}
</script>
<style scoped></style>

调用:

<EchartsRose :data="data" />

数据:

data = [
            {
              name: '区域1',
              value: 10
            },
            {
              name: '区域2',
              value: 20
            },
            {
              name: '区域3',
              value: 30
            },
            {
              name: '区域4',
              value: 2
            },
            {
              name: '区域5',
              value: 0
            },
            {
              name: '区域6',
              value: 8
            }
          ]

效果:
在这里插入图片描述

饼状图6

组件:

<!--
 * @Author: your name
 * @Date: 2020-07-02 14:53:13
 * @LastEditTime: 2020-07-15 16:58:51
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \web\src\components\echartsPieCircle.vue
-->
<template>
  <div style="width: 100%; height: 100%" class="relative">
    <e-charts
      :option="options"
      ref="echarts"
      :id="ids"
      class="echarts-content"
    />
    <div class="echarts-legend">
      <ul>
        <li
          v-for="(item, idx) in data"
          :key="item.name"
          style="position: relative; border: none; display: flex"
        >
          <div
            :style="{ 'background-color': color[idx] }"
            style="
              width: 10px;
              height: 10px;
              position: absolute;
              top: 50%;
              left: -10px;
              transform: translateY(-50%);
            "
          ></div>
          <p >{{ item.name }}</p>
          <div style="margin-left: 10px" :style="{ color: color[idx] }">
            <span>{{
              ((item.value / total) * 100).toFixed(2)
            }}{{ unit }}</span>
          </div>
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import ECharts from '@/components/echarts/ECharts.vue'
export default {
  components: {
    ECharts
  },
  props: {
    ids: {
      default: 'echartsPieCircle'
    },
    data: {
      default: function () {
        return [
          {
            name: '1',
            value: 17
          },
          {
            name: '2',
            value: 11
          }
        ]
      }
    },
    unit: {
      default: '%'
    },
    split: {
      default: 2
    }
  },
  data() {
    return {
      color: ['#1CE2FF', '#00FFE3', '#26E4A7'],
      total: '',
      options: {}
    }
  },
  computed: {},
  created() {},
  mounted() {
    this.initPie()
  },
  updated() {},
  activated() {},
  watch: {},
  methods: {
    initPie() {
      var datas = this.data

      var data = []
      var color = this.color
      var total = 0
      if (datas && datas.length > 0) {
        datas.forEach((item) => {
          total += item.value
        })
        this.total = total
      }
      for (var i = 0; i < datas.length; i++) {
        data.push({
          value: datas[i].value,
          name: datas[i].name,
          unit: datas[i].unit || '',
          itemStyle: {
            normal: {
              borderWidth: 1,
              borderColor: color[i]
            }
          }
        })
        if (datas.length > 1) {
          data.push({
            value: (total * this.split) / 100,
            tooltip: {
              show: false
            },
            name: '',
            itemStyle: {
              normal: {
                label: {
                  show: false
                },
                labelLine: {
                  show: false
                },
                color: 'rgba(0, 0, 0, 0)',
                borderColor: 'rgba(0, 0, 0, 0)',
                borderWidth: 0
              }
            }
          })
        }
      }
      var seriesOption = [
        {
          name: '',
          type: 'pie',
          clockWise: false,
          radius: [
            (document.getElementById(this.ids).clientHeight * 3) / 9,
            (document.getElementById(this.ids).clientHeight * 3) / 9 + 6
          ],
          hoverAnimation: false,
          itemStyle: {
            normal: {
              label: {
                show: false
              },
              labelLine: {
                length: 30,
                length2: 100,
                show: false
              }
            }
          },
          data: data
        }
      ]
      var option = {
        color: color,
        title: {
          show: false
        },
        graphic: {
          elements: [
            {
              type: 'image',
              z: 3,
              style: {
                width:
                  (document.getElementById(this.ids).clientHeight * 3) / 5 - 14,
                height:
                  (document.getElementById(this.ids).clientHeight * 3) / 5 - 14,
                image: '/assets/images/echarts/circle.png'
              },
              left: 'center',
              top: 'center',
              position: [100, 100]
            },
            {
              type: 'group',
              top: document.getElementById(this.ids).clientHeight / 2 - 16,
              left: 'center',
              style: {
                textAlign: 'center'
              },
              children: [
                {
                  type: 'text',
                  left: -10,
                  style: {
                    text: total,
                    fill: '#fff',
                    fontSize: '36px',
                    fontWeight: 400
                  }
                },
                {
                  type: 'text',
                  top: 8,
                  left: total.toString().length * 6 + 30,
                  style: {
                    text: '个',
                    fill: '#fefefe',
                    font: '16px "Microsoft YaHei"'
                  }
                }
              ]
            }
          ]
        },
        tooltip: {
          confine: true,
          formatter: (params) => {
            return (
              params.data.name +
              ':' +
              params.data.value +
              ' ' +
              params.data.unit
            )
          }
        },
        legend: {
          show: false,
          icon: 'circle',
          orient: 'horizontal',
          // x: 'left',
          data: ['火车'],
          right: 340,
          bottom: 150,
          align: 'right',
          textStyle: {
            color: '#fff'
          },
          itemGap: 20
        },
        toolbox: {
          show: false
        },
        series: seriesOption
      }
      // let myChart = this.$echarts.init(document.getElementById(this.ids));
      // myChart.setOption(option);
      this.options = option
    }
  },
  filters: {}
}
</script>
<style scoped lang="scss">
.echarts-content {
  width: 180px;
  height: 80%;
  max-height: 200px;
  vertical-align: middle;
  display: inline-block;
  position: absolute;
  top: 50%;
  left: 0;
  transform: translate(0, -50%);
}
.echarts-legend {
  display: inline-block;
  vertical-align: middle;
  position: absolute;
  left: 200px;
  top: 50%;
  transform: translate(0, -50%);
  li {
    border-left: 2px solid;
    padding-left: 10px;
    margin-bottom: 15px;
    &:last-of-type {
      margin-bottom: 0;
    }
    p {
      font-size: 16px;
      color: #fff;
    }
    span {
      font-size: 18px;
    }
  }
}
</style>

调用:

 <EchartsPieCircie :data="data" />

数据:

data =  [
        {
          name: '废水',
          value: 17,
          unit: '个'
        },
        {
          name: '废气',
          value: 11,
          unit: '个'
        },
        {
          name: '固废',
          value: 19,
          unit: '个'
        }
      ]

circle.png
在这里插入图片描述

效果:
在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 中使用 Echarts 绘制自定义图表组件可以按照以下步骤进行: 1. 首先,确保已经安装了 echarts 库。可以使用 npm 或 yarn 进行安装: ``` npm install echarts --save ``` 2. 创建一个 Vue 组件,用于包含 Echarts 图表。可以命名为 `EchartsChart.vue`。 ```html <template> <div :ref="chartRef" class="echarts-chart"></div> </template> <script> import echarts from 'echarts'; export default { props: ['chartData'], data() { return { chartRef: 'echartsChart', chartInstance: null, }; }, mounted() { this.chartInstance = echarts.init(this.$refs[this.chartRef]); this.renderChart(); }, methods: { renderChart() { // 使用 chartData 配置图表数据和样式 this.chartInstance.setOption(this.chartData); }, }, beforeDestroy() { if (this.chartInstance) { this.chartInstance.dispose(); // 销毁图表实例,释放资源 } }, }; </script> <style scoped> .echarts-chart { width: 100%; height: 400px; /* 根据需求设置图表高度 */ } </style> ``` 在上面的示例中,我们创建了一个 `EchartsChart` 组件,接受一个 `chartData` 属性,用于配置图表的数据和样式。在 `mounted` 钩子中,我们初始化了 Echarts 实例,并在 `renderChart` 方法中使用 `setOption` 方法渲染图表。在组件销毁前,我们通过调用 `dispose` 方法销毁图表实例,释放资源。 3. 在使用自定义图表组件的父组件中,引入并使用 `EchartsChart` 组件。可以通过传递 `chartData` 属性来配置图表。 ```html <template> <div> <echarts-chart :chartData="chartData"></echarts-chart> </div> </template> <script> import EchartsChart from '@/components/EchartsChart.vue'; export default { components: { EchartsChart, }, data() { return { chartData: { // 配置图表的数据和样式 }, }; }, }; </script> ``` 在上面的示例中,我们在父组件中引入了 `EchartsChart` 组件,并通过 `chartData` 属性配置图表的数据和样式。 你可以根据自己的需求在 `chartData` 中配置图表的相关数据,例如 `title`、`tooltip`、`xAxis`、`yAxis`、`series` 等。具体的配置可以参考 Echarts 的文档。 希望这个示例能够帮助你创建自定义的 Echarts 图表组件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值