停机次数

描述:当前是关于Echarts图表中的 柱状图 示例。
 
            let data = [{
    "haltCountMonthGoal": 80,
    "monthHaltCount": 40,
    "name": "A",
    "todayHaltCount": 5
}, {
    "haltCountMonthGoal": 50,
    "monthHaltCount": 50,
    "name": "C",
    "todayHaltCount": 10
}, ]
data = data.reverse()
// a在下,b在上
const [a, b] = data
// 取最大值,上下两列的最大值都设为这个值
const max = Math.max(a.haltCountMonthGoal, b.haltCountMonthGoal)
// 箭头标记点坐标,当月累计大于月目标时,去最大值,否则乘以相应的比例
const markPointData = [{
        name: '日累计',
        value: b.todayHaltCount,
        xAxis: b.monthHaltCount >= b.haltCountMonthGoal ? max : (b.monthHaltCount + b.todayHaltCount) * (max / b.haltCountMonthGoal),
        yAxis: 1
    },
    {
        name: '日累计',
        value: a.todayHaltCount,
        xAxis: a.monthHaltCount >= a.haltCountMonthGoal ? max : (a.monthHaltCount + a.todayHaltCount) * (max / a.haltCountMonthGoal),
        yAxis: 0
    }
]
// 提示框标记坐标
let markPointRectData = JSON.parse(JSON.stringify(markPointData))
// 提示框左侧和右侧都不能被隐藏
markPointRectData.map(v => {
    if ((v.xAxis - v.value) >= max) {
        v.xAxis -= v.value * 2
    }
    let rate = v.xAxis / max
    if (rate < 0.1) {
        v.xAxis += max * 0.08
    } else if (rate > 0.9) {
        v.xAxis -= max * 0.08
    }
})
// 标记线数据,上下两列
let markLineData = [
    // 下标记线
    [{
            x: '2',
            y: '76.5%',
            lineStyle: {
                width: 40,
                color: '#ff001c'
            }
        },
        {
            x: '80%',
            y: '76.5%'
        }
    ],
    // 上标记线
    [{
            x: '15',
            y: '38.4%',
            lineStyle: {
                width: 40,
                color: '#ff001c'
            }
        },
        {
            x: '525',
            y: '38.4%'
        }
    ]
]
// 标记线数量,长度
let monthCount = data.map((v, index) => {
    // 长度是否为2,如果长度不为2,那么下标只能取0,而取不到1
    const lengthIs2 = markLineData.length === 2
    if (v.monthHaltCount >= v.haltCountMonthGoal) {
        // 控制红色警告线的长度
        markLineData[lengthIs2 ? index : 0][1].x -= 5.1
        return max - v.todayHaltCount * (max / v.haltCountMonthGoal)
    } else {
        // 未超过,不显示标记线
        markLineData.splice(lengthIs2 ? index : 0, 1)
    }
    return (v.monthHaltCount / v.haltCountMonthGoal) * max
})
option = {
    color: ['#5095f3', '#000f84', '#bbdaf7'],
    title: {
        text: '停机次数',
        textStyle: {
            fontFamily: 'PingFang SC Bold',
            fontSize: 30,
            fontWeight: 'lighter'
        },
        left: 12,
        top: 15
    },
    legend: {
        textStyle: {
            fontFamily: 'PingFang SC Regular',
            fontSize: 100 / 4
        },
        right: 15,
        top: 66 / 4,
        itemHeight: 96 / 4,
        itemWidth: 96 / 4,
        itemGap: 76 / 4,
        data: [{
                name: '日累计',
                icon: 'rect'
            },
            {
                name: '月累计',
                icon: 'rect'
            },
            {
                name: '月目标',
                icon: 'rect'
            }
        ]
    },
    grid: {
        top: 60,
        left: 15,
        right: 15,
        bottom: -10,
        containLabel: true
    },
    xAxis: {
        show: false,
        type: 'value',
        max: max
    },
    yAxis: {
        type: 'category',
        axisLabel: {
            show: false
        },
        data: data.map(v => v.name),
        splitLine: {
            show: false
        },
        axisTick: {
            show: false
        },
        axisLine: {
            show: false
        }
    },
    series: [{
            name: '月累计',
            type: 'bar',
            barWidth: 160 / 4,
            stack: 'count',
            label: {
                show: true,
                position: 'insideLeft',
                fontFamily: 'PingFang SC Regular',
                fontSize: 18,
                offset: [0, -40],
                color: '#333',
                formatter: params => {
                    return '{letter|' + params.name + '}组 月累计停机次数 ' +
                        '{number|' + (params.dataIndex === 0 ? a : b).monthHaltCount + '}次'
                },
                rich: {
                    letter: {
                        fontFamily: 'PingFang SC Regular',
                        color: '#333',
                        fontSize: 30,
                        verticalAlign: 'top'
                    },
                    number: {
                        fontFamily: 'PingFang SC Regular',
                        color: '#333',
                        fontSize: 30,
                        verticalAlign: 'top',
                        lineHeight: 36
                    }
                }
            },
            markLine: {
                symbol: 'none',
                lineStyle: {
                    type: 'solid'
                },
                silent: true,
                label: {
                    position: 'middle',
                    color: '#fff',
                    fontFamily: 'PingFang SC Regular',
                    fontSize: 18,
                    height: 30,
                    lineHeight: 40,
                    verticalAlign: 'middle',
                    formatter: params => {
                        const {
                            haltCountMonthGoal,
                            monthHaltCount
                        } = data[params.dataIndex]
                        const value = monthHaltCount - haltCountMonthGoal
                        if (value === 0) {
                            return '已触及月目标'
                        } else if (value > 0) {
                            return '已超出月目标停机次数{number|' + value + '}次'
                        }
                        return ''
                    },
                    rich: {
                        number: {
                            fontFamily: 'PingFang SC Regular',
                            fontSize: 27,
                            color: '#fff',
                            verticalAlign: 'middle',
                            lineHeight: 27
                        }
                    }
                },
                data: markLineData
            },
            data: monthCount
        },
        {
            name: '日累计',
            type: 'bar',
            barWidth: 160 / 4,
            barGap: '0%',
            stack: 'count',
            label: {
                normal: {
                    show: false,
                    position: 'top',
                    fontFamily: 'PingFang SC Regular',
                    fontSize: 120 / 4,
                    color: '#333'
                }
            },
            data: data.map(v => {
                return v.todayHaltCount * (max / v.haltCountMonthGoal)
            }),
            markPoint: {
                symbol: 'arrow',
                symbolSize: 15,
                symbolOffset: [0, 20],
                data: markPointData,
                label: {
                    show: false
                }
            }
        },
        {
            name: '月目标',
            type: 'bar',
            barWidth: 160 / 4,
            stack: 'count',
            label: {
                show: true,
                position: 'insideRight',
                offset: [0, -40],
                fontFamily: 'PingFang SC Regular',
                fontSize: 18,
                color: '#333',
                formatter: params => {
                    return '月目标停机次数 {number|' + (params.dataIndex === 0 ? a : b).haltCountMonthGoal + '}次'
                },
                rich: {
                    number: {
                        fontFamily: 'PingFang SC Regular',
                        color: '#333',
                        fontSize: 30,
                        verticalAlign: 'top',
                        lineHeight: 36
                    }
                }
            },
            data: data.map(v => {
                if (v.monthHaltCount >= v.haltCountMonthGoal) {
                    return 0
                }
                return max - (v.monthHaltCount / v.haltCountMonthGoal) * max - v.todayHaltCount * (max / v.haltCountMonthGoal)
            }),
            markPoint: {
                symbol: 'rect',
                symbolSize: [100, 30],
                symbolOffset: [0, 45],
                data: markPointRectData,
                itemStyle: {
                    color: '#000f84'
                },
                label: {
                    fontFamily: 'PingFang SC Regular',
                    fontSize: 15,
                    formatter: params => {
                        return '今日已停 ' + (params.dataIndex === 0 ? b : a).todayHaltCount + '次'
                    },
                    offset: [0, 0]
                }
            }
        }
    ]
}