vue3+g2plot之瀑布图

137 阅读5分钟

基础瀑布图 - 每月收支情况

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

核心代码:

import { Waterfall } from '@antv/g2plot';

const data = [  { type: '日用品', money: 120 },  { type: '伙食费', money: 900 },  { type: '交通费', money: 200 },  { type: '水电费', money: 300 },  { type: '房租', money: 1200 },  { type: '商场消费', money: 1000 },  { type: '红包收入', money: -2000 },];

const waterfallPlot = new Waterfall('container', {
  data,
  xField: 'type',
  yField: 'money',
  appendPadding: [15000],
  meta: {
    type: {
      alias: '类别',
    },
    money: {
      alias: '收支',
      formatter: (v) => `${v} 元`,
    },
  },
  label: {
    style: { fontSize: 10, fill: 'rgba(0,0,0,0.65)' },
    layout: [{ type: 'interval-adjust-position' }],
  },
  total: {
    label'总支出',
    style: {
      fill: '#96a6a6',
    },
  },
});

waterfallPlot.render();

变化瀑布图 - 销售量一年的变化情况

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

核心代码:

import { Waterfall } from '@antv/g2plot';

const data = [  { month: '2019', value: 23000000 },  { month: 'Jan', value: 2200000 },  { month: 'Feb', value: -4600000 },  { month: 'Mar', value: -9100000 },  { month: 'Apr', value: 3700000 },  { month: 'May', value: -2100000 },  { month: 'Jun', value: 5300000 },  { month: 'Jul', value: 3100000 },  { month: 'Aug', value: -1500000 },  { month: 'Sep', value: 4200000 },  { month: 'Oct', value: 5300000 },  { month: 'Nov', value: -1500000 },  { month: 'Dec', value: 5100000 },];

const waterfallPlot = new Waterfall('container', {
  data,
  padding'auto',
  appendPadding: [20000],
  xField: 'month',
  yField: 'value',
  meta: {
    month: {
      alias: '月份',
    },
    value: {
      alias: '销售量',
      formatter: (v) => `${v / 10000000} 亿`,
    },
  },
  /** 展示总计 */
  total: {
    label'2020',
  },
  color: ({ month, value }) => {
    if (month === '2019' || month === '2020') {
      return '#96a6a6';
    }
    return value > 0 ? '#f4664a' : '#30bf78';
  },
  legend: {
    custom: true,
    items: [
      {
        name: 'Increase',
        value: 'increase',
        marker: { symbol: 'square', style: { r: 5, fill: '#f4664a' } },
      },
      {
        name: 'Decrease',
        value: 'decrease',
        marker: { symbol: 'square', style: { r: 5, fill: '#30bf78' } },
      },
      {
        name: 'Total',
        value: 'total',
        marker: { symbol: 'square', style: { r: 5, fill: '#96a6a6' } },
      },
    ],
  },
  label: {
    style: {
      fontSize: 10,
    },
    layout: [{ type: 'interval-adjust-position' }],
    background: {
      style: {
        fill: '#f6f6f6',
        stroke: '#e6e6e6',
        strokeOpacity: 0.65,
        radius: 2,
      },
      padding1.5,
    },
  },
  waterfallStyle: () => {
    return {
      fillOpacity: 0.85,
    };
  },
});

waterfallPlot.render();

瀑布图 - 数值标签展示绝对值

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

核心代码:

import { Waterfall } from '@antv/g2plot';

const data = [  { month: '一月', value: 6200000 },  { month: '二月', value: -600000 },  { month: '三月', value: -4100000 },  { month: '四月', value: 3700000 },  { month: '五月', value: -2100000 },  { month: '六月', value: 5300000 },  { month: '七月', value: 3100000 },  { month: '八月', value: -500000 },  { month: '九月', value: 4200000 },  { month: '十月', value: 5300000 },  { month: '十一月', value: -500000 },  { month: '十二月', value: 5100000 },];

const waterfallPlot = new Waterfall('container', {
  data,
  padding'auto',
  appendPadding: [20000],
  xField: 'month',
  yField: 'value',
  meta: {
    month: {
      alias: '月份',
    },
    value: {
      alias: '销售量',
      formatter: (v) => `${v / 10000000} 亿`,
    },
  },
  /** 展示总计 */
  total: {
    label'总计',
    style: {
      fill: '#96a6a6',
    },
  },
  /** 数据标签展示模式:绝对值 */
  labelMode: 'absolute',
  label: {
    style: {
      fontSize: 10,
    },
    background: {
      style: {
        fill: '#f6f6f6',
        radius: 1,
      },
      padding1.5,
    },
  },
});

waterfallPlot.render();

瀑布图 - 添加标注

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

核心代码:

import { Waterfall } from '@antv/g2plot';

