最近接到一个关于彩带图的实现,具体需求是根据后台配置的分值区间以及对应的结论对应展示给用户,彩带图展示:每个区间要根据分数段占比展示。
实现思路:获取每个分值区间长度,得到总长度,再算出每个区间占总长度的百分比。剪头实现,先判断得分在哪个分值区间内,获取所在区间的总长度,得分在这个区间占的长度,得到剪头指向的位置。
效果图:
具体实现
import React from "react";
import PropTypes from "prop-types";
import "./index.less";
const ColorRamp = () => {
let RampListAll = [];
let totalRang = 0; //
let resultScore = 80; // 得分,箭头对应的位置
const colorRampList = [
{ id: 1, start: 0, end: 20, color: "#03C067", desc: "温和" },
{ id: 2, start: 20, end: 30, color: "#4A90F6", desc: "慢热" },
{ id: 3, start: 30, end: 45, color: "#FFAA00", desc: "不太平常" },
{ id: 4, start: 45, end: 70, color: "#FF7700", desc: "坚定自信最多八个" },
{ id: 5, start: 70, end: 90, color: "#FF2E22", desc: "热血冲动" },
];
colorRampList.map((item, index) => {
let items = {
id: item?.id,
start: item?.start,
end: item?.end,
rang: item?.end - item?.start,
color: item?.color,
desc: item?.desc,
checked: item?.start < resultScore && resultScore < item?.end,
percent: `${(item?.rang / (totalRang + item?.rang)) * 100}%`,
};
RampListAll.push(items);
});
return (
<div className="ramp-warpper" style={{ width: "calc(100% - 32px)" }}>
{RampListAll.map((list, index) => {
return (
<div className="item-ramp" style={{ width: list.percent }} key={index}>
<div className="arrow-content">
{list.checked && (
<div
style={{
left: `${((resultScore - list.start) / list.rang) * 100}%`,
borderColor: `${list.color} transparent transparent`,
}}
></div>
)}
</div>
<div
style={{ width: "100%", height: "4px", background: list.color }}
></div>
<div className="score-content">{list.desc}</div>
</div>
);
})}
</div>
);
};
ColorRamp.propTypes = {};
export default ColorRamp;
index.less文件
.ramp-warpper {
display: flex;
margin: 12px auto 0;
.item-ramp:first-child {
border-radius: 100px 0 0 100px;
}
.item-ramp:last-child {
border-radius: 0 100px 100px 0;
}
.item-ramp:not(:last-child) {
margin-right: 2px;
}
.item-ramp {
display: flex;
flex-direction: column;
.arrow-content {
height: 12px;
display: flex;
position: relative;
div {
position: absolute;
width: 0px;
height: 0px;
border-width: 8px 7px;
border-style: solid;
display: inline-block;
margin-left: -7px;
}
}
.score-content {
width: calc(100% - 24px);
display: flex;
justify-content: center;
padding: 10px 12px 0;
font-family: PingFangSC-Regular;
font-size: 10px;
color: #666666;
letter-spacing: 0;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
line-height: 14px;
text-align: center;
}
}
}