React+CSS 實現(xiàn)繪制橫向柱狀圖
前言:
頁面一共分為兩個結構
文字 + 漸變柱形圖為一個部分,下面的標注為一個結構。
我們先看文字 + 漸變柱形圖部分。
總體使用 flex 布局,左邊文字部分占總體的 50%,右邊的占剩余的空間部分。右側漸變柱形部分的寬度是動態(tài)變化的。寬度是根據(jù)傳入的 value,進行計算的。
<section className="graphs" style={style}> <div className="chart-1"> {listData.map((item, index) => { return ( <div className="chart-2" key={index}> <div className="chart-3"> <span>{item.name}</span> </div> <div className="chart-4"> <div style={{ width: `${item.percent}%`, height: 24 }} /> </div> </div> ) })} </div> </section>
.graphs { width: 100%; position: relative; .chart-1 { .chart-2 { display: flex; .chart-3 { flex: 0 0 auto; width: 50%; } .chart-4 { flex: 1 1 auto; } } } }
下方的標注部分,使用絕對定位,width = 50%,占父元素整體的一半,left = 50%,讓其定位在右側。這樣就實現(xiàn)了,標注和漸變柱形部分的重疊。
這部分將 li 標簽的 width = 1px,height = 100%,間隔通過 left 來動態(tài)實現(xiàn)。
<div className="bar-10"> <ul className="chart-11"> {scaleArray.map((item, itemIndex) => { return ( <li className="chart-12" style={{ left: `${(100 / scaleNum) * itemIndex}%` }} key={itemIndex} > <span>{item}</span> </li> ) })} </ul> </div>
.bar-10 { position: absolute; top: 0px; height: 100%; width: 50%; left: 50%; box-sizing: border-box; .chart-11 { height: 100%; position: relative; width: 100%; .chart-12 { position: absolute; top: -3px; width: 1px; height: 89%; border-right: 1px solid #d7dbe0; } } }
關于數(shù)值的計算,這里筆者是找到這一組數(shù)據(jù)里面的最大值
let maxValue = 0; data.forEach((dataItem) => { if (dataItem.value > maxValue) maxValue = dataItem.value; });
獲取最大值最近的100整數(shù)
let maxScaleNum = Math.ceil(maxValue / 100) * 100
求取最小公倍數(shù)
let lcm = getLcm(maxScaleNum, scaleNum)
計算每一個數(shù)據(jù)的 value,占最小公倍數(shù)的百分比。
percent: (dataItem.value / lcm) * 100
標注的left,使用 for 循環(huán)生成。
const newArray = new Array(); for (let i = 0; i <= lcm; i += lcm / scaleNum) { newArray.push(i); }
整體代碼:
import React, { useState, useEffect } from 'react'; import ReactDom from 'react-dom'; function getGcd(a, b) { let max = Math.max(a, b); let min = Math.min(a, b); if (max % min === 0) { return min; } else { return getGcd(max % min, min); } } function getLcm(a, b) { return a * b / getGcd(a, b); } const Test = ({ data, style, scaleNum = 5 }) => { const [listData, setListData] = useState([]) const [scaleArray, setScaleArray] = useState([]) useEffect(() => { if (scaleNum <= 0) { return } let maxValue = 0 data.forEach((dataItem) => { if (dataItem.value > maxValue) maxValue = dataItem.value }) let maxScaleNum = Math.ceil(maxValue / 100) * 100 let lcm = getLcm(maxScaleNum, scaleNum) if (maxValue <= 0) { const newArray = [0] let number = 0 for (let i = 0; i < scaleNum; i++) { newArray.push((number += 20)) } setScaleArray(newArray) setListData( data.map((dataItem) => { return { name: dataItem.name, percent: 0, value: dataItem.value } }) ) return } setListData( data.map((dataItem) => { return { name: dataItem.name, percent: (dataItem.value / lcm) * 100, value: dataItem.value } }) ) const newArray = new Array() for (let i = 0; i <= lcm; i += (lcm / scaleNum)) { newArray.push(i) } setScaleArray(newArray) }, [data, scaleNum]) return ( <section className="graphs" style={style}> <div className="chart-1"> {listData.map((item, index) => { return ( <div className="chart-2" key={index}> <div className="chart-3"> <span>{item.name}</span> </div> <div className="chart-4"> <div style={{ width: `${item.percent}%`, height: 24 }} /> </div> </div> ) })} </div> <div className="bar-5"> <ul className="chart-6"> {scaleArray.map((item, itemIndex) => { return ( <li className="chart-7" style={{ left: `${(100 / scaleNum) * itemIndex}%` }} key={itemIndex} > <span>{item}</span> </li> ) })} </ul> </div> </section> ) } ReactDom.render(<Test style={{ width: 440 }} scaleNum={6} data={[ { name: '西瓜', value: 40 }, { name: '菠蘿', value: 56 }, { name: '香蕉', value: 47 } ]} />, document.getElementById('app'));
運行結果:
到此這篇關于React+CSS 實現(xiàn)繪制橫向柱狀圖的文章就介紹到這了,更多相關React+CSS 柱狀圖內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
React中的useState和setState的執(zhí)行機制詳解
這篇文章主要介紹了React中的useState和setState的執(zhí)行機制,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03React項目中fetch實現(xiàn)跨域接收傳遞session的解決方案
這篇文章主要介紹了React項目中fetch實現(xiàn)跨域接收傳遞session的解決方案,本次項目使用了react框架,同時使用fetch取代ajax作為獲取接口數(shù)據(jù)的交互方法,下面就對這次問題的解決做個總結,需要的朋友可以參考下2022-04-04React循環(huán)遍歷渲染數(shù)組和對象元素方式
這篇文章主要介紹了React循環(huán)遍歷渲染數(shù)組和對象元素方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09