首页 前端知识 echarts时间轴;计划时间实际时间

echarts时间轴;计划时间实际时间

2024-06-20 00:06:40 前端知识 前端哥 597 479 我要收藏

最近遇到一个图表需要展示任务计划时间实际时间
常用echarts的大佬知道这是一个xy轴刻度对应两条柱子的图;
但是由于多个任务(刻度)开始的时间不一致可能不在0开始(多任务柱子开始位置)

需要展示两条柱子

let option = {
        ...
        series:[
            {
                name: '计划时间',
                type: 'bar',
                data:[...]
            }{
                name: '实际时间',
                type: 'bar',
                data:[...]
            }
        ]
        ...
    }

如上的option加上数据渲染出的如图
image.png

处理开始日期(值)不一样问题

开始日期不一样的(多个任务;任务一10月1日-10月10日;任务二10月2日开始)两个任务的开始位置是不一样的
我想到是用堆叠柱状图把开始日期空白的部分隐藏掉

 let option = {
        ...
        series:[
        
            //用于开始位置空白的柱子要注意堆叠图的数组位置在前渲染时在前
            {
                name: '计划时间0',
                type: 'bar',
                stack: 'total1',     //堆叠属性;计划时间的这里用的total1
                data:[...],
                label: {
                    show: false
                },
                itemStyle: {    //隐藏柱子
                    opacity: 0,
                },
            }{
                name: '计划时间',
                type: 'bar',
                stack: 'total1',
                data:[...]
            }//用于开始位置空白的柱子
            {
                name: '实际时间0',
                type: 'bar',
                stack: 'total2',    //堆叠属性;实际时间的这里用的total2
                data:[...],
                label: {
                    show: false
                },
                itemStyle: {      //隐藏柱子
                    opacity: 0,
                },
            }
            {
                name: '实际时间',
                type: 'bar',
                stack: 'total2',     //堆叠属性;实际时间的这里用的total2
                data:[...]
            }
        ]
        ...
    }
   

加上数据渲染可以看到效果如下

image.png

处理轴label显示

由于这个图的需求就是展示日期;后期数据可以使用时间戳;
通过时间戳在x或者y轴自定义渲染刻度

数据格式我这里是这样的

    let date_timestr = +new Date();   
    //为什么有这个;这个作用于xy轴的自定义显示;
    //因为echarts是从0开始的如果设置最小值为数据内的最小值;
    //就会发现自定义x轴显示日期跨度非常之大不合理
    // 这个变量在我们自定义是拼接格式化就好;
    // 这个值是所有数据中最小的日期的时间戳


    // 数据部分没有前面的年月 相当于只有任务的开始的天和结束的天;小时等等应该都可以吧
    // 计划时间
    let opacity_Data = [            //隐藏部分的;开始时间的 (几天几小时)
        1000 * 60 * 60 * 24 * 2,
        1000 * 60 * 60 * 24 * 4,
        1000 * 60 * 60 * 24 * 2,
        1000 * 60 * 60 * 24 * 10,
    ]
    let high_Data = [               //高亮部分的;结束时间的
        1000 * 60 * 60 * 24 * 5,
        1000 * 60 * 60 * 24 * 10,
        1000 * 60 * 60 * 24 * 100,
        1000 * 60 * 60 * 24 * 50,
    ]

    // 实际时间的
    let opacity_Data2 = [
        1000 * 60 * 60 * 24 * 2,
        1000 * 60 * 60 * 24 * 4,
        1000 * 60 * 60 * 24 * 2,
        1000 * 60 * 60 * 24 * 10,
    ]
    let high_Data2 = [
        1000 * 60 * 60 * 24 * 10,
        1000 * 60 * 60 * 24 * 7,
        1000 * 60 * 60 * 24 * 10,
        1000 * 60 * 60 * 24 * 55,
    ]

