Echarts目标与达成柱状图

763 阅读1分钟

有个需求,有A、B、C、D四个组,每个组又有几个小组,要展示每个小组的目标与完成值对比。

一、最直接的就是下边这种方式。

代码如下:

<template>    <div>        <div id="main" style="width: 100%;height:600px;"></div>    </div></template><script lang="ts">import {    defineComponent,    onMounted,} from 'vue'import * as echarts from 'echarts';export default defineComponent({    setup(props) {        const initCharts = () => {            var chartDom = document.getElementById('main');            if (!chartDom) return            let myChart = echarts.init(chartDom);            var option;            option = {                legend: {},                tooltip: {                    trigger: 'axis',                    axisPointer: {                        type: 'shadow'                    }                },                xAxis: {                    type: 'category',                    data: ['a', 'b', 'c', 'd'],                    // axisTick: { show: false },                    // axisLabel: {                    //     formatter: "barGap: '-100%'"                    // }                },                yAxis: {                    //     splitLine: { show: false }                },                // animationDurationUpdate: 1200,                series: [                    {                        type: 'bar',                        itemStyle: {                            normal: {                                color: '#ddd'                            }                        },                        name: '完成',                        data: [10, 40, 50, 80]                    },                    {                        type: 'bar',                        name: '目标',                        itemStyle: {                            normal: {                                color: 'green'                            }                        },                        data: [20, 30, 60, 70]                    },                    {                        type: 'bar',                        itemStyle: {                            normal: {                                color: '#ddd'                            }                        },                        name: '完成',                        data: [10, 40, 50, 80]                    },                    {                        type: 'bar',                        silent: true,                        name: '目标',                        itemStyle: {                            normal: {                                color: 'green'                            }                        },                        data: [20, 30, 60, 70]                    },                ]            };            option && myChart.setOption(option);            window.addEventListener("resize", () => {                myChart.resize();            });        }        onMounted(() => {            initCharts()        })    }})</script>

二、但是有时候需求需要我们把小组的目标与完成柱子叠加在一起。我们可以使用堆叠柱状图。

代码如下:

<template>    <div>        <div id="main" style="width: 100%;height:400px;"></div>    </div></template><script lang="ts">import {    defineComponent,    onMounted,} from 'vue'import * as echarts from 'echarts';export default defineComponent({    setup(props) {        const initCharts = () => {            var chartDom = document.getElementById('main');            if (!chartDom) return            let myChart = echarts.init(chartDom);            var option;             option = {                legend: {},                tooltip: {},                dataset: {                    source: [                        ['product', '杯赛完成', '杯赛目标', 'SAAS完成','SASS目标','官网完成','官网目标'],                        ['一季度', 43.3, 100, 93.7,100, 85.8, 93.7],                        ['二季度', 83.1, 100, 55.1,100, 85.8, 93.7],                        ['三季度', 86.4, 100, 82.5,100, 85.8, 93.7],                        ['四季度', 72.4, 100, 39.1,100, 85.8, 93.7]                    ]                },                xAxis: { type: 'category' },                yAxis: {},                series: [{ type: 'bar',color:'#f00',barGap: 7,z:11,barWidth: 40, }, { type: 'bar',color:'gray',barWidth: 40, }, { type: 'bar',color:'#0f0',barGap: '-100%',z:12,barWidth: 40, },{ type: 'bar',color:'yellow',barWidth: 40, }]                // series: [{ type: 'bar',color:'#f00',barGap: '-10%', }, { type: 'bar',color:'gray' }, { type: 'bar',color:'#f00',barGap: '-100%', },{ type: 'bar',color:'gray' }, { type: 'bar',color:'#f00',barGap: '-100%', }, { type: 'bar',color:'gray' }]            };                       option && myChart.setOption(option);            window.addEventListener("resize", () => {                myChart.resize();            });        }        onMounted(() => {            initCharts()        })    }})</script>

也有横向的

<template>    <div>        <div id="main" style="width: 100%;height:400px;"></div>    </div></template><script lang="ts">import {    defineComponent,    onMounted,} from 'vue'import * as echarts from 'echarts';export default defineComponent({    setup(props) {        const initCharts = () => {            var chartDom = document.getElementById('main');            if (!chartDom) return            let myChart = echarts.init(chartDom);            var option;            option = {                tooltip: {                    trigger: 'axis',                    axisPointer: {                        // Use axis to trigger tooltip                        type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'                    }                },                legend: {},                grid: {                    left: '3%',                    right: '4%',                    bottom: '3%',                    containLabel: true                },                xAxis: {                    type: 'value'                },                yAxis: {                    type: 'category',                    data: ['全年']                },                series: [                    {                        name: 'Direct',                        type: 'bar',                        stack: 'total',                        label: {                            show: true                        },                        emphasis: {                            focus: 'series'                        },                        data: [320]                    },                    {                        name: 'Mail Ad',                        type: 'bar',                        stack: 'total',                        label: {                            show: true                        },                        emphasis: {                            focus: 'series'                        },                        data: [120]                    },                    {                        name: 'Affiliate Ad',                        type: 'bar',                        stack: 'total1',                        label: {                            show: true                        },                        emphasis: {                            focus: 'series'                        },                        data: [220]                    },                    {                        name: 'Video Ad',                        type: 'bar',                        stack: 'total1',                        label: {                            show: true                        },                        emphasis: {                            focus: 'series'                        },                        data: [150]                    },                    {                        name: 'Search Engine',                        type: 'bar',                        stack: 'total2',                        label: {                            show: true                        },                        emphasis: {                            focus: 'series'                        },                        data: [820]                    },                    {                        name: 'Search Engine',                        type: 'bar',                        stack: 'total2',                        label: {                            show: true                        },                        emphasis: {                            focus: 'series'                        },                        data: [620]                    },                ]            };            option && myChart.setOption(option);            window.addEventListener("resize", () => {                myChart.resize();            });        }        onMounted(() => {            initCharts()        })    }})</script>

这个图的缺点就是叠加时候每一个叠加是在上一个数值基础上叠加的,目标值与实际完成值的差值体现的不明显。

三、看到官网上提供了一种移动坐标轴的案例。

代码如下:

<template>    <div>        <div id="main" style="width: 100%;height:400px;"></div>    </div></template><script lang="ts">import {    defineComponent,    onMounted,} from 'vue'import * as echarts from 'echarts';export default defineComponent({    setup(props) {        const initCharts = () => {            var chartDom = document.getElementById('main');            if (!chartDom) return            let myChart = echarts.init(chartDom);            var option;            option = {                legend: {},                tooltip: {},                xAxis: {                    type: 'category',                    data: ['a', 'b', 'c', 'd'],                    // axisTick: { show: false },                    // axisLabel: {                    //     formatter: "barGap: '-100%'"                    // }                },                yAxis: {                    //     splitLine: { show: false }                },                // animationDurationUpdate: 1200,                series: [                    {                        type: 'bar',                        itemStyle: {                            normal: {                                color: '#ddd'                            }                        },                        silent: true,                        barWidth: 40,                        barGap: '-100%',                        data: [60, 60, 60, 60]                    },                    {                        type: 'bar',                        silent: true,                        barWidth: 40,                        z: 10,                        data: [45, 60, 13, 25]                    }                ]            };            option && myChart.setOption(option);            window.addEventListener("resize", () => {                myChart.resize();            });        }        onMounted(() => {            initCharts()        })    }})</script>

但是这种方法有弊端,首先层级没法确定,可能出现其中一个数据覆盖另一个小的数据,然后就是每一组只能展示一组数据,对多组数据也都会重叠在一起。

详细地址:echarts.apache.org/handbook/zh…

四、有一种是可以满足上述需求的。

代码如下:

<template>    <div>        <div id="main" style="width: 100%;height:400px;"></div>    </div></template><script lang="ts">import {    defineComponent,    onMounted,} from 'vue'import * as echarts from 'echarts';export default defineComponent({    setup(props) {        const initCharts = () => {            var chartDom = document.getElementById('main');            if (!chartDom) return            let myChart = echarts.init(chartDom);            var option;            //下面就是上图的配置项,关键部分有注释            option = {                title: {                    text: '业绩报表'                },                tooltip: {                    trigger: 'axis',                    axisPointer: {                        type: 'shadow'                    }                },                legend: {},                grid: {                    left: '3%',                    right: '4%',                    bottom: '3%',                    containLabel: true                },                xAxis: {                    type: 'category',                    data: ['周一', '周二', '周三', '周四', '周五']                },                yAxis: {                    type: 'value',                    boundaryGap: [0, 0.01]                },                series: [                    {//里层的柱子                        name: '销售部A组',                        type: 'pictorialBar',//象形柱状图                        barWidth: 30,//柱子的宽度                        data: [72, 109, 70, 67, 59],//柱子的数据                        symbol: 'circle',//柱子的形状                        symbolRepeat: true,//是否重复                        symbolOffset: [-30, 0],//柱子的位置                        symbolBoundingData: 1,//图形的个数                        z: 12//柱子的层级                    },                    { //外层的柱子                        name: "销售部B组",                        type: "pictorialBar",                        barWidth: 50,                        //symbolSize: [40, 18], //调整截面形状                        symbolOffset: [-40, 0],                        symbol: 'circle',                        symbolRepeat: true,                        symbolBoundingData: 1,                        itemStyle: {                            color: ''                        },                        data: [82, 89, 90, 97, 79]                    },                    {//里面的柱子                        name: '营销部A组',                        type: 'pictorialBar',                        data: [73, 80, 71, 75, 64],                        barWidth: 30,                        symbol: 'circle',                        symbolRepeat: true,                        symbolOffset: [40, 0],                        symbolBoundingData: 1,                        z: 12                    },                    { //外面的柱子                        name: "营销部B组",                        type: "pictorialBar",                        barWidth: 50,                        //symbolSize: [40, 18], //调整截面形状                        symbolOffset: [30, 0],                        symbol: 'circle',                        symbolRepeat: true,                        symbolBoundingData: 1,                        itemStyle: {                            color: ''                        },                        data: [82, 89, 89, 97, 79]                    },                ]            };            option && myChart.setOption(option);            window.addEventListener("resize", () => {                myChart.resize();            });        }        onMounted(() => {            initCharts()        })    }})</script>

通过设置柱子粗细就不会有覆盖问题了。

参考文章:blog.csdn.net/m0_52313178…

五、最后无意间看到一个很好看的折线图柱状图混合的图,对每组只有一组数据适用。

代码如下:

<template>    <div>        <div id="main" style="width: 100%;height:400px;"></div>    </div></template><script lang="ts">import {    defineComponent,    onMounted,} from 'vue'import * as echarts from 'echarts';export default defineComponent({    setup(props) {        const initCharts = () => {            var chartDom = document.getElementById('main');            if (!chartDom) return            let myChart = echarts.init(chartDom);            var option;            let category = [];            let dottedBase = +new Date();            let lineData = [];            let barData = [];            for (let i = 0; i < 20; i++) {                let date = new Date((dottedBase += 3600 * 24 * 1000));                category.push(                    [date.getFullYear(), date.getMonth() + 1, date.getDate()].join('-')                );                let b = Math.random() * 200;                let d = Math.random() * 200;                barData.push(b);                lineData.push(d + b);            }            option = {                backgroundColor: '#0f375f',                tooltip: {                    trigger: 'axis',                    axisPointer: {                        type: 'shadow'                    }                },                legend: {                    data: ['line', 'bar'],                    textStyle: {                        color: '#ccc'                    }                },                xAxis: {                    data: category,                    axisLine: {                        lineStyle: {                            color: '#ccc'                        }                    }                },                yAxis: {                    splitLine: { show: false },                    axisLine: {                        lineStyle: {                            color: '#ccc'                        }                    }                },                series: [                    {                        name: 'line',                        type: 'line',                        smooth: true,                        showAllSymbol: true,                        symbol: 'emptyCircle',                        symbolSize: 15,                        data: lineData                    },                    {                        name: 'bar',                        type: 'bar',                        barWidth: 10,                        itemStyle: {                            borderRadius: 5,                            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [                                { offset: 0, color: '#14c8d4' },                                { offset: 1, color: '#43eec6' }                            ])                        },                        data: barData                    },                    {                        name: 'line',                        type: 'bar',                        barGap: '-100%',                        barWidth: 10,                        itemStyle: {                            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [                                { offset: 0, color: 'rgba(20,200,212,0.5)' },                                { offset: 0.2, color: 'rgba(20,200,212,0.2)' },                                { offset: 1, color: 'rgba(20,200,212,0)' }                            ])                        },                        z: -12,                        data: lineData                    },                    {                        name: 'dotted',                        type: 'pictorialBar',                        symbol: 'rect',                        itemStyle: {                            color: '#0f375f'                        },                        symbolRepeat: true,                        symbolSize: [12, 4],                        symbolMargin: 1,                        z: -10,                        data: lineData                    }                ]            };            option && myChart.setOption(option);            window.addEventListener("resize", () => {                myChart.resize();            });        }        onMounted(() => {            initCharts()        })    }})</script>

官网地址:echarts.apache.org/examples/zh…