reactjs 创建符合规范的React组件时出现问题

vc6uscn9  于 2023-01-25  发布在  React
关注(0)|答案(1)|浏览(105)

我正在尝试创建一个react组件来匹配此图像:但似乎不能得到正确的。该组件采取了一个百分比,并根据该百分比增加颜色的面积,虚线是100%标记和外部部分是200%,所以在0%,它将是所有白色的,在200%和超过整个甜甜圈将是橙子的
到目前为止,我尝试使用css径向梯度来解决,但没有效果,因为梯度从整个组件的中心开始,所以在大约前60%是不可见的,我也查看了highcharts,但我遇到的似乎没有什么适合的设计。有什么建议的库,有这样的组件或推荐的解决方式?

kh212irz

kh212irz1#

此React组件为图形的外部元素和内部元素创建一个ref。这样,该组件就可以访问每个元素的宽度来计算图形的边框宽度。特别是,它可以计算图形的最大强度(内外宽度之差),然后将其乘以提供给组件的值以确定边框宽度。通过使用ref,该组件能够访问计算边界宽度所需的相关数据而不必重新呈现该组件。
如果你决定在CSS中不使用固定值,而是选择通过 prop 来动态调整大小,那么引用就不是必需的,可以用 prop 来代替。

import { createRef, useEffect, useState } from 'react';
import css from './graph.module.css';

export interface GraphProps {
  value: number;
}

function IntensityGraph(props: GraphProps) {
  const [borderWidth, setBorderWidth] = useState<number>(0);
  const outerRef = createRef<HTMLDivElement>();
  const innerRef = createRef<HTMLDivElement>();
  const { value } = props;

  useEffect(() => {
    if (outerRef.current !== null && innerRef.current !== null) {
      const { clientWidth: outerWidth } = outerRef.current;
      const { clientWidth: innerWidth } = innerRef.current;
      const maxIntensity = outerWidth - innerWidth;

      setBorderWidth(((maxIntensity / 100) * value) / 4);
    }
  }, [value, setBorderWidth]);

  return (
    <div ref={outerRef} className={css.outer}>
      <div ref={innerRef} className={css.inner} style={{ borderWidth }}>
        <h1>{value}%</h1>
        <h3>Intensity</h3>
      </div>
    </div>
  );
}

export default IntensityGraph;
.outer {
  display: grid;
  place-items: center;
  place-content: center;
  border-radius: 50%;
  background-color: rgb(255 255 255 / 0.15);
  outline-color: rgb(255 255 255 / 0.2);
  outline-style: dashed;
  outline-offset: -2rem;
  overflow: hidden;
  width: 16rem;
  height: 16rem;
}

.inner {
  display: grid;
  place-items: center;
  place-content: center;
  gap: 0.5rem;
  background-color: white;
  color: #242424;
  border-radius: 50%;
  border-style: solid;
  border-color: orange;
  padding: 0.5rem;
  transition: border-width 0.3s linear;
  width: 8rem;
  height: 8rem;
  text-transform: uppercase;
}

.inner > * {
  margin: 0;
}

相关问题