Echarts x軸分組與不規(guī)則刻度線

前言

在年后一個普普通通的日子殴玛,普普通通的我接到了一個被描述為可簡單的報表工作,口頭描述為“全是柱狀圖”,報表嘛~so easy水评,然后我眼睜睜看著這東西的設(shè)計從最初excel里可愛又簡陋的柱狀圖迭代3版之后成了PPT里要演示的稀奇古怪的狀態(tài),其中x軸的2-3層分組讓孤陋寡聞的我滿腦子問號媚送,需求是這樣的:


需求1.png

這樣的


需求2.png

以及這樣的
需求3.png

我快速的去官方文檔坐標(biāo)軸配置項(xiàng)xAxis里從頭到尾翻了一遍中燥,發(fā)現(xiàn)沒有相關(guān)功能,又去echarts項(xiàng)目的git翻看issues,只看到了這個


issues.png

然后開始嘗試自己畫線塘偎,企圖用markLine先把分組刻度線造出來疗涉,然而造是造出來了拿霉,但是隨著視窗大小變動,markLine位置會產(chǎn)生偏移咱扣,無法完美跟x軸位置對應(yīng)上绽淘。山窮水盡之時,我又去百度了一下echarts的分組闹伪,然后看到了

echarts示例圖.png

附訪問地址:https://vis.baidu.com/chartusage/grouped-bar/
其中
echarts示例圖.png

已經(jīng)非常接近實(shí)現(xiàn)目標(biāo)了沪铭,示例右下角的前往 Gallery 編輯點(diǎn)過去獲得了此示例的源碼(附示例源碼鏈接https://www.makeapie.com/editor.html?c=xBk7TY_hWx&v=2),那么接下來便是分析實(shí)現(xiàn)思路及變更到X軸實(shí)現(xiàn)即可偏瓤。

示例實(shí)現(xiàn)思路分析

按照示例源碼伦意,可以發(fā)現(xiàn)主要實(shí)現(xiàn)方式是通過多個y軸(即yAxis)的刻度線(即axisTick)延長作為分組線,刻度文字(即axisLabel)顯示作為分組的組名硼补,再將此y軸向左偏移到合適位置驮肉,來完成整體效果的實(shí)現(xiàn),所以x軸分組的實(shí)現(xiàn)思路如下:

1.建立新的用于分組的x軸已骇,并向下進(jìn)行偏移离钝,方便后續(xù)調(diào)試顯示;
2.在合適位置畫刻度延長線作為分組線褪储;
3.在合適位置放置刻度對應(yīng)文字卵渴。

基礎(chǔ)實(shí)現(xiàn)

本文使用官方柱狀圖示例做基礎(chǔ),在此上進(jìn)行修改講解(附示例鏈接:https://echarts.apache.org/examples/zh/editor.html?c=bar-simple
首先建立分組xAxis鲤竹,原示例中單項(xiàng)xAxis需改成數(shù)組浪读,改動前:

    xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },

改動后:

    xAxis: [{
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },{
        position: 'bottom',// 將分組x軸位置定至底部,不然默認(rèn)在頂部
        offset: 40,// 向下偏移辛藻,使分組文字顯示位置不與原x軸重疊
        axisLine: {
           show: false // 隱藏分組x軸的軸線
        },
        axisTick: {
            length: 40, // 延長刻度線做分組線 
            inside: true, // 使刻度線相對軸線在上面與原x軸相接碘橘,默認(rèn)在軸線下方
            lineStyle: {color: '#ff9800'},// 非必須,僅為了演示吱肌,明顯標(biāo)示出分組刻度線
        },
        data:['分組1','分組2']
    }],

此時效果如下(為了便于區(qū)分痘拆,分組刻度線使用橙色):


等分刻度.png

可以看到此時完成了均分效果的分組,如果像我那個需求1一樣氮墨,是偶數(shù)個柱狀圖均分分組纺蛆,那么此時已經(jīng)完成了。

非均分分組實(shí)現(xiàn)

繼續(xù)完成非均分的分組规揪,需要繼續(xù)處理好思路的2和3:
2.在合適位置畫刻度延長線作為分組線桥氏;
3.在合適位置放置刻度對應(yīng)文字。
首先猛铅,需要改變刻度線位置字支,那么翻看配置手冊中axisTick配置項(xiàng),發(fā)現(xiàn)interval可以控制間隔幾顯示,同時接受返回boolean的function祥款,那么增加分組x軸的刻度分組后,控制刻度線的顯示即可達(dá)成目的月杉,如(注意data也在跟隨示例效果做變動):

axisTick: {
            length: 40, // 延長刻度線做分組線 
            inside: true, // 使刻度線相對軸線在上面與原x軸相接刃跛,默認(rèn)在軸線下方
            lineStyle: {color: '#ff9800'},// 非必須,僅為了演示苛萎,明顯標(biāo)示出分組刻度線
            interval: function (index, value) {
                return index % 3 === 0 // 從第一個開始桨昙,每3個分一組
            }
        },
data: ['','分組1','','','分組2','','分組3']

效果如下:

靈活的等分刻度.png

因?yàn)閕nterval接受的function返回值是boolean,所以方法中可以做任意判斷腌歉,如(注意data也在跟隨示例效果做變動):