const data = [
  { quarter: '第一季度', value: 6200000 },
  { quarter: '第二季度', value: -2600000 },
  { quarter: '第三季度', value: 4100000 },
  { quarter: '第四季度', value: 3700000 },
];

const formatter = (v) => `${v / 10000000} 亿`;

const annotations = [];
data.reduce((v, d) => {
  annotations.push({
    type'text',
    position: () => {
      const = v + d.value / 2;
      return [d.quarter, y];
    },
    content: formatter(d.value),
    style: {
      fontSize: 14,
      stroke: '#666',
      fill: '#fff',
      lineWidth: 1,
      textAlign: 'center',
      verticalAlign: 'middle',
    },
  });
  return v + d.value;
}, 0);

const waterfallPlot new Waterfall('container', {
  data,
  padding'auto',
  appendPadding: [20000],
  xField'quarter',
  yField'value',
  meta: {
    quarter: {
      alias'月份',
    },
    value: {
      alias'销售量',
      min0,
      formatter,
    },
  },
  /** 展示总计 */
  total: {
    label'总计',
    style: {
      fill'#96a6a6',
    },
  },
  /** 数据标签展示模式:绝对值 */
  labelMode'absolute',
  label: {
    style: {
      fontSize12,
    },
  },

  annotations,
});

waterfallPlot.render();

接下来,结合vue3

首先,创建相应的waterfall页面:

  • basic:基础瀑布图
  • change:变化瀑布图
  • label:数值标签
  • annotation:标注

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

改造后的页面结构: 在这里插入图片描述 改造后的页面效果: 在这里插入图片描述

vue3版基础瀑布图

核心代码:

import { Waterfall } from '@antv/g2plot';

const data = [  { type: '日用品', money: 120 },  { type: '伙食费', money: 900 },  { type: '交通费', money: 200 },  { type: '水电费', money: 300 },  { type: '房租', money: 1200 },  { type: '商场消费', money: 1000 },  { type: '红包收入', money: -2000 },];

const waterfallPlot = new Waterfall('container', {
  data,
  xField: 'type',
  yField: 'money',
  appendPadding: [15000],
  meta: {
    type: {
      alias: '类别',
    },
    money: {
      alias: '收支',
      formatter: (v) => `${v} 元`,
    },
  },
  label: {
    style: { fontSize: 10, fill: 'rgba(0,0,0,0.65)' },
    layout: [{ type: 'interval-adjust-position' }],
  },
  total: {
    label'总支出',
    style: {
      fill: '#96a6a6',
    },
  },
});

waterfallPlot.render();

实现基础瀑布图: 在这里插入图片描述

完整代码如下:

<script setup>
import {onMounted} from "vue";
import {Funnel, Waterfall} from "@antv/g2plot";


onMounted(async () => {
  const data = [
    { type'日用品', money120 },
    { type'伙食费', money900 },
    { type'交通费', money200 },
    { type'水电费', money300 },
    { type'房租', money1200 },
    { type'商场消费', money1000 },
    { type'红包收入', money: -2000 },
  ];

  const waterfallPlot = new Waterfall('container', {
    data,
    xField'type',
    yField'money',

    appendPadding: [15000],

    meta: {
      type: {
        alias'类别',
      },
      money: {
        alias'收支',
        formatter: (v) => `${v} 元`,
      },
    },

    label: {
      style: { fontSize10, fill'rgba(0,0,0,0.65)' },
      layout: [{ type'interval-adjust-position' }],
    },
    
    total: {
      label'总支出',
      style: {
        fill'#96a6a6',
      },
    },
  });

  waterfallPlot.render();

})

</script>

<template>
  <div id="container"></div>
</template>

vue3版变化瀑布图

核心代码:

import { Waterfall } from '@antv/g2plot';

const data = [  { month: '2019', value: 23000000 },  { month: 'Jan', value: 2200000 },  { month: 'Feb', value: -4600000 },  { month: 'Mar', value: -9100000 },  { month: 'Apr', value: 3700000 },  { month: 'May', value: -2100000 },  { month: 'Jun', value: 5300000 },  { month: 'Jul', value: 3100000 },  { month: 'Aug', value: -1500000 },  { month: 'Sep', value: 4200000 },  { month: 'Oct', value: 5300000 },  { month: 'Nov', value: -1500000 },  { month: 'Dec', value: 5100000 },];

