循环 Table 与 HTML , CSS 和 JS

Circular Table with HTML , CSS and JS

我正在尝试使用 HTML、JS 和 CSS 重新创建以下内容:

我的目标是能够将每个圈子中的内容替换成我想要的任何内容,就像table。

到目前为止,我已阅读以下 post - 。这个有答案,但我无法让它工作,它使用了一些 CSS 扩展

阅读代码后,我尝试自己实现,并且能够做到这一点:

使用以下代码:codepen.io

    function createLayer(radius) {
        let circleGraph = document.createElement("div");
        circleGraph.classList.add("circlegraph");
        circleGraph.style.width = `${radius}px`;
        circleGraph.style.height = `${radius}px`;
        for (let j = 0; j < 12; j++) {
            let note = document.createElement("div");
            note.classList.add("circle");
            note.classList.add("center");
            let content = document.createTextNode(`${j}`)
            note.appendChild(content);
            circleGraph.appendChild(note);
        }
        let circles = circleGraph.querySelectorAll( '.circle' )
        let theta = 0, dtheta = Math.PI * 2 / circles.length
        for( let i = 0; i < circles.length; ++i ){
            let circle = circles[i]
            theta += dtheta
            circle.style.transform = `translate(-50%, -50%) rotate(${theta}rad) translate(${radius}px) `;
            circle.style.transform += `rotate(${Math.PI/2}rad)`;
        }
        document.body.appendChild(circleGraph)
    }

    createLayer(100);
    createLayer(150);
    createLayer(200);
    createLayer(250);
    html, body {
        margin: 0;
        height: 100%;
    }

    .circlegraph {
        margin: auto;
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
    }


    .circlegraph .circle {
        position: absolute;
        top: 50%; left: 50%;
        width: 50%;
        height: 50px;
        transform-origin: center;
        border: 1px solid red;
        /*border-radius: 50%;*/
    }

    .center{
        display: flex;
        justify-content: center;
        align-items: center;
    }

我希望得到一些帮助,使其与原始图像相匹配。如果您知道比手动翻译每个元素更好的方法,我很乐意看到它。

从@HoratioNullbuilt 的评论中获得灵感,我能够对他们链接的示例进行可扩展的修改:

http://blog.fofwebdesign.co.uk/16-circular-segment-pie-chart-menu-experimental

之所以需要对其进行扩展,是因为许多值都是硬编码的,例如,您不能在不同的层中包含不同数量的元素。

这里修改后的结果是:

https://codepen.io/cuppajoeman/pen/oNGwxzQ

radial.js

let data =  [
    Array.from(Array(15).keys()).map(String),
    Array.from(Array(13).keys()).map(String),
    Array.from(Array(10).keys()).map(String),
    Array.from(Array(7).keys()).map(String),
    Array.from(Array(4).keys()).map(String),
]

function getRandomHTMLColor() {
    var r = 255*Math.random()|0,
        g = 255*Math.random()|0,
        b = 255*Math.random()|0;
    return 'rgb(' + r + ',' + g + ',' + b + ')';
}

function createPieMenu() {
    let pieMenu = document.createElement("div");
    pieMenu.id = "pie-menu"
    pieMenu.classList.add("pie-outer");

    let widthDelta = 100/data.length;
    let widthPercentage = 100;

    for (let i = 0; i < data.length; i ++) {
        let dataItem = data[i];
        let numSegments = dataItem.length;
        let segmentAngle = (Math.PI * 2)/numSegments;
        let skewAngle = (Math.PI/2) - segmentAngle;

        let pie = document.createElement("div");
        let pieRotateAngle = (Math.PI/2) - segmentAngle/2;
        pie.classList.add("pie");
        console.log(widthPercentage);

        pie.style.width = `${widthPercentage}%`;
        pie.style.background = getRandomHTMLColor();

        pie.style.transform = `translate(-50%,-50%) rotate(${pieRotateAngle}rad)`;

        let pieList = document.createElement("ul");

        for (let j = 0; j < dataItem.length; j ++) {
            let rotationAngle = segmentAngle * j;
            let dataContent = dataItem[j];
            let pieListItem = document.createElement('li'); // create a new list item
            let pieItemAnchor = document.createElement('a'); // create a new list item

            pieListItem.style.transform = `rotate(${rotationAngle}rad) skew(${skewAngle}rad)`;

            pieItemAnchor.appendChild(document.createTextNode(dataContent)); // append the text to the li
            let anchorRotate = segmentAngle/2 - Math.PI/2;
            let anchorSkew = segmentAngle - Math.PI/2;
            pieItemAnchor.style.transform = `skew(${anchorSkew}rad) rotate(${anchorRotate}rad)`;

            pieListItem.appendChild(pieItemAnchor);
            pieList.appendChild(pieListItem)
        }
        pie.appendChild(pieList);
        pieMenu.appendChild(pie);
        widthPercentage -= widthDelta;
    }

    document.body.appendChild(pieMenu);
}