axisTick: {
            length: 40, // 延長刻度線做分組線 
            inside: true, // 使刻度線相對軸線在上面與原x軸相接蛙酪,默認(rèn)在軸線下方
            lineStyle: {color: '#ff9800'},// 非必須,僅為了演示翘盖,明顯標(biāo)示出分組刻度線
            interval: function (index, value) {
               return index === 0 || index === 5 || index === 6 // 在0桂塞、5、6處各畫一條刻度線
            }
        },
data: ['','','分組1','','','分組2','分組3']

效果如下:

非等分刻度.png

至此馍驯,上述例子中分組組名的位置一直在通過配置data的內(nèi)容來調(diào)整阁危,而實(shí)際需求中,往往需要更靈活的配置方式汰瘫,axisLabel的formatter可以幫助我們達(dá)成這種需求(注意:為了顯示效果更好狂打,offset、axisTick.length混弥、data均有變動):

    xAxis: [{
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },{
        position: 'bottom',// 將分組x軸位置定至底部趴乡,不然默認(rèn)在頂部
        offset: 55,// 向下偏移,使分組文字顯示位置不與原x軸重疊
        axisLine: {
           show: false // 隱藏分組x軸的軸線
        },
        axisTick: {
            length: 55, // 延長刻度線做分組線 
            inside: true, // 使刻度線相對軸線在上面與原x軸相接蝗拿,默認(rèn)在軸線下方
            lineStyle: {color: '#ff9800'},// 非必須晾捏,僅為了演示,明顯標(biāo)示出分組刻度線
            interval: function (index, value) {
               return index === 0 || index === 5 || index === 6 // 在0哀托、5粟瞬、6處各畫一條刻度線
            }
        },
        axisLabel: {
                    inside: true,// 使刻度名稱相對軸線在上面與原x軸相接,默認(rèn)在軸線下方
                    interval: 0,// 強(qiáng)制顯示全部刻度名
                    formatter: function (val, index) {
                        if (val === 'Wed') {// 可以通過刻度名稱判斷
                            return '2019'
                        } else if (index === 5) {// 也可以通過索引判斷
                            return '2020'
                        } else if (index === 6) {
                            return '2021'
                        }
                    }
                },
        data:['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] // 與原x軸保持一致萤捆,方便使用對應(yīng)名稱做判斷
    }],

效果如下:

靈活配置分組組名位置及內(nèi)容.png

如果分組是偶數(shù)的裙品,可以通過axisLabel文字內(nèi)容前加入空格達(dá)到文字向右偏移的效果(axisTick、axisLabel內(nèi)容有變化):

 xAxis: [{
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },{
        position: 'bottom',// 將分組x軸位置定至底部俗或,不然默認(rèn)在頂部
        offset: 55,// 向下偏移市怎,使分組文字顯示位置不與原x軸重疊
        axisLine: {
           show: false // 隱藏分組x軸的軸線
        },
        axisTick: {
            length: 55, // 延長刻度線做分組線 
            inside: true, // 使刻度線相對軸線在上面與原x軸相接,默認(rèn)在軸線下方
            lineStyle: {color: '#ff9800'},// 非必須辛慰,僅為了演示区匠,明顯標(biāo)示出分組刻度線
            interval: function (index, value) {
               return index === 0 || index === 4 || index === 6 // 在0、4、6處各畫一條刻度線
            }
        },
        axisLabel: {
                    inside: true,// 使刻度名稱相對軸線在上面與原x軸相接驰弄,默認(rèn)在軸線下方
                    interval: 0,// 強(qiáng)制顯示全部刻度名
                    formatter: function (val, index) {
                        if (val === 'Tue') {
                            return '                 2019'
                        } else if (index === 4) {
                            return '                 2020'
                        } else if (index === 6) {
                            return '2021'
                        }
                    }
                },
        data:['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    }],

效果如下:

偶數(shù)位置通過偏移居中.png

但是添加固定空格的偏移方式無法隨著屏幕寬度變化麻汰,所以建議優(yōu)化為添加空格數(shù)量隨著屏幕寬度增加而動態(tài)增加,如:

        axisLabel: {
                    inside: true,// 使刻度名稱相對軸線在上面與原x軸相接戚篙,默認(rèn)在軸線下方
                    interval: 0,// 強(qiáng)制顯示全部刻度名
                    formatter: function (val, index) {
                        var _wid = window.innerWidth /70; // 70這個數(shù)字請自行對著自己項(xiàng)目頁面調(diào)試五鲫,作者使用echarts示例編輯器window.innerWidth跟實(shí)際用于顯示的width無法對應(yīng)上
                        var _pla = new Array(Number(_wid.toFixed(0))).fill(' ');
                        if (val === 'Tue') {
                            return _pla.join('')+'2019'
                        } else if (index === 4) {
                            return _pla.join('')+'2020'
                        } else if (index === 6) {
                            return '2021'
                        }
                    }
                },

第三層分組

其實(shí)通過創(chuàng)建第二級分組,第三層的分組的思路已經(jīng)很明確了岔擂,不外乎再創(chuàng)建一個刻度線更長的分組位喂,而實(shí)際操作中發(fā)現(xiàn),僅1個刻度時乱灵,刻度線僅能畫出首位刻度線塑崖,所以第三層分組如果是只有一個大組的情況下,需要2個xAxis痛倚,一正一反來畫首位更長的刻度線:

  xAxis: [{
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },{
        position: 'bottom',// 將分組x軸位置定至底部规婆,不然默認(rèn)在頂部
        offset: 55,// 向下偏移,使分組文字顯示位置不與原x軸重疊
        axisLine: {
           show: false // 隱藏分組x軸的軸線
        },
        axisTick: {
            length: 55, // 延長刻度線做分組線 
            inside: true, // 使刻度線相對軸線在上面與原x軸相接蝉稳,默認(rèn)在軸線下方
            lineStyle: {color: '#ff9800'},// 非必須聋呢,僅為了演示,明顯標(biāo)示出分組刻度線
            interval: function (index, value) {
               return index === 0 || index === 4 || index === 6 // 在0颠区、5削锰、6處各畫一條刻度線
            }
        },
        axisLabel: {
                    inside: true,// 使刻度名稱相對軸線在上面與原x軸相接,默認(rèn)在軸線下方
                    interval: 0,// 強(qiáng)制顯示全部刻度名
                    formatter: function (val, index) {
                        var _wid = window.innerWidth /70; // 70這個數(shù)字請自行對著自己項(xiàng)目頁面調(diào)試毕莱,作者使用echarts示例編輯器window.innerWidth跟實(shí)際用于顯示的width無法對應(yīng)上
                        var _pla = new Array(Number(_wid.toFixed(0))).fill(' ');
                        if (val === 'Tue') {
                            return _pla.join('')+'2019'
                        } else if (index === 4) {
                            return _pla.join('')+'2020'
                        } else if (index === 6) {
                            return '2021'
                        }
                    }
                },
        data:['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },{
                position: 'bottom',
                offset: 80,
                axisLine: {
                    onZero: false,
                    show: false
                },
                axisTick: {
                    length: 70,
                    inside: true,
                    lineStyle: {color: 'red'},// 為了區(qū)分明顯標(biāo)色的
                    interval: function (index, value) {// 畫左邊年框線
                        return index === 0
                    }
                },
                axisLabel: {
                    inside: true,
                    color: 'red',// 為了區(qū)分明顯標(biāo)色的
                    interval: 0,
                },
                data: ['第三層分組']
            }, {
                inverse: true,
                position: 'bottom',
                offset: 80,
                axisLine: {
                    onZero: false,
                    show: false
                },
                axisTick: {
                    length: 70,
                    inside: true,
                    lineStyle: {color: 'red'},// 為了區(qū)分明顯標(biāo)色的
                    interval: function (index, value) {// 畫右邊年框線
                        return index === 0
                    }
                },
                axisLabel: {
                    inside: true,
                    color: 'red',// 為了區(qū)分明顯標(biāo)色的
                    interval: 0,
                },
                data: ['第三層分組']
            }],

效果如下:


三層分組效果圖.png

最后

至此器贩,靜態(tài)的需求1-3已全部實(shí)現(xiàn),動態(tài)的分組可以計算每一組首刻度線的數(shù)字做動態(tài)刻度線朋截,相對的動態(tài)控制分組文字的居中顯示奇數(shù)為(首刻度數(shù)+(組內(nèi)柱狀圖數(shù)目)/2+0.5)蛹稍,偶數(shù)為(首刻度數(shù)+(組內(nèi)柱狀圖數(shù)目)/2)+ 偏移量,我代碼寫太蠢了部服,不放了唆姐。

本文僅做提供思路及記錄作用,如有錯誤廓八,歡迎指正奉芦。

echarts示例編輯器可運(yùn)行的全代碼如下:

option = {
    xAxis: [{
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },{
        position: 'bottom',// 將分組x軸位置定至底部,不然默認(rèn)在頂部
        offset: 55,// 向下偏移剧蹂,使分組文字顯示位置不與原x軸重疊
        axisLine: {
           show: false // 隱藏分組x軸的軸線
        },
        axisTick: {
            length: 55, // 延長刻度線做分組線 
            inside: true, // 使刻度線相對軸線在上面與原x軸相接声功,默認(rèn)在軸線下方
            lineStyle: {color: '#ff9800'},// 非必須,僅為了演示宠叼,明顯標(biāo)示出分組刻度線
            interval: function (index, value) {
               return index === 0 || index === 4 || index === 6 // 在0先巴、5、6處各畫一條刻度線
            }
        },
        axisLabel: {
                    inside: true,// 使刻度名稱相對軸線在上面與原x軸相接,默認(rèn)在軸線下方
                    interval: 0,// 強(qiáng)制顯示全部刻度名
                    formatter: function (val, index) {
                        var _wid = window.innerWidth /70; // 70這個數(shù)字請自行對著自己項(xiàng)目頁面調(diào)試伸蚯,作者使用echarts示例編輯器window.innerWidth跟實(shí)際用于顯示的width無法對應(yīng)上
                        var _pla = new Array(Number(_wid.toFixed(0))).fill(' ');
                        if (val === 'Tue') {
                            return _pla.join('')+'2019'
                        } else if (index === 4) {
                            return _pla.join('')+'2020'
                        } else if (index === 6) {
                            return '2021'
                        }
                    }
                },
        data:['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },{
                position: 'bottom',
                offset: 80,
                axisLine: {
                    onZero: false,
                    show: false
                },
                axisTick: {
                    length: 70,
                    inside: true,
                    lineStyle: {color: 'red'},
                    interval: function (index, value) {// 畫左邊年框線
                        return index === 0
                    }
                },
                axisLabel: {
                    inside: true,
                    color: 'red',
                    interval: 0,
                },
                data: ['第三層分組']
            }, {
                inverse: true,
                position: 'bottom',
                offset: 80,
                axisLine: {
                    onZero: false,
                    show: false
                },
                axisTick: {
                    length: 70,
                    inside: true,
                    lineStyle: {color: 'red'},
                    interval: function (index, value) {// 畫右邊年框線
                        return index === 0
                    }
                },
                axisLabel: {
                    inside: true,
                    color: 'red',
                    interval: 0,
                },
                data: ['第三層分組']
            }],
    yAxis: {
        type: 'value'
    },
    series: [{
        data: [120, 200, 150, 80, 70, 110, 130],
        type: 'bar'
    }]
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末摩渺,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子剂邮,更是在濱河造成了極大的恐慌摇幻,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抗斤,死亡現(xiàn)場離奇詭異囚企,居然都是意外死亡丈咐,警方通過查閱死者的電腦和手機(jī)瑞眼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棵逊,“玉大人伤疙,你說我怎么就攤上這事×居埃” “怎么了徒像?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蛙讥。 經(jīng)常有香客問我锯蛀,道長,這世上最難降的妖魔是什么次慢? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任旁涤,我火速辦了婚禮,結(jié)果婚禮上迫像,老公的妹妹穿的比我還像新娘劈愚。我一直安慰自己,他們只是感情好闻妓,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布菌羽。 她就那樣靜靜地躺著,像睡著了一般由缆。 火紅的嫁衣襯著肌膚如雪注祖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天均唉,我揣著相機(jī)與錄音氓轰,去河邊找鬼。 笑死浸卦,一個胖子當(dāng)著我的面吹牛署鸡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼靴庆,長吁一口氣:“原來是場噩夢啊……” “哼时捌!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起炉抒,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤奢讨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后焰薄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拿诸,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年塞茅,在試婚紗的時候發(fā)現(xiàn)自己被綠了亩码。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡野瘦,死狀恐怖描沟,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鞭光,我是刑警寧澤吏廉,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站惰许,受9級特大地震影響席覆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜汹买,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一佩伤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧卦睹,春花似錦畦戒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至徐鹤,卻和暖如春垃环,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背返敬。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工遂庄, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人劲赠。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓涛目,卻偏偏與公主長得像秸谢,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子霹肝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 在vue使用echarts echarts是什么 ecahrts 是一個高度可定制化的圖表庫 如何使用echart...
    小將和硝子閱讀 2,172評論 0 3
  • 江漢曾為客估蹄,相逢每醉還。浮云一別后沫换,流水十年間臭蚁。 制作echarts的柱狀圖時我們發(fā)現(xiàn)axisLabel的長度過長...
    Nanayai閱讀 15,432評論 1 6
  • 1、Echarts Y軸底紋改為虛線:yAxis: {splitLine :{ //網(wǎng)格線lineStyl...
    哈0閱讀 12,044評論 0 1
  • 最近在實(shí)習(xí)期間讯赏,接手了一個數(shù)據(jù)搜索項(xiàng)目垮兑,需要我從后臺調(diào)取數(shù)據(jù),并將之用折線圖直方圖顯示出來漱挎,并且可以將多組數(shù)據(jù)繪制...
    南客nk閱讀 7,971評論 3 21
  • 推薦指數(shù): 6.0 書籍主旨關(guān)鍵詞:特權(quán)系枪、焦點(diǎn)、注意力识樱、語言聯(lián)想嗤无、情景聯(lián)想 觀點(diǎn): 1.統(tǒng)計學(xué)現(xiàn)在叫數(shù)據(jù)分析震束,社會...
    Jenaral閱讀 5,716評論 0 5