<div id="root">
</div>
.CircleSelect
{
  border-radius: 50%;
    background-color: #F8E600;
    display: flex;
    justify-content: center;
    align-items: center;
    float: left;
    border-color: black;
    border: thick solid;
}

.CircleSelectItem
{
   font-size: 20pt;
   font-weight: 800;
}

.CircleSelectItem:hover
{
    color: #F8E600;
}
function CircleSelectItem(params) {
    let angle = params.index * (360 / params.N);
    let x = params.x0 + Math.floor(2 * params.radius * Math.sin(Math.PI * 2 * angle / 360));
    let y = params.y0 + Math.floor(2 * params.radius * Math.cos(Math.PI * 2 * angle / 360));
    let xSideCoefficient = 0;
    let ySideCoefficient = 0;

    if (Math.abs(params.x0 - x) > 1 || Math.abs(params.y0 - y) > 1) {
        if (x < params.x0)
            xSideCoefficient = -1;
        if (x > params.x0)
            xSideCoefficient = 0;
        ySideCoefficient = -1;
    }

    if (Math.abs(params.x0 - x) < 5) {
        if (params.y0 < y)
            ySideCoefficient = 5;
        xSideCoefficient = -1 / 3;
    }


    return (
        <>
            <div style={{ left: x + xSideCoefficient * 100, top: y + ySideCoefficient * 5, position: 'absolute' }} className="CircleSelectItem" onClick={(e) => { params.handleSelect(e) }}>
                {params.value}
            </div>
        </>
    );
}

function Lines(params) {
    let angle = params.index * (360 / params.N);

    let x1 = params.x0 + Math.floor(params.radius * Math.sin(Math.PI * 2 * angle / 360));
    let y1 = params.y0 + Math.floor(params.radius * Math.cos(Math.PI * 2 * angle / 360));

    let x2 = params.x0 + Math.floor(2 * params.radius * Math.sin(Math.PI * 2 * angle / 360));
    let y2 = params.y0 + Math.floor(2 * params.radius * Math.cos(Math.PI * 2 * angle / 360));



    let sideCoefficient = 0;
    if (params.x0 !== x1 || params.y0 !== y1) {
        if (x1 < params.x0)
            sideCoefficient = -1;
        if (x1 > params.x0)
            sideCoefficient = 1;
    }
    return (
        <>
            <line  x1={params.x0} y1={params.y0} x2={x2} y2={y2} stroke="black" stroke-width="5" />
            <line  x1={x2} y1={y2} x2={x2 + sideCoefficient * 100} y2={y2} stroke="black" stroke-width="5" />

        </>
    );
}

function CircleSelect(params) {

    let radius = Math.floor(params.size / 2);
    let x0 = params.x0 + radius;
    let y0 = params.y0 + radius;
    const [selectedItems, setSelectedItems] = React.useState([]);
    const handleSelect = (e) => {
        let newArray = selectedItems.slice();
        let value = e.target.innerHTML
        if (newArray.includes(value)) {
            const index = newArray.indexOf(value);
            if (index > -1) {
                newArray.splice(index, 1);
            }
        }
        else { newArray.push(value); }



        setSelectedItems(newArray)
    }
    return (
        <>
            <div className="CircleSelect" style={{ width: params.size, height: params.size, left: params.x0, top: params.y0, position: 'absolute' }}>
                <h1 className="Centroid-title">Select</h1>
            </div>

            {params.data.map((value, index) => <CircleSelectItem handleSelect={handleSelect} x0={x0} y0={y0} radius={radius} index={index} value={value} N={params.data.length} />)}

            <svg width="1920" height="250">
                {params.data.map((value, index) => <Lines x0={x0} y0={y0} radius={radius} index={index} value={value} N={params.data.length} />)}
            </svg>
            Выбраны следующие элементы:
            <ul>
                {selectedItems.map((value) => <li>{value}</li>)}
            </ul>
        </>
    );
}



function Content() {
    const [data, setData] = React.useState(Array.from(new Array(6), (val, index) => "Option " + index));

    return (
        <>
            <input type="number" placeholder="Количество опций" onChange={(e) => { setData(Array.from(new Array(Number.parseInt(e.target.value)), (val, index) => "Option " + index)) }} />
            <CircleSelect data={data} size={100} x0={350} y0={60} />
        </>
    )
}

ReactDOM.render(
    <Content />,
    document.getElementById('root')
);
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://unpkg.com/react/umd/react.development.js
  2. https://unpkg.com/react-dom/umd/react-dom.development.js