当前位置:网站首页>D3.js打造酷炫圆弧图
D3.js打造酷炫圆弧图
2022-07-15 16:32:00 【紫微前端】

<main></main>
<script src="https://unpkg.com/[email protected]/dist/d3.min.js"></script>
<style>
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
body {
background: hsl(240, 20%, 10%);
font-family: "Biryani", sans-serif;
}
main {
max-width: 40rem;
width: 95vw;
margin: 1rem auto;
padding: 1.25rem;
border-radius: 0.5rem;
color: hsl(0, 0%, 100%);
background: hsl(240, 15%, 20%);
box-shadow: 0 2px 15px hsl(240, 20%, 10%);
}
main h1 {
font-size: 1.75rem;
}
main > svg {
margin-top: 1rem;
width: 100%;
height: auto;
display: block;
}
</style>
<script>
const nodes = [
"HTML",
"Haml",
"Markdown",
"Slim",
"Pug",
"CSS",
"LESS",
"SCSS",
"Sass",
"Stylus",
"PostCSS",
"JavaScript",
"Babel",
"TypeScript",
"CoffeeScript",
"LiveScript"
];
// set html as the root node
const links = [
{ source: "HTML", target: "CSS" },
{ source: "HTML", target: "JavaScript" },
{ source: "HTML", target: "Haml" },
{ source: "HTML", target: "Markdown" },
{ source: "HTML", target: "Slim" },
{ source: "HTML", target: "Pug" },
{ source: "CSS", target: "LESS" },
{ source: "CSS", target: "SCSS" },
{ source: "CSS", target: "Sass" },
{ source: "CSS", target: "Stylus" },
{ source: "CSS", target: "PostCSS" },
{ source: "JavaScript", target: "Babel" },
{ source: "JavaScript", target: "TypeScript" },
{ source: "JavaScript", target: "CoffeeScript" },
{ source: "JavaScript", target: "LiveScript" }
];
const main = d3.select("main");
main.append("h1").text("Arc Diagram");
// change the dimensions according to the gap between the nodes, and the number of nodes itself
const gap = 30;
const padding = {
top: 20,
right: 20,
bottom: 150,
left: 20
};
const width = nodes.length * gap;
// for the height consider the syntax of the d attribute for the path elements
// the steeper the arc, the taller the container
const height = width * 0.4;
const svg = main
.append("svg")
.attr("width", width + (padding.left + padding.right))
.attr("height", height + (padding.top + padding.bottom))
.attr(
"viewBox",
`-${padding.left} -${padding.top + height} ${
width + (padding.left + padding.right)
} ${height + (padding.top + padding.bottom)}`
);
const scaleX = d3.scaleBand().domain(nodes).range([0, width]);
const scaleColor = d3.schemeSet2;
svg.attr("transform", `translate(${scaleX.bandwidth() / 2} 0)`);
// links
svg.append("g").attr("class", "links");
d3
.select(".links")
.selectAll("path.link")
.data(links)
.enter()
.append("path")
.attr("class", "link")
.attr("fill", "none")
.attr("stroke", "currentColor")
.attr(
"stroke",
({ source }) =>
scaleColor[nodes.findIndex((d) => d === source) % scaleColor.length]
)
.attr("stroke-width", 3)
.attr("d", ({ source, target }) => {
const x0 = scaleX(source);
const x1 = scaleX(target);
return `M ${x0} 0 A ${(x1 - x0) / 2} ${(x1 - x0) / 2} 0 0 1 ${x1} 0`;
});
// nodes
svg.append("g").attr("class", "nodes");
d3
.select(".nodes")
.selectAll("g.node")
.data(nodes)
.enter()
.append("g")
.attr("class", "node")
.attr("transform", (d) => `translate(${scaleX(d)} 0)`)
.attr("fill", (d, i) => scaleColor[i % scaleColor.length]);
d3.selectAll("g.node").append("circle").attr("r", 7);
d3
.selectAll("g.node")
.append("text")
.attr("y", 15)
.style("writing-mode", "vertical-rl")
.style("font-weight", "900")
.style("text-shadow", "0 0 5px -4px hsl(0, 0%, 0%)")
.text((d) => d);
// animate only if the media query doesn't specify reduced motion
const prefersReducedMotion = window.matchMedia(
"(prefers-reduced-motion: reduce)"
);
if (!prefersReducedMotion.matches) {
// nodes in opacity of the circle element
d3
.selectAll("g.node")
.style("opacity", 0)
.transition()
.duration(150)
.delay((d, i) => 50 * i)
.style("opacity", 1);
d3
.selectAll("g.node circle")
.style("transform", "scale(0)")
.transition()
.duration(150)
.delay((d, i) => 50 * i)
.style("transform", "scale(1)");
// links in stroke-dashoffset
// ! use the function keyword to have access to "this"
d3
.selectAll("path.link")
.attr("stroke-dasharray", function () {
return this.getTotalLength();
})
.attr("stroke-dashoffset", function () {
return this.getTotalLength();
})
.transition()
.ease(d3.easeQuadOut)
.duration(500)
.delay((d, i) => 400 * i + (50 * nodes.length + 150))
.attr("stroke-dashoffset", 0);
}
</script>边栏推荐
- MySQL CREATE TABLE statement error: 1103 incorrect table name
- 图扑 Web 可视化引擎在仿真分析领域的应用
- fink.15 DataSet模块 算子大全
- leetcode:74. Search 2D matrix
- [Mori city] random talk on GIS data (IV) - coordinate system
- Special topic of software R & D efficiency demand value stream analysis
- 医疗单据OCR识别+知识库校验,赋能保险智能理赔
- 智能工厂具体的名词解释
- leetcode:74. 搜索二维矩阵
- 如何將notepad++設置為默認打開方式
猜你喜欢
C 基本语法解读: 总结程序中的一些常用到的但是容易混乱的函数(i++与++i) (位域)

2022年智能运维企业50强,博睿数据实力入选

函数与箭头函数

Faster Planner——Kinodynamic Astar详解

Matlab-mex
![[Mori city] random talk on GIS data (IV) - coordinate system](/img/c8/9c58be36247c59582bd4c645ba3774.jpg)
[Mori city] random talk on GIS data (IV) - coordinate system

Diwen serial port screen tutorial (3)

MP4文件简介

Among the top 50 intelligent operation and maintenance enterprises in 2022, Borui data strength was selected

Practice of online problem feedback module (III): automatically generate all controller, service, mapper and other files
随机推荐
Distributed basic theory that cannot be ignored
Comment définir Notepad + + comme mode d'ouverture par défaut
Domain Driven Design Fundamentals
dried food! Teach you how to build a highly available architecture
区分子类方法中的重名
flink.14 DataStream模块 source底层是怎么实现的?
leetcode:240. Search 2D matrix II
Extrait d'un bon article
迭代器与生成器
Excerpts of good articles and sentences in the thesis
es5和es6的区别
regular expression
Among the top 50 intelligent operation and maintenance enterprises in 2022, Borui data strength was selected
Grafana Labs携手阿里云,将提供国内首款Grafana托管服务
Gurobi——GRBLinExpr
Redis (II) three special types of redis
Empowering new industries and creating a new future | Tupo software was invited to participate in the Xiamen Industrial Expo
Practice of online problem feedback module (III): automatically generate all controller, service, mapper and other files
2021-05-30
leetcode:240. 搜索二维矩阵 II