網站首頁 編程語言 正文
前言:
頁面一共分為兩個結構
文字 + 漸變柱形圖為一個部分,下面的標注為一個結構。
我們先看文字 + 漸變柱形圖部分。
總體使用 flex 布局,左邊文字部分占總體的 50%,右邊的占剩余的空間部分。右側漸變柱形部分的寬度是動態變化的。寬度是根據傳入的 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%,讓其定位在右側。這樣就實現了,標注和漸變柱形部分的重疊。
這部分將 li 標簽的 width = 1px,height = 100%,間隔通過 left 來動態實現。
<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;
}
}
}
關于數值的計算,這里筆者是找到這一組數據里面的最大值
let maxValue = 0;
data.forEach((dataItem) => {
if (dataItem.value > maxValue) maxValue = dataItem.value;
});
獲取最大值最近的100整數
let maxScaleNum = Math.ceil(maxValue / 100) * 100
求取最小公倍數
let lcm = getLcm(maxScaleNum, scaleNum)
計算每一個數據的 value,占最小公倍數的百分比。
percent: (dataItem.value / lcm) * 100
標注的left,使用 for 循環生成。
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'));
運行結果:
原文鏈接:https://juejin.cn/post/7142290948104388615
相關推薦
- 2023-03-20 C#中程序自刪除實現方法_C#教程
- 2022-10-29 vite 配置 @ 路徑別名
- 2022-07-21 push函數,將一個數組添加到另一個數組的尾部
- 2022-05-21 Python中三種花式打印的示例詳解_python
- 2022-06-19 python繪制餅圖和直方圖的方法_python
- 2022-06-28 react18中react-redux狀態管理的實現_React
- 2023-07-05 settings delete global hidden_api_policy_pre_p_app
- 2023-01-09 使用C#?11的靜態接口方法改進?面向約定?的設計方法_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支