antv完成區(qū)間柱形圖一列多柱配置實現(xiàn)詳解
使用antv 配置區(qū)間柱形圖
需求: 來源與產(chǎn)品的一個想法,想在 X 軸 每一行輸出多個區(qū)間柱形,以時間為分段,X軸 底線顯示時間, 找了一下 echarts 的實現(xiàn), 可以使用配置函數(shù)的方式 實現(xiàn),但只實現(xiàn)了一行,而且函數(shù)的配置項其API 文檔也晦澀難懂, 最后使用 antv 的 區(qū)間柱形圖來實現(xiàn), 但是 antv 無法像 echarts 一樣配置每一個柱形的顏色, 因為他的 color 配置回調(diào)函數(shù)只接受一個 type 字符串類型, 最后使用了數(shù)組隊列匹配的方式來實現(xiàn)
使用的是 antv 的 g2plot 官方分組柱形圖效果如下: 定位鏈接: g2plot.antv.vision/zh/examples…
實現(xiàn)之后的效果
分享思路
- 文件引入 這里是 html 文件, 直接可以復(fù)制, 下面的 js 文件我我們通過引入 CDN 的方式,這樣在使用 demo 的時候更加方便
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <style> .root { padding: 50px; width: 1600px; height: 500px; } </style> <body> <div id="container" class="root"></div> </body> </html>
js文件
<script type="text/javascript" src="https://unpkg.com/@antv/g2plot@latest/dist/g2plot.min.js" ></script>
引入了 g2 以后
上面引入了 g2 以后 , 我們開始分享業(yè)務(wù)邏輯, 里面包含一些功能函數(shù), 會拆開 首先是功能函數(shù), 會在 我們的業(yè)務(wù)當中使用到的
// 時間處理 // 小時轉(zhuǎn)分鐘 function ChangeStrToMinutes(str) { var arrminutes = str.split(":"); if (arrminutes.length == 2) { var minutes = parseInt(arrminutes[0]) * 60 + parseInt(arrminutes[1]); return minutes; } else { return 0; } } // 分鐘轉(zhuǎn)小時 function ChangeHourMinutestr(str) { if (str !== "0" && str !== "" && str !== null) { return ( (Math.floor(str / 60).toString().length < 2 ? "0" + Math.floor(str / 60).toString() : Math.floor(str / 60).toString()) + ":" + ((str % 60).toString().length < 2 ? "0" + (str % 60).toString() : (str % 60).toString()) ); } else { return ""; } } // 樣式處理 const setStyles = (container, styles) => { for (const key in styles) { container.style[key] = styles[key]; } }; // 動態(tài)設(shè)置畫布高度 function setHeigh(data, name, height = 100) { const dom = document.getElementsByClassName(name)[0]; const count = data.length; dom.style["height"] = count * height + "px"; }
業(yè)務(wù)邏輯處理
注意點:
- 數(shù)據(jù)使用的是假數(shù)據(jù), 這里我們可以根據(jù)自己的業(yè)務(wù)需求進行修改和擴展 因為區(qū)間柱形圖使用的數(shù)據(jù) data 是一個數(shù)組, 所以在使用我們的數(shù)據(jù)的時候需要進行一下改造
- 在使用 color 回調(diào)函數(shù)進行配置顏色的時候,不知道里面的循環(huán)為什么會進入兩次,如果有大佬可以解答或有其他解決方案歡迎交流, 這里我使用了一個閉包的方式來記錄次數(shù),因為這里的數(shù)據(jù)我們業(yè)務(wù)上還沒有和后端對接,所以暫時無法判定哪一條是第一個數(shù)據(jù),而且 color 這回調(diào)函數(shù)也不提供 其他參數(shù), 只提供一個 type 是字符串 作為參數(shù), 所以我在上面數(shù)據(jù)處理的方法里面自己加入了一個 空字符的 type,用來區(qū)分循環(huán)的進入。
- 因為 color 方法的參數(shù)只有 type, 所以我也無法區(qū)分當前應(yīng)該顯示哪一種顏色, 數(shù)據(jù)里面的 way 就是顏色, 這里我使用了一個臨時隊列 arr 也是以閉包的形式存儲, 然后從我處理好的數(shù)據(jù)中 過濾出當前 type 類型組成的一個數(shù)組, 通過下標的方式 取到當前對應(yīng)的數(shù)據(jù)
- tooltip 如果想要自定義的話 需要使用 customContent API
- 由于我們這柱形一行有多個, 默認是鼠標懸浮到當前行,沒有到我們的柱上,就會有 tooltip 提示, 可以設(shè)置shared 來匹配鼠標懸浮到柱形上才顯示 tooltip
const { Bar } = G2Plot; // 假數(shù)據(jù) var busDataInfo = [ { module: "BJ6123C7BTD", line: "8", wayLine: [ { time: ["05:50", "06:30"], way: "E", }, { time: ["06:42", "08:32"], way: "S", }, { time: ["08:46", "10:39"], way: "E", }, { time: ["14:06", "15:46"], way: "S", }, ], }, { module: "BJ6123C7BTD", line: "7", wayLine: [ { time: ["05:00", "06:30"], way: "S", }, { time: ["06:42", "08:32"], way: "E", }, { time: ["08:46", "10:39"], way: "S", }, { time: ["14:06", "15:46"], way: "E", }, ], }, { module: "BJ6123C7BTD", line: "6", wayLine: [ { time: ["05:00", "06:00"], way: "S", }, { time: ["06:12", "08:42"], way: "E", }, { time: ["08:46", "09:09"], way: "S", }, { time: ["14:06", "15:46"], way: "E", }, { time: ["16:10", "18:00"], way: "S", }, { time: ["18:34", "20:07"], way: "E", }, ], }, ]; // 數(shù)據(jù)改造 將上面的數(shù)據(jù)改造成我需要的數(shù)組格式 function changeData(data) { const outPutData = []; data.forEach((item) => { item.wayLine.forEach((every) => { outPutData.push({ type: item.line, module: item.module, way: every.way, values: [ ChangeStrToMinutes(every.time[0]), ChangeStrToMinutes(every.time[1]), ], }); }); }); //TODO 這里是為了解決 顏色 處理部分循環(huán)進入兩次的問題, 這里寫在 上面的數(shù)據(jù)處理之前和之后 會有分別,分別在于 后面是否使用 reverse 反轉(zhuǎn)數(shù)組 outPutData.push({}); return outPutData; } // 樣式 const divStyles = { position: "absolute", background: "rgba(255,255,255,0.95)", boxShadow: "rgb(174, 174, 174) 0px 0px 10px", borderRadius: "4px", padding: "10px", }; // 畫布高度設(shè)置, 是根據(jù)數(shù)組數(shù)據(jù)長度,掛載點,以及高度 三個參數(shù)來進行設(shè)置 setHeigh(busDataInfo, "root", 60); const data = changeData(busDataInfo); // 畫布實例化 const barPlot = new Bar("container", { barWidthRatio: 0.7, // 條形圖寬度占比 data: data, xField: "values", yField: "type", colorField: "type", // 部分圖表使用 seriesField color: ((arg) => { var count = 0; var arr = []; return (arg) => { const { type = "" } = arg; if (type === "") { count = count + 1; } // 解決循環(huán)會進入兩次的問題 if (count !== 1) return; arr.push(type); let currentArr = data.filter((item) => item.type === type); let filterArr = arr.filter((item) => item === type); // 獲取當前往返類型 const wayType = currentArr[filterArr.length - 1]?.way; console.log("type", type, wayType, currentArr); if (wayType === "E") { return "#FF5CA2"; } return "#6C3E00"; }; })(), xAxis: { // x軸文本標簽配置項 label: { formatter: (value) => { return ChangeHourMinutestr(value); }, }, // 坐標軸網(wǎng)格線的配置項 grid: { // alignTick:false, }, // 坐標軸線樣式 // line: // { // style: // { // stroke: 'black', // lineWidth: 1, // strokeOpacity: 0.7, // shadowColor: 'black', // shadowBlur: 10, // shadowOffsetX: 5, // shadowOffsetY: 5, // cursor: 'pointer' // } // }, // 坐標軸刻度線樣式 tickLine: { length: 1, style: (item, index, items) => { return { stroke: "black", lineWidth: 2, lineDash: [4, 5], strokeOpacity: 0.7, shadowColor: "black", shadowBlur: 10, shadowOffsetX: 5, shadowOffsetY: 5, cursor: "pointer", }; }, }, min: 270, // 坐標軸最小值 這里指分鐘數(shù) tickCount: 20, // 坐標軸刻度數(shù)量 如果寫了下面的刻度間隔, 則數(shù)量優(yōu)先級變低 tickInterval: 30, // 坐標軸刻度間隔 }, isRange: true, // 柱形上面的文字 label: { content: "", }, // barBackground: { // style: { // fill: '#000', // fillOpacity: 0.01, // } // }, tooltip: { fields: ["type", "way", "module", "values"], // formatter:(data)=>{ // const { type,module,way,values} = data // console.log('data',data); // return { // name:module, // values:way // } // }, shared: false, // 只在鼠標懸浮到塊上再展示 showCrosshairs: false, customContent: (value, item) => { console.log("customContent", value, item[0]); if (!value || !item) return; const { data } = item[0]; const container = document.createElement("div"); setStyles(container, divStyles); container.innerHTML = `<div>車輛號碼${data.type}</div><div>往返:${data?.way}</div>`; return container; }, }, }); // 官方顏色主題 barPlot.update({ theme: { styleSheet: { brandColor: "#FF4500", paletteQualitative10: [ "#FF4500", "#1AAF8B", "#406C85", "#F6BD16", "#B40F0F", "#2FB8FC", "#4435FF", "#FF5CA2", "#BBE800", "#FE8A26", ], paletteQualitative20: [ "#FF4500", "#1AAF8B", "#406C85", "#F6BD16", "#B40F0F", "#2FB8FC", "#4435FF", "#FF5CA2", "#BBE800", "#FE8A26", "#946DFF", "#6C3E00", "#6193FF", "#FF988E", "#36BCCB", "#004988", "#FFCF9D", "#CCDC8A", "#8D00A1", "#1CC25E", ], }, }, }); 掛載 barPlot.render();
- 如果想查看本 demo 的效果, 可以把以上代碼直接復(fù)制到 自己的 HTML 文件中, 運行即可
- 參考 antv g2plot
以上就是antv完成區(qū)間柱形圖一列多柱配置實現(xiàn)詳解的詳細內(nèi)容,更多關(guān)于antv 區(qū)間柱形圖一列多柱配置的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
基于 flexible 的 Vue 組件:Toast -- 顯示框效果
這篇文章主要介紹了基于 flexible 的 Vue 組件:Toast -- 顯示框效果,需要的朋友可以參考下2017-12-12Vue組件化(ref,props,?mixin,.插件)詳解
這篇文章主要介紹了Vue組件化(ref,?props,?mixin,?插件)的相關(guān)知識,包括ref屬性,props配置項及mixin混入的方式,本文通過示例代碼多種方式相結(jié)合給大家介紹的非常詳細,需要的朋友可以參考下2022-05-05Vue中?引入使用?babel-polyfill?兼容低版本瀏覽器的方法
最近在項目中使用 webpack 打包后升級,用戶反饋使用瀏覽器(chrome 45)訪問白屏。經(jīng)過排查發(fā)現(xiàn):由于 chrome 45 無法兼容 ES6 語法導致的,接下來給大家介紹下Vue中?引入使用?babel-polyfill?兼容低版本瀏覽器方法,需要的朋友可以參考下2023-02-02Vue+Echarts實現(xiàn)分時圖和交易量圖的繪制
近來發(fā)現(xiàn)Echarts?API越發(fā)的強大,對于繪制各類圖形可以使用Echarts實現(xiàn)。本文將利用Echarts實現(xiàn)分時圖和交易量圖的繪制,希望對大家有所幫助2023-03-03