createPieMenu();

radial.css

html, body {
    margin:0;
    padding:0;
    font:1em/1.75 Verdana, Arial, Helvetica, sans-serif;
    -ms-text-size-adjust:100%;
    -webkit-text-size-adjust:100%
}

.pie-outer *, .pie-outer {
    padding:0;
    margin:0
}

.pie-outer {
    position:relative;
    padding-top:100%;
    margin:auto
}

.pie {
    pointer-events:none;
    position:absolute;
    top:50%;
    left:50%;
    overflow:hidden;
    border:2px solid #000;
    border-radius:50%;
}

.pie ul {
    list-style-type:none
}

.pie ul:after {
    content:" ";
    display:block;
    width:100%;
    padding-top:100%
}

.pie li {
    position:absolute;
    top:-50%;
    left:-50%;
    width:100%;
    height:100%;
    margin-left:-2px;
    margin-top:-2px;
    overflow:hidden;
    border:1px solid #000;
    -webkit-transform-origin:100% 100%;
    -ms-transform-origin:100% 100%;
    transform-origin:100% 100%
}


.pie a {
    pointer-events:auto;
    font-size:2.125vw;
    /*line-height:170%;*/
    display:block;
    position:absolute;
    top:50%;
    left:50%;
    width:100%;
    height:100%;
    text-decoration:none;
    text-align:center;
    color:#fff;
    -webkit-tap-highlight-color:rgba(0,0,0,0);
}

.pie a:hover {
    background:rgba(255,255,255,0.25)
}

@media ( min-width:42em ) {
    /* #### - > 672px - #### */
    .pie-outer {
        padding-top:0;
        width:40em;
        height:40em
    }
    .pie a {
        font-size:1em
    }

}

radial.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Circular Menu</title>
    <link rel="stylesheet" href="radial.css">
</head>
<body>
    <script src="radial.js"></script>
</body>
</html>

一些注意事项:

当您的数据列表包含大小为 2 的列表时,上面的代码不起作用,但我还没有深入探讨为什么会发生这种情况(可能某些边缘情况适用于大小 1 和 2)。

鼠标悬停效果有一个小bug,就是如果你悬停在两个相邻部分之间的裂缝上,它会向外突出下一层(似乎只有当向外的下一层有不同数量的单元格时才会发生).

文本在单元格中的位置不完美,问题与行高有关(我注释掉了),欢迎修改以修复文本位置。

从@cuppajoeman 获得灵感--

如果您修改数组构建器,您的单元格可以包含您想要的任何内容。 只需删除 '.keys()' 函数,因为它会将所有内容都转换为数字,并将实际数据而不是数字放在第二个 'Array()'

您还可以添加和删除 'Array.from(Array()' 行,整个过程将 auto-adjust。

let data =  [
//    Array.from(Array(32).keys()).map(String),
//    Array.from(Array(32).keys()).map(String),
//    Array.from(Array(16).keys()).map(String),
//    Array.from(Array(4).keys()).map(String),
//    Array.from(Array(1).keys()).map(String),

// ************************************
// *** trying to put text in boxes  ***
// ************************************
            
Array.from(Array("1","2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32")).map(String),
Array.from(Array("Nehrdas", "Jahdas", "Gahldas", "Dehrdas", "Elimdas", "Iadas", "Zepdas", "Makda", "Nehrdas", "Jahdas", "Gahldas", "Dehrdas", "Elimdas", "Iadas", "Zepdas", "Makda", "Nehrdas", "Jahdas", "Gahldas", "Dehrdas", "Elimdas", "Iadas", "Zepdas", "Makda", "Nehrdas", "Jahdas", "Gahldas", "Dehrdas", "Elimdas", "Iadas", "Zepdas", "Makda")).map(String),
Array.from(Array("Solaris", "Seprensdor", "Fonsoc", "Ganrehm", "Calidum", "Somnercrest", "Aesoc", "Jehmri", "Lunaris", "Autunsveil", "Cadoc", "Nehnma", "Frigus", "Wevnercrest", "Hemoc", "Duhmret")).map(String),
Array.from(Array(16)).map(String),
Array.from(Array(4)).map(String),
        
// ************************************
// *** END trying to put text in boxes  ***
// ************************************

]