特殊箭头图表

在这里插入图片描述

<template>
  <div class="chart" v-resize="resizeCharts" ref="piechart"></div>
</template>

<script>
const arrow =
  "data:image/png;base64,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";
const legendIcons = ["circle", "circle", "circle", "image://" + arrow];
import * as echarts from "echarts";
export default {
  data() {
    return {
      data: [
        {
          name: "本年退用量",
          percentData: [50, 40, 60, 80, 30, 75], // 所占百分比
          data: [687091, 176706, 126074, 107335, 252376, 24600], // 真实数据
          color: "rgb(0, 229, 255)", // 柱子颜色
        },
        {
          name: "本周退用量",
          percentData: [5, 6, 4, 10, 3, 8],
          data: [18785, 6000, 6295, 3951, 1769, 770],
          color: "rgb(250, 193, 45)",
        },
        {
          name: "剩余量",
          percentData: [45, 54, 36, 10, 67, 17],
          data: [1159314, 128782, 382171, 228806, 380269, 39286],
          color: "rgb(186, 155, 201)",
        },
        {
          // 箭头对应的百分比和真实数据,无需传入颜色
          name: "截至11月底计划",
          percentData: [60, 50, 70, 90, 40, 85],
          data: [687091, 176706, 126074, 107335, 252376, 24600],
        },
      ],
      yAxisData: ["冀北", "唐山", "张家口", "秦皇岛", "承德", "廊坊"],
      unit: "单位:万只",
    };
  },
  methods: {
    resizeCharts() {
      this.charts.resize();
    },
    initCharts() {
      this.$nextTick(() => {
        this.charts = echarts.init(this.$refs.piechart);
        this.charts.clear();
        this.setOption();
      });
    },
    setOption() {
      const series = this.getSeries(this.data);
      const legend = this.getLegend(this.data);
      const option = this.getOption(this.data, legend, series, this.yAxisData);
      this.charts.setOption(option, true);
    },
    getSeries(data) {
      const series = [];
      for (let i = 0; i < data.length - 1; i++) {
        const tempMap = {
          name: data[i].name,
          type: "bar",
          stack: "total",
          barWidth: 14,
          itemStyle: {
            color: data[i].color,
          },
          label: {
            show: true,
            verticalAlign: "middle",
            formatter(series) {
              return data[series.seriesIndex].percentData[series.dataIndex] + "%";
            },
            offset: [0, 1],
            textStyle: {
              color: "#fff",
            },
          },
          data: data[i].percentData,
        };
        series.push(tempMap);
      }
      series.push({
        ...data[3],
        data: data[3].percentData,
        type: "bar",
        barMaxWidth: 1,
        itemStyle: {
          color: "rgba(0, 0, 0, 0)",
        },
        label: {
          show: true,
          position: "right",
          formatter(series) {
            return `\n{b|}{a|${data[series.seriesIndex].data[series.dataIndex]}}`;
          },
          rich: {
            a: {
              color: "#fff",
              height: 20,
              lineHeight: 30,
              padding: [5, 0, 0, 0],
            },
            b: {
              backgroundColor: {
                image: arrow,
              },
              height: 15,
              width: 20,
              align: "center",
              padding: [0, 0, 0],
            },
          },
        },
      });
      return series;
    },
    getLegend(data) {
      const legend = [];
      for (let i = 0; i < data.length; i++) {
        const tempMap = {
          name: data[i].name,
          icon: legendIcons[i],
        };
        legend.push(tempMap);
      }
      return legend;
    },
    getOption(data, legend, series, yAxis) {
      const option = {
        tooltip: {
          trigger: "axis",
          formatter(series) {
            let html = `<div>${series[0].name}</div>`;
            for (let i = 0; i < series.length; i++) {
              const item = series[i];
              if (i === 3) {
                item.marker = `<span style='display:inline-block;margin-left:-5px;width:20px;height:15px;background:url("${arrow}") no-repeat center / 100% 100%;'></span>`;
              }
              html += `<div>${item.marker} ${item.seriesName}: ${data[item.seriesIndex].data[item.dataIndex]}</div>`;
            }
            return html;
          },
        },
        legend: {
          show: true,
          itemWidth: 20,
          itemHeight: 15,
          data: legend,
          bottom: 10,
          textStyle: {
            color: "#fff",
          },
        },
        grid: {
          top: 40,
          left: "10",
          right: "40",
          bottom: "45",
          containLabel: true,
        },
        xAxis: {
          type: "value",
          axisLabel: {
            formatter(val) {
              return val + "%";
            },
            textStyle: {
              color: "#fff",
            },
          },
          splitLine: {
            lineStyle: {
              color: "rgba(255, 255, 255, 0.5)",
              width: 0.5,
            },
          },
        },
        yAxis: {
          type: "category",
          name: this.unit,
          nameTextStyle: {
            color: "#fff",
          },
          nameGap: 10,
          offset: 0,
          data: yAxis,
          axisLabel: {
            textStyle: {
              color: "#fff",
            },
          },
          axisTick: {
            lineStyle: {
              color: "rgba(255, 255, 255, 0.5)",
              width: 0.5,
            },
          },
          axisLine: {
            lineStyle: {
              color: "rgba(255, 255, 255, 0.5)",
              width: 0.5,
            },
          },
        },
        series,
      };
      return option;
    },
  },
  mounted() {
    this.initCharts();
  },
  beforeDestroy() {
    this.charts && this.charts.dispose();
    this.charts = null;
  },
  watch: {
    dataArr: {
      handler() {
        if (this.charts) {
          this.setOption();
        } else {
          this.initCharts();
        }
      },
    },
  },
};
</script>

<style scoped lang="less">
.chart {
  width: 100%;
  height: 100%;
  background: #001e51;
}
</style>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值