在vue中使用antV-G2展示基础漏斗图

  介绍

在vue中使用antV-G2展示基础漏斗图

G2 是一套基于图形语法理论的可视化底层引擎,以数据驱动,提供图形语法与交互语法,具有高度的易用性和扩展性。使用 G2,你可以无需关注图表各种繁琐的实现细节,一条语句即可使用 Canvas 或 SVG 构建出各种各样的可交互的统计图表。

一、安装 antV-G2

通过 npm 安装

npm install @antv/g2 --save

成功安装完成之后,即可使用 import 或 require 进行引用。

import { Chart } from '@antv/g2';

浏览器引入

既可以通过将脚本下载到本地也可以直接引入在线资源:

<!-- 引入在线资源,选择你需要的 g2 版本以替换 version 变量 -->
<script src="https://gw.alipayobjects.com/os/lib/antv/g2/{{version}}/dist/g2.min.js"></script>
<!-- 引入本地脚本 -->
<script src="./g2.js"></script>

使用 script 标签引入 G2 资源时,挂载在 window 上的变量名为 G2,所以在上述实例中需要加上 G2 的前缀。如下:

const chart = new G2.Chart({
  /* your options */
});

二、在vue中使用antV-G2展示柱状图

创建 div 图表容器

//html布局
<template>
<div class="container" id="container"></div>
</template>

