echarts双轴图-年龄分布

在这里插入图片描述

安装插件

npm install element-resize-detector

公共方法,图标自适应窗口大小
import elementResizeDetectorMaker from "element-resize-detector";
drawLine(id, option) {
    const erd = elementResizeDetectorMaker();

    let myChart = echarts.init(document.getElementById(id));
    // 绘制图表配置
    // 窗口大小自适应方案
    myChart.setOption(option);
    setTimeout(function () {
      // window.addEventListener('resize', () => myChart.resize(), false);
      // window.onresize = function () {
      //   myChart.resize();
      // };
      erd.listenTo(document.getElementById(id), element => {
        // var width = element.offsetWidth;
        // var height = element.offsetHeight;
        // console.log("Size: " + width + "x" + height);
        myChart.resize()
      });
    }, 200);
  },
封装组件
<template>
  <div id="cf-double-column" :style="{ width: width, height: height }">
    <!-- <p class="title"><span class="title-left"></span>{{ title }}</p> -->
    <div :id="chartID" :style="{ width: width, height: height }"></div>
    <div class="footer-name">
      <p>男</p>
      <p>女</p>
    </div>
  </div>
</template>

<script>
/**
 * title{String} 图表的标题
 * chartID{String} 图表的唯一标识
 * width{String} 图表的宽度
 * height{String} 图表的高度
 * data1{Array} 左边柱状图的数据
 * data2{Array} 右边柱状图的数据
 *
 * 数据格式:
 *    data1与data2格式一致,且name应该对应,value是值,sum可以用来算百分比,是同类name的值的和
 *    data1: {
          name: "百岁以上",
          value: 23.4,
          sum: 30,
        },
        {
          name: "90-99岁",
          value: 16,
          sum: 20,
        },
        {
          name: "80-89岁",
          value: 15,
          sum: 20,
        },
        {
          name: "70-79岁",
          value: 1500,
          sum: 20,
        } 
 * 
 * 
 */