const waterfallPlot = new Waterfall('container', {
  data,
  padding'auto',
  appendPadding: [20000],
  xField: 'month',
  yField: 'value',
  meta: {
    month: {
      alias: '月份',
    },
    value: {
      alias: '销售量',
      formatter: (v) => `${v / 10000000} 亿`,
    },
  },
  /** 展示总计 */
  total: {
    label'2020',
  },
  color: ({ month, value }) => {
    if (month === '2019' || month === '2020') {
      return '#96a6a6';
    }
    return value > 0 ? '#f4664a' : '#30bf78';
  },
  legend: {
    custom: true,
    items: [
      {
        name: 'Increase',
        value: 'increase',
        marker: { symbol: 'square', style: { r: 5, fill: '#f4664a' } },
      },
      {
        name: 'Decrease',
        value: 'decrease',
        marker: { symbol: 'square', style: { r: 5, fill: '#30bf78' } },
      },
      {
        name: 'Total',
        value: 'total',
        marker: { symbol: 'square', style: { r: 5, fill: '#96a6a6' } },
      },
    ],
  },
  label: {
    style: {
      fontSize: 10,
    },
    layout: [{ type: 'interval-adjust-position' }],
    background: {
      style: {
        fill: '#f6f6f6',
        stroke: '#e6e6e6',
        strokeOpacity: 0.65,
        radius: 2,
      },
      padding1.5,
    },
  },
  waterfallStyle: () => {
    return {
      fillOpacity: 0.85,
    };
  },
});

waterfallPlot.render();

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

完整代码如下:

<script setup>
import {onMounted} from "vue";
import {Funnel, Waterfall} from "@antv/g2plot";


onMounted(async () => {
  const data = [
    { month'2019', value23000000 },
    { month'Jan', value2200000 },
    { month'Feb', value: -4600000 },
    { month'Mar', value: -9100000 },
    { month'Apr', value3700000 },
    { month'May', value: -2100000 },
    { month'Jun', value5300000 },
    { month'Jul', value3100000 },
    { month'Aug', value: -1500000 },
    { month'Sep', value4200000 },
    { month'Oct', value5300000 },
    { month'Nov', value: -1500000 },
    { month'Dec', value5100000 },
  ];

  const waterfallPlot = new Waterfall('container', {
    data,
    padding'auto',
    appendPadding: [20000],
    xField'month',
    yField'value',

    meta: {
      month: {
        alias'月份',
      },
      value: {
        alias'销售量',
        formatter: (v) => `${v / 10000000} 亿`,
      },
    },
    /** 展示总计 */
    total: {
      label'2020',
    },
    color: ({ month, value }) => {
      if (month === '2019' || month === '2020') {
        return '#96a6a6';
      }
      return value > 0 ? '#f4664a' : '#30bf78';
    },
    
    legend: {
      custom: true,
      items: [
        {
          name: 'Increase',
          value: 'increase',
          marker: { symbol: 'square', style: { r: 5, fill: '#f4664a' } },
        },
        {
          name: 'Decrease',
          value: 'decrease',
          marker: { symbol: 'square', style: { r: 5, fill: '#30bf78' } },
        },
        {
          name: 'Total',
          value: 'total',
          marker: { symbol: 'square', style: { r: 5, fill: '#96a6a6' } },
        },
      ],
    },
    label: {
      style: {
        fontSize: 10,
      },
      layout: [{ type: 'interval-adjust-position' }],
      background: {
        style: {
          fill: '#f6f6f6',
          stroke: '#e6e6e6',
          strokeOpacity: 0.65,
          radius: 2,
        },
        padding: 1.5,
      },
    },
    waterfallStyle: () => {
      return {
        fillOpacity: 0.85,
      };
    },
  });

  waterfallPlot.render();
})

</script>

<template>
  <div id="container"></div>
</template>

vue3版数值标签

核心代码:

import { Waterfall } from '@antv/g2plot';

const data = [  { month: '一月', value: 6200000 },  { month: '二月', value: -600000 },  { month: '三月', value: -4100000 },  { month: '四月', value: 3700000 },  { month: '五月', value: -2100000 },  { month: '六月', value: 5300000 },  { month: '七月', value: 3100000 },  { month: '八月', value: -500000 },  { month: '九月', value: 4200000 },  { month: '十月', value: 5300000 },  { month: '十一月', value: -500000 },  { month: '十二月', value: 5100000 },];

const waterfallPlot = new Waterfall('container', {
  data,
  padding'auto',
  appendPadding: [20000],
  xField: 'month',
  yField: 'value',
  meta: {
    month: {
      alias: '月份',
    },
    value: {
      alias: '销售量',
      formatter: (v) => `${v / 10000000} 亿`,
    },
  },
  /** 展示总计 */
  total: {
    label'总计',
    style: {
      fill: '#96a6a6',
    },
  },
  /** 数据标签展示模式:绝对值 */
  labelMode: 'absolute',
  label: {
    style: {
      fontSize: 10,
    },
    background: {
      style: {
        fill: '#f6f6f6',
        radius: 1,
      },
      padding1.5,
    },
  },
});

waterfallPlot.render();

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

完整代码:

<script setup>
import {onMounted} from "vue";
import {Funnel, Waterfall} from "@antv/g2plot";


onMounted(async () => {

  const data = [
    { month'一月', value6200000 },
    { month'二月', value: -600000 },
    { month'三月', value: -4100000 },
    { month'四月', value3700000 },
    { month'五月', value: -2100000 },
    { month'六月', value5300000 },
    { month'七月', value3100000 },
    { month'八月', value: -500000 },
    { month'九月', value4200000 },
    { month'十月', value5300000 },
    { month'十一月', value: -500000 },
    { month'十二月', value5100000 },
  ];

  const waterfallPlot = new Waterfall('container', {
    data,
    padding'auto',
    appendPadding: [20000],
    xField'month',
    yField'value',
    meta: {
      month: {
        alias'月份',
      },
      value: {
        alias'销售量',
        formatter: (v) => `${v / 10000000} 亿`,
      },
    },
    /** 展示总计 */
    total: {
      label'总计',
      style: {
        fill'#96a6a6',
      },
    },

    /** 数据标签展示模式:绝对值 */
    labelMode'absolute',

    label: {
      style: {
        fontSize10,
      },
      background: {
        style: {
          fill'#f6f6f6',
          radius1,
        },
        padding1.5,
      },
    },
  });

  waterfallPlot.render();
})

</script>

<template>
  <div id="container"></div>
</template>

vue3版添加标注

核心代码:

import { Waterfall } from '@antv/g2plot';

const data = [
  { quarter: '第一季度', value: 6200000 },
  { quarter: '第二季度', value: -2600000 },
  { quarter: '第三季度', value: 4100000 },
  { quarter: '第四季度', value: 3700000 },
];

const formatter = (v) => `${v / 10000000} 亿`;

const annotations = [];
data.reduce((v, d) => {
  annotations.push({
    type'text',
    position: () => {
      const = v + d.value / 2;
      return [d.quarter, y];
    },
    content: formatter(d.value),
    style: {
      fontSize: 14,
      stroke: '#666',
      fill: '#fff',
      lineWidth: 1,
      textAlign: 'center',
      verticalAlign: 'middle',
    },
  });
  return v + d.value;
}, 0);

const waterfallPlot new Waterfall('container', {
  data,
  padding'auto',
  appendPadding: [20000],
  xField'quarter',
  yField'value',
  meta: {
    quarter: {
      alias'月份',
    },
    value: {
      alias'销售量',
      min0,
      formatter,
    },
  },
  /** 展示总计 */
  total: {
    label'总计',
    style: {
      fill'#96a6a6',
    },
  },
  /** 数据标签展示模式:绝对值 */
  labelMode'absolute',
  label: {
    style: {
      fontSize12,
    },
  },

  annotations,
});

waterfallPlot.render();

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

完整代码:

<script setup>
import {onMounted} from "vue";
import {Funnel, Waterfall} from "@antv/g2plot";


onMounted(async () => {

  const data = [
    { quarter'第一季度', value6200000 },
    { quarter'第二季度', value: -2600000 },
    { quarter'第三季度', value4100000 },
    { quarter'第四季度', value3700000 },
  ];

  const formatter = (v) => `${v / 10000000} 亿`;

  // 标注
  const annotations = [];
  data.reduce((v, d) => {
    annotations.push({
      type'text',
      position: () => {
        const = v + d.value / 2;
        return [d.quarter, y];
      },
      content: formatter(d.value),
      style: {
        fontSize: 14,
        stroke: '#666',
        fill: '#fff',
        lineWidth: 1,
        textAlign: 'center',
        verticalAlign: 'middle',
      },
    });
    return v + d.value;
  }, 0);

  const waterfallPlot new Waterfall('container', {
    data,
    padding'auto',
    appendPadding: [20000],
    xField'quarter',
    yField'value',
    meta: {
      quarter: {
        alias'月份',
      },
      value: {
        alias'销售量',
        min0,
        formatter,
      },
    },
    /** 展示总计 */
    total: {
      label'总计',
      style: {
        fill'#96a6a6',
      },
    },
    /** 数据标签展示模式:绝对值 */
    labelMode'absolute',
    label: {
      style: {
        fontSize12,
      },
    },

    annotations,
  });

  waterfallPlot.render();
})

</script>

<template>
  <div id="container"></div>
</template>

总结

本教程讲解了Vue3如何结合g2plot绘制瀑布图,并实际讲解了四个实战案例。

完整代码如下: 在这里插入图片描述

打赏3元即可获取完整代码。

也配套录制了完整的视频教程: 在这里插入图片描述

人生苦短,我用Python,我是您身边的Python私教,有任何Python相关的问题,请随时留言,我愿意献上绵薄之力,为您排忧解难!!!

本文使用 markdown.com.cn 排版