//对应的CSS样式
<style lang="scss">
body{ background: #222;}
.container{width:800px; height: 800px; margin: 100px auto;}
</style>

在data(){}中准备好将要展示的图表数据

data(){
    return {
        chart:null,//图表对象
        showData:[//图表中将要显示的数据
                    {
                        "year": "1951 年",
                        "sales": 38
                    },
                    {
                        "year": "1952 年",
                        "sales": 52
                    },
                    {
                        "year": "1956 年",
                        "sales": 61
                    },
                    {
                        "year": "1957 年",
                        "sales": 145
                    },
                    {
                        "year": "1958 年",
                        "sales": 48
                    },
                    {
                        "year": "1959 年",
                        "sales": 38
                    }
                ],
    }
},

创建chart

//创建chart
createChart(){
    this.chart = new Chart({
        container: 'container',//chart容器id
        autoFit: false,//图表是否自适应容器宽高,默认为 false
        width: 800,//图标宽度
        height: 400,//图表高度
        padding: [40, 140, 80, 140],//图表内边距,依次为:上,右,下,左
        // defaultInteractions:"ellipsis-text",//配置图表默认交互,仅支持字符串形式。G2 默认支持的交互有 'tooltip', 'legend-filter', 'legend-active', 'continuous-filter', 'ellipsis-text'
        pixelRatio:window.devicePixelRatio,//设置设备像素比,默认取浏览器的值 window.devicePixelRatio
        renderer:"canvas",//指定渲染引擎,默认使用 canvas。可选:'canvas' | 'svg'
        theme:"dark",//配置主题,目前 g2 默认有 dark 主题模式,如需要自定义配置,可以先通过 registerTheme 注册主题,再设置主题 key。
        visible:true,//chart 是否可见,默认为 true,设置为 false 则会隐藏。
    });
},

设置展示数据 showData

//设置数据
setChartData(){
    /*加入字段:percent*/
    //获得 Y轴字段的最大值
    var max=this.getMaxOfKey(this.showData,"sales");
    //计算出 percent 百分比
    for(var i=0;i<this.showData.length;i++){
        this.showData[i]['percent']=this.showData[i]["sales"]/max;
    }
    //对showData 进行降序排列
    this.sortJson(this.showData,"sales","DESC");
    this.chart.data(this.showData);
},
//获得某个字段的最大值
getMaxOfKey(arr,field){
    var max=null;
    for (let i = 0; i < arr.length; i++) {
        var obj = arr[i];
        if(max==null){
            max=obj[field];
        }else{
            max=max>=obj[field]?max:obj[field];
        }
    }
    max=max==null?1:max;
    return max;
},
//json对象数组按对象属性排序 
sortJson(arr,field,type="ASC"){
    arr.sort(function(a,b){
        if(type=="ASC"){
            return a[field]-b[field];
        }else{
            return b[field]-a[field];
        }
    });
},

设置坐标轴

//设置坐标轴
setChartAxis(){
    //设置x Y轴
    this.chart.axis(false);
},

设置提示框信息样式

//设置提示框信息样式
setChartTooltip(){

    var yField="sales";
    
    this.chart.tooltip({
        showTitle: false,
        showMarkers: false,
        domStyles:{
            'g2-tooltip':{
                background:"rgba(00, 00, 00,0.5)",//背景RGBA形式的值
                color:"#ffffff",//文字颜色
                boxShadow:"0px 0px 5px #000000",//阴影大小 阴影颜色 
            },
        },
        itemTpl:
        '<li style="margin-bottom:4px;list-style-type:none;padding: 0;">' +
        '<span style="background-color:{color};" class="g2-tooltip-marker"></span>' +
        '{'+'year'+'}<br/>' +
        '<span style="padding-left: 16px;line-height: 16px;">'+yField+':{'+yField+'}</span><br/>' +
        '<span style="padding-left: 16px;line-height: 16px;">'+"百分比"+':{'+"percent"+'}</span><br/>' +
        '</li>',
    });
},

设置图表样式

this.chart.interaction('element-active');//设置图表样式

设置图表漏斗相关属性【漏斗样式】

//设置图表漏斗相关属性【漏斗样式】
setChartStyle(){

    this.chart
    .coordinate('rect')
    .transpose()
    .scale(1, -1);

    var line=this.chart.interval();
    
    line.adjust('symmetric').state({
    // selected:{
    //   style:{
    //     stroke:'red',
    //   }
    // }
    active:{
        style:{
        stroke:"#2681ff",//鼠标经过 边框颜色
        }
    }
    })
    .position("year"+"*"+"percent")//X轴 * 百分比字段
    .shape('funnel')
    .color("year", ["#2681ff","#00ff44","#2611ff","#26aa99"]);//参数1:year字段为X轴,参数2:颜色数组,柱体的颜色会循环的从颜色数组中取出来

    //柱子上是否显示值标签
    //line.label(false);//不需要显示,可以设置false
    line.label("sales", {//标签值
            content: (originData) => {
                return originData["year"]+" "+originData["sales"]+"万";//设置值标签最终显示的内容
            },
            style: {
                fill: "#fff",
                fontFamily: "Microsoft YaHei",
                fontWeight: 400,
                fontSize: 16,
                // fill: "#ffffff",
            },
            position:"middle",//显示位置
        })
    //提示文字
    line.tooltip("year"+"*"+"sales"+"*percent",(xField, yField, percent) => {
        // console.log("tooltip")
        // console.log(xField)
        // console.log(yField)
        // console.log(percent)
        var obj={};
        obj["year"]=xField;
        obj["sales"]=yField;
        obj.percent=parseInt(percent * 100) + '%';
        return obj;
    })
    .animate({
        appear: {
        animation: 'fade-in'
        },
        update: {
        annotation: 'fade-in'
        }
    });
},

 设置图例

//设置图例
setChartLegend(){

    // this.chart.legend(false);//设置为false,表示不显示图例

    this.chart.legend("year", {
        position: "bottom",//图例位置:"top" | "top-left" | "top-right" | "right" | "right-top" | "right-bottom" | "left" | "left-top" | "left-bottom" | "bottom" | "bottom-left" | "bottom-right"
        itemName:{
            style:{
                fill: "#fff",
                fontFamily: "Microsoft YaHei",
                fontWeight: 400,
                fontSize: 16,
            }
        },
        pageNavigator: {
            marker: {//分页器指示箭头配置项
                style: {
                    // 非激活,不可点击态时的填充色设置
                    inactiveFill: "#fff",//分页器:箭头颜色
                    inactiveOpacity: 1,//分页器:箭头透明度
                    // 默认填充色设置
                    fill: "#fff",//分页器:颜色
                    opacity: 1,//分页器:透明度
                    size: 12,//分页器:大小
                },
            },
            text: {//分页器指示文本配置项
                style: {
                    fill: "#fff",//分页器:文本颜色
                    fontSize: 12,//分页器:文本大小
                },
            },
        },
    });
},

 设置中间标题文本

//设置中间标题文本
setChartCenterText(){
    
    var _this=this;
    _this.chart.on('beforepaint', () => {
    _this.chart.annotation().clear(true);
    const chartData = _this.chart.getData();
    // 中间标签文本
    chartData.forEach((obj) => {
        var position={};
        position["year"]=obj["year"];
        position["percent"]="end";

        _this.chart.annotation().text({
        top: true,
        // position: ['50%','50%'],
        position: position,
        content: parseInt(obj.percent * 100) + '%', // 显示的文本内容
        style: {
            stroke: null,
            fill: '#fff',
            textAlign: 'center',
        },
        });
    });
    });
},

设置动画

//设置动画
setChartAnimate(){
    
    // this.chart.animate(false);//设置为false,表示不使用动画效果

    this.chart.animate({
        // 初始化时的入场动画
        appear: {
            animation: 'fade-in', // 动画名称:'fade-in'|'fan-in'|'scale-inx'|'scale-iny'|'path-in'|'zoom-in'|'clip-in'
            easing: 'easeQuadIn', // 动画缓动效果
            delay: 100, // 动画延迟执行时间
            duration: 600 // 动画执行时间
        },
        // 更新时的出现动画
        enter: {
            animation: 'fade-in', //动画名称:'fade-in'|'fan-in'|'scale-inx'|'scale-iny'|'path-in'|'zoom-in'|'clip-in'
            easing: 'easeQuadIn', // 动画缓动效果
            delay: 100, // 动画延迟执行时间
            duration: 600 // 动画执行时间
        },
        // 更新时的动画
        leave: {
            animation: 'path-out', //动画名称:'fade-out'|'path-out'|'zoom-out'|'lineWidth-out'
            easing: 'easeQuadIn', // 动画缓动效果
            delay: 100, // 动画延迟执行时间
            duration: 600 // 动画执行时间
        },
        // 更新时的变化动画
        update: {
            animation: 'fade-in', //动画名称:'fade-in'|'fan-in'
            easing: 'easeQuadIn', // 动画缓动效果
            delay: 100, // 动画延迟执行时间
            duration: 600 // 动画执行时间
        },
    })
},

渲染图表

//渲染图表
this.chart.render();

三、效果预览

 

 四、完整vue代码文件

<template>
<div class="container" id="container"></div>
</template>
<script>
import { Chart } from '@antv/g2';

//柱状图
export default {
  components: {},
    name:"test",
    data(){
        return {
            chart:null,//图表对象
            showData:[//图表中将要显示的数据
                        {
                            "year": "1951 年",
                            "sales": 38
                        },
                        {
                            "year": "1952 年",
                            "sales": 52
                        },
                        {
                            "year": "1956 年",
                            "sales": 61
                        },
                        {
                            "year": "1957 年",
                            "sales": 145
                        },
                        {
                            "year": "1958 年",
                            "sales": 48
                        },
                        {
                            "year": "1959 年",
                            "sales": 38
                        }
                    ],
        }
    },
    created(){
        
    },
    mounted(){
        this.init();
    },
    methods:{
        // 初始化
        init(){
            
            this.createChart();//创建chart
            this.setChartData();//设置字段和数据

            this.setChartAxis();//设置坐标轴和度量
            this.setChartTooltip();//设置提示信息

            this.chart.interaction('element-active');//设置图表样式

            this.setChartStyle();//设置图表柱子相关属性
            // this.chart.legend(false);//设置为false,表示不显示图例
            this.setChartLegend();//设置图例
            this.setChartCenterText(); //中间标签文本
            this.setChartAnimate();//设置动画
            //渲染图表
            this.chart.render();
            //添加点击事件
            this.addClickEvent();
            
        },
        //创建chart
        createChart(){
            this.chart = new Chart({
                container: 'container',//chart容器id
                autoFit: false,//图表是否自适应容器宽高,默认为 false
                width: 800,//图标宽度
                height: 400,//图表高度
                padding: [40, 140, 80, 140],//图表内边距,依次为:上,右,下,左
                // defaultInteractions:"ellipsis-text",//配置图表默认交互,仅支持字符串形式。G2 默认支持的交互有 'tooltip', 'legend-filter', 'legend-active', 'continuous-filter', 'ellipsis-text'
                pixelRatio:window.devicePixelRatio,//设置设备像素比,默认取浏览器的值 window.devicePixelRatio
                renderer:"canvas",//指定渲染引擎,默认使用 canvas。可选:'canvas' | 'svg'
                theme:"dark",//配置主题,目前 g2 默认有 dark 主题模式,如需要自定义配置,可以先通过 registerTheme 注册主题,再设置主题 key。
                visible:true,//chart 是否可见,默认为 true,设置为 false 则会隐藏。
            });
        },
        //设置数据
        setChartData(){
            /*加入字段:percent*/
            //获得 Y轴字段的最大值
            var max=this.getMaxOfKey(this.showData,"sales");
            //计算出 percent 百分比
            for(var i=0;i<this.showData.length;i++){
                this.showData[i]['percent']=this.showData[i]["sales"]/max;
            }
            //对showData 进行降序排列
            this.sortJson(this.showData,"sales","DESC");
            this.chart.data(this.showData);
        },
        //获得某个字段的最大值
        getMaxOfKey(arr,field){
            var max=null;
            for (let i = 0; i < arr.length; i++) {
                var obj = arr[i];
                if(max==null){
                    max=obj[field];
                }else{
                    max=max>=obj[field]?max:obj[field];
                }
            }
            max=max==null?1:max;
            return max;
        },
        //json对象数组按对象属性排序 
        sortJson(arr,field,type="ASC"){
            arr.sort(function(a,b){
                if(type=="ASC"){
                    return a[field]-b[field];
                }else{
                    return b[field]-a[field];
                }
            });
        },
        //设置坐标轴
        setChartAxis(){
            //设置x Y轴
            this.chart.axis(false);
        },
        //设置提示框信息样式
        setChartTooltip(){

            var yField="sales";
            
            this.chart.tooltip({
                showTitle: false,
                showMarkers: false,
                domStyles:{
                    'g2-tooltip':{
                        background:"rgba(00, 00, 00,0.5)",//背景RGBA形式的值
                        color:"#ffffff",//文字颜色
                        boxShadow:"0px 0px 5px #000000",//阴影大小 阴影颜色 
                    },
                },
                itemTpl:
                '<li style="margin-bottom:4px;list-style-type:none;padding: 0;">' +
                '<span style="background-color:{color};" class="g2-tooltip-marker"></span>' +
                '{'+'year'+'}<br/>' +
                '<span style="padding-left: 16px;line-height: 16px;">'+yField+':{'+yField+'}</span><br/>' +
                '<span style="padding-left: 16px;line-height: 16px;">'+"百分比"+':{'+"percent"+'}</span><br/>' +
                '</li>',
            });
        },
        //设置图表漏斗相关属性【漏斗样式】
        setChartStyle(){

            this.chart
            .coordinate('rect')
            .transpose()
            .scale(1, -1);

            var line=this.chart.interval();
            
            line.adjust('symmetric').state({
            // selected:{
            //   style:{
            //     stroke:'red',
            //   }
            // }
            active:{
                style:{
                stroke:"#2681ff",//鼠标经过 边框颜色
                }
            }
            })
            .position("year"+"*"+"percent")//X轴 * 百分比字段
            .shape('funnel')
            .color("year", ["#2681ff","#00ff44","#2611ff","#26aa99"]);//参数1:year字段为X轴,参数2:颜色数组,柱体的颜色会循环的从颜色数组中取出来

            //柱子上是否显示值标签
            //line.label(false);//不需要显示,可以设置false
            line.label("sales", {//标签值
                    content: (originData) => {
                        return originData["year"]+" "+originData["sales"]+"万";//设置值标签最终显示的内容
                    },
                    style: {
                        fill: "#fff",
                        fontFamily: "Microsoft YaHei",
                        fontWeight: 400,
                        fontSize: 16,
                        // fill: "#ffffff",
                    },
                    position:"middle",//显示位置
                })
            //提示文字
            line.tooltip("year"+"*"+"sales"+"*percent",(xField, yField, percent) => {
                // console.log("tooltip")
                // console.log(xField)
                // console.log(yField)
                // console.log(percent)
                var obj={};
                obj["year"]=xField;
                obj["sales"]=yField;
                obj.percent=parseInt(percent * 100) + '%';
                return obj;
            })
            .animate({
                appear: {
                animation: 'fade-in'
                },
                update: {
                annotation: 'fade-in'
                }
            });
        },
        //设置图例
        setChartLegend(){

            // this.chart.legend(false);//设置为false,表示不显示图例

            this.chart.legend("year", {
                position: "bottom",//图例位置:"top" | "top-left" | "top-right" | "right" | "right-top" | "right-bottom" | "left" | "left-top" | "left-bottom" | "bottom" | "bottom-left" | "bottom-right"
                itemName:{
                    style:{
                        fill: "#fff",
                        fontFamily: "Microsoft YaHei",
                        fontWeight: 400,
                        fontSize: 16,
                    }
                },
                pageNavigator: {
                    marker: {//分页器指示箭头配置项
                        style: {
                            // 非激活,不可点击态时的填充色设置
                            inactiveFill: "#fff",//分页器:箭头颜色
                            inactiveOpacity: 1,//分页器:箭头透明度
                            // 默认填充色设置
                            fill: "#fff",//分页器:颜色
                            opacity: 1,//分页器:透明度
                            size: 12,//分页器:大小
                        },
                    },
                    text: {//分页器指示文本配置项
                        style: {
                            fill: "#fff",//分页器:文本颜色
                            fontSize: 12,//分页器:文本大小
                        },
                    },
                },
            });
        },
        //设置中间标题文本
        setChartCenterText(){
            
            var _this=this;
            _this.chart.on('beforepaint', () => {
            _this.chart.annotation().clear(true);
            const chartData = _this.chart.getData();
            // 中间标签文本
            chartData.forEach((obj) => {
                var position={};
                position["year"]=obj["year"];
                position["percent"]="end";

                _this.chart.annotation().text({
                top: true,
                // position: ['50%','50%'],
                position: position,
                content: parseInt(obj.percent * 100) + '%', // 显示的文本内容
                style: {
                    stroke: null,
                    fill: '#fff',
                    textAlign: 'center',
                },
                });
            });
            });
        },
        //设置动画
        setChartAnimate(){
            
            // this.chart.animate(false);//设置为false,表示不使用动画效果

            this.chart.animate({
                // 初始化时的入场动画
                appear: {
                    animation: 'fade-in', // 动画名称:'fade-in'|'fan-in'|'scale-inx'|'scale-iny'|'path-in'|'zoom-in'|'clip-in'
                    easing: 'easeQuadIn', // 动画缓动效果
                    delay: 100, // 动画延迟执行时间
                    duration: 600 // 动画执行时间
                },
                // 更新时的出现动画
                enter: {
                    animation: 'fade-in', //动画名称:'fade-in'|'fan-in'|'scale-inx'|'scale-iny'|'path-in'|'zoom-in'|'clip-in'
                    easing: 'easeQuadIn', // 动画缓动效果
                    delay: 100, // 动画延迟执行时间
                    duration: 600 // 动画执行时间
                },
                // 更新时的动画
                leave: {
                    animation: 'path-out', //动画名称:'fade-out'|'path-out'|'zoom-out'|'lineWidth-out'
                    easing: 'easeQuadIn', // 动画缓动效果
                    delay: 100, // 动画延迟执行时间
                    duration: 600 // 动画执行时间
                },
                // 更新时的变化动画
                update: {
                    animation: 'fade-in', //动画名称:'fade-in'|'fan-in'
                    easing: 'easeQuadIn', // 动画缓动效果
                    delay: 100, // 动画延迟执行时间
                    duration: 600 // 动画执行时间
                },
            })
        },
        //添加点击事件
        addClickEvent(){
            this.chart.on('element:click', (ev) => {
                var data=ev.data.data;
                console.log(data);
                alert(JSON.stringify(data));
            });
        }
    },
}
</script>

<style lang="scss">
body{ background: #222;}
.container{width:800px; height: 800px; margin: 100px auto; background: cadetblue;}
</style>

数据可视化工具推荐

基于VUE实现拖拽制作数据可视化大屏

基于SpringBoot+Vue3+mysql开发,支持多种数据源:excel、api接口、mysql、oracle、SqlServer等多种类型的数据源,支持数据模型转换,图形化编辑界面:拖拽即可完成大屏制作和数据配置,无需编程就能轻松搭建数据大屏。私有化部署:使用私有化部署的方式,保障贵公司的数据安全,数据大屏支持加密发布

界面展示

  1. 大屏编辑界面 

    (https://www.51qingtian.com)
  2. 可视化大屏 

    (https://www.51qingtian.com)
  3. 数据模型 

    (https://www.51qingtian.com)
  4. 数据源 

    (https://www.51qingtian.com)

模板展示

  1. 健身数据报告

(https://www.51qingtian.com)

  1. 智慧园区数据统计中心

(https://www.51qingtian.com)

  1. 交通安全主题

(https://www.51qingtian.com)

  1. 财务数据大屏

(https://www.51qingtian.com)

  1. 智慧医疗大数据可视化大屏

(https://www.51qingtian.com)

官网

  1. 情天数据可视化 www.51qingtian.com
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值