import * as echarts from "echarts";
export default {
  name: "CFDoubleColumn",
  props: ["chartID", "width", "height", "data1", "data2", "title"],
  data() {
    return {
      myChart: "",
    };
  },
  watch: {
    data1: {
      handler(newVal, oldVal) {
        console.log(newVal);
        if (this.myChart) {
          this.myChart.dispose();
        }
        this.$nextTick(() => {
          this.getDoubleCloumn();
        });
      },
      immediate: true,
    },
  },
  mounted() {
    this.getDoubleCloumn();
  },
  methods: {
    getDoubleCloumn() {
      var data1 = this.data1;
      var data2 = this.data2;
      let getArrByKey = (data, k) => {
        let key = k || "value";
        let res = [];
        if (data) {
          data.forEach(function (t) {
            res.push(t[key]);
          });
        }
        return res;
      };
      var maxNum = 0; // 横坐标的最大值
      var maxNumList = [], data1Num = [], data2Num = []
      for (let i in data1) {
        data1Num.push(data1[i].value)
      }
      for (let i in data2) {
        data2Num.push(data2[i].value)
      }
      var data1Max = Math.max(...data1Num)
      var data2Max = Math.max(...data2Num)
      if (data1Max > data2Max) {
        maxNum = data1Max
      } else {
        maxNum = data2Max
      }
      for (let i = 0; i < data1.length; i++) {
        maxNumList.push(maxNum)
      }
      console.log(data1Max, data2Max, maxNumList)
      // [起始最深颜色,结束的浅颜色]
      let colorLeft = ["#3DA1FF", "#2749FC"];
      let colorRight = ["#FB857D", "#F6504A"];
      let option = {
        legend: {
          top: "5%",
          right: "10%",
          itemWidth: 50,
          itemHeight: 22,
          itemGap: 40,
          orient: "horizontal",
          icon: "circle",
          textStyle: {
            color: "#ffffff",
            fontSize: 20,
          },
          // data: ['规模猪场', '中小猪场']
        },
        grid: [
          {
            show: false,
            left: "2%",
            top: "10%",
            bottom: "8%",
            width: "40%",
          },
          {
            show: false,
            left: "51%",
            top: "10%",
            bottom: "8%",
            width: "0%",
          },
          {
            show: false,
            right: "2%",
            top: "10%",
            bottom: "8%",
            width: "40%",
          },
        ],
        tooltip: {
          show: false,
          // 设置  是否百分比
          formatter: "{b} : {c}",
        },
        xAxis: [
          {
            type: "value",
            inverse: true,
            axisLine: {
              show: false,
            },
            axisTick: {
              show: false,
            },
            position: "bottom",
            axisLabel: {
              show: false,
            },
            splitLine: {
              show: false,
            },
          },
          {
            gridIndex: 1,
            show: false,
          },
          {
            gridIndex: 2,
            show: true,
            type: "value",
            inverse: false,
            axisLine: {
              show: false,
            },
            axisTick: {
              show: false,
            },
            position: "bottom",
            axisLabel: {
              show: true,
              textStyle: {
                color: "white",
              },
            },
            splitLine: {
              show: false,
            },
          },
        ],
        yAxis: [
          {
            gridIndex: 0,
            triggerEvent: true,
            show: true,
            inverse: true,
            data: getArrByKey(data1, "name"),
            axisLine: {
              show: false,
            },
            splitLine: {
              show: false,
            },
            axisTick: {
              show: false,
            },
            axisLabel: {
              show: false,
            },
          },
          {
            gridIndex: 1,
            type: "category",
            inverse: true,
            position: "left",
            axisLine: {
              show: false,
            },
            axisTick: {
              show: false,
            },
            axisLabel: {
              show: true,
              interval: 0,
              align: "auto",
              verticalAlign: "middle",
              textStyle: {
                color: "#000",
                fontSize: 16,
                align: "center",
              },
            },
            data: getArrByKey(data1, "name"),
          },
          {
            gridIndex: 2,
            triggerEvent: true,
            show: true,
            inverse: true,
            data: getArrByKey(data2, "name"),
            axisLine: {
              show: false,
            },
            splitLine: {
              show: false,
            },
            axisTick: {
              show: false,
            },
            axisLabel: {
              show: false,
            },
          },
        ],
        series: [
          {
            type: "pictorialBar",
            xAxisIndex: 0,
            yAxisIndex: 0,
            // symbol: 'rect',
            itemStyle: {
              normal: {
                color: "rgba(0,0,0,0)",
              },
            },
            barWidth: 10,
            // symbolRepeat: true,
            // symbolSize: 14,
            data: maxNumList,
            barGap: "-100%",
            barCategoryGap: 0,
            label: {
              normal: {
                show: false,
                // formatter: (series) => {
                //   return lastYearData[timeLineData[0]][series.dataIndex] + "%";
                // },
                position: "insideTopLeft",
                textStyle: {
                  color: "#ffffff",
                  fontSize: 20,
                },
                offset: [0, -10],
              },
            },
            z: -100,
            animationEasing: "elasticOut",
            animationDelay: function (dataIndex, params) {
              return params.index * 30;
            },
          },
          {
            // name: '规模猪场',
            type: "bar",
            gridIndex: 0,
            // showBackground: true,
            backgroundStyle: {
              barBorderRadius: 30,
            },
            xAxisIndex: 0,
            yAxisIndex: 0,
            data: data1,
            barWidth: 20,
            // barCategoryGap: '40%',
            itemStyle: {
              normal: {
                show: true,
                // 线性渐变,前四个参数分别是 x0, y0, x2, y2, 范围从 0 - 1,分别表示右,下,左,上。例如(0,0,0,1)表示从正上开始向下渐变;如果是(1,0,0,0),则是从正右开始向左渐变。
                // 相当于在图形包围盒中的百分比,如果最后一个参数传 true,则该四个值是绝对的像素位置
                color: new echarts.graphic.LinearGradient(
                  0,
                  0,
                  1,
                  0,
                  [
                    {
                      offset: 0,
                      color: colorLeft[0], //指0%处的颜色
                    },
                    {
                      offset: 1,
                      color: colorLeft[1], //指100%处的颜色
                    },
                  ],
                  false
                ),
                barBorderRadius: [10, 0, 0, 10],
              },
            },

            label: {
              normal: {
                show: false,
                position: "insideRight",
                textStyle: {
                  color: "#ffffff",
                  fontSize: "12",
                },
              },
            },
          },
          {
            type: "pictorialBar",
            xAxisIndex: 2,
            yAxisIndex: 2,
            symbol: "rect",
            itemStyle: {
              normal: {
                color: "rgba(0,0,0,0)",
              },
            },
            barWidth: 10,
            symbolRepeat: true,
            symbolSize: 14,
            data: maxNumList,
            barGap: "-100%",
            barCategoryGap: 0,
            label: {
              normal: {
                show: false,
                // formatter: (series) => {
                //   return thisYearData[timeLineData[0]][series.dataIndex] + "%";
                // },
                position: "insideTopRight",
                textStyle: {
                  color: "#ffffff",
                  fontSize: 20,
                },
                offset: [0, -10],
              },
            },
            z: -100,
            animationEasing: "elasticOut",
            animationDelay: function (dataIndex, params) {
              return params.index * 30;
            },
          },
          {
            // name: '中小猪场',
            type: "bar",
            xAxisIndex: 2,
            yAxisIndex: 2,
            gridIndex: 2,
            showBackground: false,
            backgroundStyle: {
              barBorderRadius: 30,
            },
            data: data2,
            barWidth: 20,
            // barCategoryGap: '40%',
            itemStyle: {
              normal: {
                show: true,
                // 线性渐变,前四个参数分别是 x0, y0, x2, y2, 范围从 0 - 1,分别表示右,下,左,上。例如(0,0,0,1)表示从正上开始向下渐变;如果是(1,0,0,0),则是从正右开始向左渐变。
                // 相当于在图形包围盒中的百分比,如果最后一个参数传 true,则该四个值是绝对的像素位置
                color: new echarts.graphic.LinearGradient(
                  0,
                  0,
                  1,
                  0,
                  [
                    {
                      offset: 0,
                      color: colorRight[0], //指0%处的颜色
                    },
                    {
                      offset: 1,
                      color: colorRight[1], //指100%处的颜色
                    },
                  ],
                  false
                ),
                barBorderRadius: [0, 10, 10, 0],
              },
            },
            label: {
              normal: {
                show: false,
                position: "insideLeft",
                textStyle: {
                  color: "#ffffff",
                  fontSize: "12",
                },
              },
            },
          },
        ],
      };
      this.myChart = this.tools.drawLine(this.chartID, option);
    },
  },
};
</script>