xAxis: {
    type: 'value',
    minInterval: 1000 * 60 * 60 * 24,       //最小轴线分割 一天的的值 如果是小时自行修改
    // 此处可
    // 最大的用于限制x多刻度线的一刻度值 这里8天一刻度;其它的都可以多了如果要细致到小时等等自行修改
    // 如果数据是天的且想要精确到一天甚至更小推荐添加滚动条
    maxInterval: 1000 * 60 * 60 * 24 * 8,   //最大轴线分割 一天的的值 如果是小时自行修改
    axisLabel: {
        fontSize: 12,
        fontWeight: 600,
        color: '#888',
        formatter: function (val, index) {
            let date_ = new Date(val + date_timestr);
            let label_ = `${date_.getFullYear()}/${date_.getMonth() + 1}/${date_.getDate()}`;
            return label_;
        },
        // maxInterval 的设置刻度较多旋转显示
        rotate: 20
    },
    splitLine: {
        show: true,
        lineStyle: {
            color: '#eee',
        },
    },
    axisLine: {
        show: false
    }
},

完整代码


    let date_timestr = +new Date();  //任务开始的最小值我这里就用的目前时间
    date_timestr = +new Date('2022/10/19');
    let opacity_Data = [            //隐藏部分的;开始时间的 (几天几小时)
        1000 * 60 * 60 * 24 * 2,
        1000 * 60 * 60 * 24 * 4,
        1000 * 60 * 60 * 24 * 2,
        1000 * 60 * 60 * 24 * 10,
    ]
    let high_Data = [               //高亮部分的;结束时间的
        1000 * 60 * 60 * 24 * 5,
        1000 * 60 * 60 * 24 * 10,
        1000 * 60 * 60 * 24 * 100,
        1000 * 60 * 60 * 24 * 50,
    ]

    let opacity_Data2 = [
        1000 * 60 * 60 * 24 * 2,
        1000 * 60 * 60 * 24 * 4,
        1000 * 60 * 60 * 24 * 2,
        1000 * 60 * 60 * 24 * 10,
    ]
    let high_Data2 = [
        1000 * 60 * 60 * 24 * 10,
        1000 * 60 * 60 * 24 * 7,
        1000 * 60 * 60 * 24 * 10,
        1000 * 60 * 60 * 24 * 55,
    ]
    const formatterTime = (d) => {
        let d_ = new Date(d);
        return `${d_.getFullYear()}/${d_.getMonth() + 1}/${d_.getDate()} ${d_.getHours()}:${d_.getMinutes()}:${d_.getSeconds()}`
    }
    let option = {
        grid: {
            containLabel: true,
            right: '10%',
            left: '5%',
            bottom: '6%',
            top: '10%',
        },
        legend: {
            top: "5%",
            data: ['计划时间', '实际时间'],
            selectedMode: false,        //这里禁止点击;需要的自己写事件使用filter动态setOption
            textStyle: {
                fontSize: 12,
                fontWeight: 600
            }
        },
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                // Use axis to trigger tooltip
                type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
            },
            formatter: function (ToolFormatterParam) {
                let labels = `<div>
                    <b>${ToolFormatterParam[0].name}</b>
                </div>`;
                ToolFormatterParam.map((item) => {
                    let isSeriesNameZero = item.seriesName.includes('0');
                    if (!isSeriesNameZero) {
                        let startTime = ToolFormatterParam.filter((item2) => {
                            if (item2.seriesName.includes((item.seriesName + '0'))) {
                                return item2
                            }
                        })[0].value + date_timestr;
                        let endTime = null;
                        endTime = date_timestr + item.value;
                        let label_item = `<div>${item.seriesName}${formatterTime(startTime)}${formatterTime(endTime)}</div>`
                        labels += label_item
                    }
                })
                return labels;
            }
        },
        xAxis: {
            type: 'value',
            minInterval: 1000 * 60 * 60 * 24,       //最小轴线分割 一天的的值 如果是小时自行修改
            // 此处可
            // 最大的用于限制x多刻度线的一刻度值 这里8天一刻度;其它的都可以多了如果要细致到小时等等自行修改
            // 如果数据是天的且想要精确到一天甚至更小推荐添加滚动条
            maxInterval: 1000 * 60 * 60 * 24 * 8,   //最大轴线分割 一天的的值 如果是小时自行修改
            axisLabel: {
                fontSize: 12,
                fontWeight: 600,
                color: '#888',
                formatter: function (val, index) {
                    let date_ = new Date(val + date_timestr);
                    let label_ = `${date_.getFullYear()}/${date_.getMonth() + 1}/${date_.getDate()}`;
                    return label_;
                },
                // maxInterval 的设置刻度较多旋转显示
                rotate: 20
            },
            splitLine: {
                show: true,
                lineStyle: {
                    color: '#eee',
                },
            },
            axisLine: {
                show: false
            }
        },
        yAxis: {
            type: 'category',
            inverse: true,
            data: ['收购痛讯', '亿个小目标', '下一个小目标', '周游世界'],
            axisLabel: {
                color: '#333',
                fontSize: 12,
                fontWeight: 600
            },
            axisLine: {
                show: false,
            },
            axisTick: {
                show: false,
            },
        },
        // k = 0,1 隐藏的;k=1,2高亮的
        color: [
            '#fff',
            {
                type: 'linear',
                x: 0,
                y: 0,
                x2: 1,
                y2: 0,
                colorStops: [
                    {
                        offset: 0,
                        color: '#4297FE', // 0% 处的颜色
                    },
                    {
                        offset: 1,
                        color: '#007BFF', // 0% 处的颜色
                    },
                ],
                global: false, // 缺省为 false
            },
            '#fff',
            {
                type: 'linear',
                x: 0,
                y: 0,
                x2: 1,
                y2: 0,
                colorStops: [
                    {
                        offset: 0,
                        color: '#5198FF', // 0% 处的颜色
                    },
                    {
                        offset: 1,
                        color: '#8BF8FE', // 0% 处的颜色
                    },
                ],
                global: false, // 缺省为 false
            }
        ],
        series: [
            {
                //开始空白(隐藏部分需要在后面加0)tooltip formatter内有判断需要修改注意
                name: '计划时间0',
                type: 'bar',
                stack: 'total',
                label: {
                    show: false
                },
                itemStyle: {
                    opacity: 0,
                },
                emphasis: {
                    focus: 'series'
                },
                barWidth: 24,
                barGap: '10%',
                data: opacity_Data
            },
            {
                name: '计划时间',
                type: 'bar',
                stack: 'total',
                label: {
                    show: false
                },
                emphasis: {
                    focus: 'series'
                },
                barWidth: 24,
                barGap: '10%',
                itemStyle: {
                    borderRadius: [6, 20, 20, 6]
                },
                data: high_Data
            },


            {
                name: '实际时间0',
                type: 'bar',
                stack: 'total2',
                label: {
                    show: false,
                },
                itemStyle: {
                    opacity: 0
                },
                barWidth: 24,
                emphasis: {
                    focus: 'series'
                },
                barGap: '10%',
                data: opacity_Data2
            },
            {
                name: '实际时间',
                type: 'bar',
                stack: 'total2',
                label: {
                    show: false
                },
                emphasis: {
                    focus: 'series'
                },
                barWidth: 24,
                barGap: '10%',
                itemStyle: {
                    borderRadius: [6, 20, 20, 6]
                },
                data: high_Data2
            },
        ],
    };

最终效果如图

image.png

echarts也是有xAxis,yAxis type:"time"的配置可以支持日期;

因为使用版本是v5.4.1的原因堆叠没有展示正确
image.png
image.png
同样代码3.x版本是这样的可以正常展示堆叠的
image.png

转载请注明出处或者链接地址:https://www.qianduange.cn//article/12924.html
标签
评论
发布的文章

读魏书生的心得体会

2024-07-03 14:07:10

jQuery 选择器

2024-05-12 00:05:34

Vue中public/assets目录区别

2024-07-02 23:07:29

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!