带有 HTML、CSS 和 JS 的圆表
Posted
技术标签:
【中文标题】带有 HTML、CSS 和 JS 的圆表【英文标题】:Circular Table with HTML , CSS and JS 【发布时间】:2022-01-20 19:05:15 【问题描述】:我正在尝试使用 html、JS 和 CSS 重新创建以下内容:
我的目标是能够用我想要的任何内容替换每个圈子中的内容,就像一个表格一样。
到目前为止,我已经阅读了以下帖子 - Circular HTML table。这个有一个答案,但我无法让它工作,它使用了一些 CSS 扩展
阅读完代码后,我尝试自己实现,并且能够做到这一点:
使用以下代码:codepen.io
function createLayer(radius)
let circleGraph = document.createElement("div");
circleGraph.classList.add("circlegraph");
circleGraph.style.width = `$radiuspx`;
circleGraph.style.height = `$radiuspx`;
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($thetarad) translate($radiuspx) `;
circle.style.transform += `rotate($Math.PI/2rad)`;
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;
我正在寻求一些帮助,使其与原始图像相匹配。如果您知道更好的方法而不是手动翻译每个元素,我很乐意看到它。
【问题讨论】:
使用 SVG 或画布 也许这对你有帮助 - blog.fofwebdesign.co.uk/… 我不知道如何给它一个曲线,但如果你在.circlegraph .circle ...
中添加width:50%
而不是px,这看起来会好一些。我对此提交了修改。
【参考方案1】:
从@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($pieRotateAnglerad)`;
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($rotationAnglerad) skew($skewAnglerad)`;
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($anchorSkewrad) rotate($anchorRotaterad)`;
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)。
鼠标悬停效果有一个小错误,即如果您将鼠标悬停在两个相邻部分之间的裂缝上,它将向外突出显示下一层(仅当下一层向外具有不同数量的单元格时才会发生)。
单元格中文本的位置并不完美,问题与行高有关(我已将其注释掉),欢迎修改以修复文本位置。
【讨论】:
只想说,出于兴趣一直在跟踪这个问题,干得好!所有相关人员都做得很好。 哇,那真是太好了。干得好。以上是关于带有 HTML、CSS 和 JS 的圆表的主要内容,如果未能解决你的问题,请参考以下文章
如何在 WebView Cocoa / Mac OS 上加载带有图像、js 和 css 的本地 html 文件
将 Bootstrap 主题(带有自定义 CSS 和 JS 插件)与带有 Webpacker 和 Yarn/NPM 的 Rails 6 集成