如何在这个层圆的多层中定位元素,使元素均匀分布并距中心等距?

问题描述 投票:0回答:1

我拥有的CSS同心圆图像 我需要在给定 json 列表的情况下动态显示项目,但我需要知道的是如何将所有项目放在正确的位置。我想做一些类似的事情 A 层(内圆)= 距中心 20 像素,B 层(距中心第二个圆)= 距中心 120 像素,依此类推 并用(距离中心,角度)对来定位项目,从顶部开始的角度为 0。 有没有办法做到这一点?或者用更简单的方法来做?

import React from 'react'
import styles from './test.module.css'

export default function RadarComponent() {
  return (
    <div className={styles.container}>
        <h1>Radar Cadmus</h1>
        <div className={styles.circleOne}>
            <div className={styles.circleTwo}>
                <div className={styles.circleThree}>
                    <div className={styles.circleFour}>

                    </div>
                </div>
            </div>
        </div>
    </div>
  );
}
.container{
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  border: 1px solid #000;
}

.circleOne{
    border-radius: 50% 50% 50% 50% / 50% 50% 50% 50% ;
    background-color: green;
    width: 700px;
    height: 700px;
    align-items: center;
    display: flex;
    justify-content: center;
}

.circleTwo{
    border-radius: 50% 50% 50% 50% / 50% 50% 50% 50% ;
    background-color: rgb(128, 255, 0);
    width: 550px;
    height: 550px;
    align-items: center;
    display: flex;
    justify-content: center;
}

.circleThree{
    border-radius: 50% 50% 50% 50% / 50% 50% 50% 50% ;
    background-color: rgb(242, 255, 0);
    width: 400px;
    height: 400px;
    align-items: center;
    display: flex;
    justify-content: center;
}

.circleFour{
    border-radius: 50% 50% 50% 50% / 50% 50% 50% 50% ;
    background-color: rgb(255, 153, 0);
    width: 250px;
    height: 250px;
    align-items: center;
    display: flex;
    justify-content: center;
}

我尝试使用 ChartJs 雷达,但问题是我无法使各部分具有不同的颜色,并且数据集中添加的一项会更改所有项目的整体位置,因为雷达图具有相对位置。

'use client';

import React from 'react';
import { Radar } from 'react-chartjs-2';
import {
  Chart as ChartJS,
  RadialLinearScale,
  PointElement,
  LineElement,
  Filler,
  Tooltip,
  Legend,
} from 'chart.js';

ChartJS.register(
  RadialLinearScale,
  PointElement,
  LineElement,
  Filler,
  Tooltip,
  Legend,
);


const data = {
  labels: ['Eating', 'Drinking', 'Sleeping', 'Designing', 'Coding', 'Cycling', 'Running'],
  datasets: [{
    label: 'My First Dataset',
    data: [65, 59, 90, 81, 56, 55, 40],
    fill: false, // Não preencher o fundo
    borderColor: 'transparent', // Tornar a linha invisível
    pointBackgroundColor: '#415364', // Cor das bolinhas
    pointBorderColor: '#415364',
    pointHoverBackgroundColor: '#415364',
    pointHoverBorderColor: '#fff',
    pointRadius: 5, // Tamanho das bolinhas
  }]
};

const options = {
  elements: {
    line: {
      borderWidth: 3,
    },
  },
  scales: {
    r: {
      backgroundColor: 'rgba(0, 255, 0 , 1)',
      angleLines: {
        display: false, //if true shows angleLines that cross with the ticks
      },
      grid: {
        circular: true, //this allows the ticks to be circular and not polygonal
        color: 'rgba(0, 0, 0, 1)',
      },
      ticks: { //a tick is one of the circunferences of the chart
        color: 'black',
        count: 5, //number of ticks
        display: false, //if true show tick labels
      },
      pointLabels: {
        font: {
          size: 12,
          weight: 'bold',
        },
        color: 'black',
      },
    },
  },
  plugins: {
    legend: {
      display: false
    },
    tooltip: {
      enabled: true,
    },
  },
};

// Função para obter o texto do marcador
const getMarkerText = (value: number) => {
  if (value >= 75) return 'Alto';
  if (value >= 50) return 'Médio';
  return 'Baixo';
};

export default function RadarComponent() {
    
  return (
    <div style={{ width: '600px', height: '600px' }}>
      <Radar options={options} data={data}/>
    </div>
  );
}

在此输入图片描述

javascript html css reactjs chart.js
1个回答
0
投票

我建议一种相当简单的方法 - 将每个斑点作为背景放置在一个细长元素中,该元素的高度为圆的半径,并根据其子位置(0 到 6)旋转该元素。

此代码片段还通过将标签放置在每个旋转元素内的元素中来将标签放置到位 - 并再次旋转回来以使它们全部水平。

注意:此代码片段还将背景圆圈绘制为 CSS 背景,但如果您确实需要它们成为 4 个单独的元素,请使用您的原始代码。

<style>
  * {
    margin: 0;
  }
  
  body {
    display: flex;
    align-items: center;
    justify-content: center;
  }
  
  .chart {
    background-image: radial-gradient(rgb(255, 153, 0) 0 17.5%, rgb(242, 255, 0) 17.5% 35%, rgb(128, 255, 0) 35% 52.5%, green 52.5% 70%, transparent 70% 100%);
    --r: 40vmin;
    width: calc(2 * var(--r));
    aspect-ratio: 1;
    border-radius: 50%;
    position: relative;
  }
  
  .datum {
    position: absolute;
    bottom: 50%;
    left: 50%;
    width: 10vmin;
    height: var(--r);
    transform: translateX(-50%) rotate(calc(1deg * var(--n) * 360 / var(--num)));
    transform-origin: center bottom;
    background-image: radial-gradient(gray 0 70%, transparent 70% 100%);
    background-repeat: no-repeat;
    background-position: center calc(var(--r) - ((var(--data) * var(--r)) / 100));
    background-size: 2vmin 2vmin;
  }
  
  .blob {
    transform: rotate(calc(-1deg * var(--n) * 360 / var(--num)));
    display: inline-block;
    position: absolute;
    top: -2em;
  }
</style>

<body>
  <div class="chart"></div>
</body>
<script>
  const labels = ['Eating', 'Drinking', 'Sleeping', 'Designing', 'Coding', 'Cycling', 'Running'];
  const data = [65, 59, 90, 81, 56, 55, 40];
  const num = labels.length;
  const chart = document.querySelector('.chart');
  chart.style.setProperty('--num', num);
  for (let n = 0; n < num; n++) {
    const datum = document.createElement('div');
    datum.classList.add('datum');
    datum.style.setProperty('--n', n);
    datum.style.setProperty('--data', data[n]);
    const blob = document.createElement('div');
    blob.innerHTML = labels[n];
    blob.classList.add('blob');
    datum.appendChild(blob);
    chart.appendChild(datum);
  }
</script>

© www.soinside.com 2019 - 2024. All rights reserved.