<style lang="scss" scoped>
#cf-double-column {
  position: relative;
  width: 100%;
  height: 100%;
  background: #ffffff;
  border-radius: 0.5rem;
  .title {
    position: absolute;
    top: 0;
    left: 1rem;
    font-size: 1.13rem;
    font-weight: bold;
    color: #333333;
    .title-left {
      display: inline-block;
      width: 0.25rem;
      height: 1rem;
      background: linear-gradient(180deg, #3ea2ff 0%, #2746fc 100%);
      border-radius: 0.13rem;
      margin-right: 1rem;
    }
  }
  .footer-name {
    position: absolute;
    bottom: 0;
    color: #333333;
    font-size: 0.88rem;
    width: 100%;
    p {
      display: inline-block;
      width: 50%;
      padding: 0 3rem;
    }
    p:nth-of-type(1) {
      text-align: right;
    }
  }
}
</style>
父组件调用
<CFDoubleColumn
        chartID="chart2"
        width="48.75rem"
        height="28.63rem"
        :data1="columndata1"
        :data2="columndata2"
        title="年龄分布"
></CFDoubleColumn>
数据格式

name 是坐标名称,value是对应的值

      columndata1: [
        { name: "百岁以上",  value: 234 },
        { name: "90-99岁", value: 160  },
        { name: "80-89岁",  value: 1500 },
        { name: "70-79岁", value: 1500 },
        { name: "60-69岁", value: 960 },
        { name: "45-59岁", value: 98 },
        { name: "18-44岁", value: 97 },
        { name: "6-17岁", value: 95 },
        { name: "0-5岁", value: 94 },
      ],
      columndata2: [
        { name: "百岁以上", value: 234 },
        { name: "90-99岁", value: 1600 },
        { name: "80-89岁", value: 105 },
        { name: "70-79岁", value: 105 },
        { name: "60-69岁", value: 960 },
        { name: "45-59岁", value: 98 },
        { name: "18-44岁", value: 97 },
        { name: "6-17岁", value: 95 },
        { name: "0-5岁", value: 94 },
      ],
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值