antv完成區(qū)間柱形圖一列多柱配置實(shí)現(xiàn)詳解
使用antv 配置區(qū)間柱形圖

需求: 來源與產(chǎn)品的一個(gè)想法,想在 X 軸 每一行輸出多個(gè)區(qū)間柱形,以時(shí)間為分段,X軸 底線顯示時(shí)間, 找了一下 echarts 的實(shí)現(xiàn), 可以使用配置函數(shù)的方式 實(shí)現(xiàn),但只實(shí)現(xiàn)了一行,而且函數(shù)的配置項(xiàng)其API 文檔也晦澀難懂, 最后使用 antv 的 區(qū)間柱形圖來實(shí)現(xiàn), 但是 antv 無法像 echarts 一樣配置每一個(gè)柱形的顏色, 因?yàn)樗?color 配置回調(diào)函數(shù)只接受一個(gè) type 字符串類型, 最后使用了數(shù)組隊(duì)列匹配的方式來實(shí)現(xiàn)
使用的是 antv 的 g2plot 官方分組柱形圖效果如下: 定位鏈接: g2plot.antv.vision/zh/examples…

實(shí)現(xiàn)之后的效果

分享思路
- 文件引入 這里是 html 文件, 直接可以復(fù)制, 下面的 js 文件我我們通過引入 CDN 的方式,這樣在使用 demo 的時(shí)候更加方便
<!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ù)當(dāng)中使用到的
// 時(shí)間處理
// 小時(shí)轉(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)小時(shí)
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];
}
};
// 動(dòng)態(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ù)邏輯處理
注意點(diǎn):
- 數(shù)據(jù)使用的是假數(shù)據(jù), 這里我們可以根據(jù)自己的業(yè)務(wù)需求進(jìn)行修改和擴(kuò)展 因?yàn)閰^(qū)間柱形圖使用的數(shù)據(jù) data 是一個(gè)數(shù)組, 所以在使用我們的數(shù)據(jù)的時(shí)候需要進(jìn)行一下改造
- 在使用 color 回調(diào)函數(shù)進(jìn)行配置顏色的時(shí)候,不知道里面的循環(huán)為什么會進(jìn)入兩次,如果有大佬可以解答或有其他解決方案歡迎交流, 這里我使用了一個(gè)閉包的方式來記錄次數(shù),因?yàn)檫@里的數(shù)據(jù)我們業(yè)務(wù)上還沒有和后端對接,所以暫時(shí)無法判定哪一條是第一個(gè)數(shù)據(jù),而且 color 這回調(diào)函數(shù)也不提供 其他參數(shù), 只提供一個(gè) type 是字符串 作為參數(shù), 所以我在上面數(shù)據(jù)處理的方法里面自己加入了一個(gè) 空字符的 type,用來區(qū)分循環(huán)的進(jìn)入。
- 因?yàn)?color 方法的參數(shù)只有 type, 所以我也無法區(qū)分當(dāng)前應(yīng)該顯示哪一種顏色, 數(shù)據(jù)里面的 way 就是顏色, 這里我使用了一個(gè)臨時(shí)隊(duì)列 arr 也是以閉包的形式存儲, 然后從我處理好的數(shù)據(jù)中 過濾出當(dāng)前 type 類型組成的一個(gè)數(shù)組, 通過下標(biāo)的方式 取到當(dāng)前對應(yīng)的數(shù)據(jù)
- tooltip 如果想要自定義的話 需要使用 customContent API
- 由于我們這柱形一行有多個(gè), 默認(rèn)是鼠標(biāo)懸浮到當(dāng)前行,沒有到我們的柱上,就會有 tooltip 提示, 可以設(shè)置shared 來匹配鼠標(biāo)懸浮到柱形上才顯示 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)進(jì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ù)長度,掛載點(diǎn),以及高度 三個(gè)參數(shù)來進(jìn)行設(shè)置
setHeigh(busDataInfo, "root", 60);
const data = changeData(busDataInfo);
// 畫布實(shí)例化
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)會進(jìn)入兩次的問題
if (count !== 1) return;
arr.push(type);
let currentArr = data.filter((item) => item.type === type);
let filterArr = arr.filter((item) => item === type);
// 獲取當(dāng)前往返類型
const wayType = currentArr[filterArr.length - 1]?.way;
console.log("type", type, wayType, currentArr);
if (wayType === "E") {
return "#FF5CA2";
}
return "#6C3E00";
};
})(),
xAxis: {
// x軸文本標(biāo)簽配置項(xiàng)
label: {
formatter: (value) => {
return ChangeHourMinutestr(value);
},
},
// 坐標(biāo)軸網(wǎng)格線的配置項(xiàng)
grid: {
// alignTick:false,
},
// 坐標(biāo)軸線樣式
// line:
// {
// style:
// {
// stroke: 'black',
// lineWidth: 1,
// strokeOpacity: 0.7,
// shadowColor: 'black',
// shadowBlur: 10,
// shadowOffsetX: 5,
// shadowOffsetY: 5,
// cursor: 'pointer'
// }
// },
// 坐標(biāo)軸刻度線樣式
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, // 坐標(biāo)軸最小值 這里指分鐘數(shù)
tickCount: 20, // 坐標(biāo)軸刻度數(shù)量 如果寫了下面的刻度間隔, 則數(shù)量優(yōu)先級變低
tickInterval: 30, // 坐標(biāo)軸刻度間隔
},
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, // 只在鼠標(biāo)懸浮到塊上再展示
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 文件中, 運(yùn)行即可
- 參考 antv g2plot
以上就是antv完成區(qū)間柱形圖一列多柱配置實(shí)現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于antv 區(qū)間柱形圖一列多柱配置的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue實(shí)現(xiàn)點(diǎn)擊出現(xiàn)操作彈出框的示例
這篇文章主要介紹了vue實(shí)現(xiàn)點(diǎn)擊出現(xiàn)操作彈出框的示例,幫助大家更好的理解和使用vue,感興趣的朋友可以了解下2020-11-11
基于 flexible 的 Vue 組件:Toast -- 顯示框效果
這篇文章主要介紹了基于 flexible 的 Vue 組件:Toast -- 顯示框效果,需要的朋友可以參考下2017-12-12
Vue組件化(ref,props,?mixin,.插件)詳解
這篇文章主要介紹了Vue組件化(ref,?props,?mixin,?插件)的相關(guān)知識,包括ref屬性,props配置項(xiàng)及mixin混入的方式,本文通過示例代碼多種方式相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
Vue中?引入使用?babel-polyfill?兼容低版本瀏覽器的方法
最近在項(xiàng)目中使用 webpack 打包后升級,用戶反饋使用瀏覽器(chrome 45)訪問白屏。經(jīng)過排查發(fā)現(xiàn):由于 chrome 45 無法兼容 ES6 語法導(dǎo)致的,接下來給大家介紹下Vue中?引入使用?babel-polyfill?兼容低版本瀏覽器方法,需要的朋友可以參考下2023-02-02
Vue+Echarts實(shí)現(xiàn)分時(shí)圖和交易量圖的繪制
近來發(fā)現(xiàn)Echarts?API越發(fā)的強(qiáng)大,對于繪制各類圖形可以使用Echarts實(shí)現(xiàn)。本文將利用Echarts實(shí)現(xiàn)分時(shí)圖和交易量圖的繪制,希望對大家有所幫助2023-03-03
詳解vue2如何實(shí)現(xiàn)點(diǎn)擊預(yù)覽本地文件
這篇文章主要為大家詳細(xì)介紹了vue2如何實(shí)現(xiàn)點(diǎn)擊預(yù)覽本地的word、excle、pdf文件,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04

