javascript - 动画不适用于 d3 折线图
问题描述
我对d3没有经验。我最近才学会了这门语言的基础知识。作为一名学生记者,我真的只精通 HTML 和 CSS。我正在尝试为学校制作动画折线图。
当我添加动画代码时,它不起作用。我确保所有名称(不确定这是否是术语)都匹配,并且我仔细研究了其他人的动画折线图代码以找出问题所在。更重要的是,当我尝试重新排序代码以将轴放在动画下方时,图表完全消失,只留下 HTML 页眉和页脚文本。
<!-- container for the visualization -->
<!DOCTYPE html>
<head>
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>
<link href="/Users/megfletch/Desktop/line-chart-draft/src/style.css" type="text/css" rel="stylesheet" />
</head>
<header>
<h1 class="text">Proactive Community Testing — <b class="highlight">Students</b></h1>
<h4 class="text">Since school started the week of Aug. 23, proactive community testing has fluctuated.</h4>
</header>
<body>
<svg class="viz" id="viz" width="1000" height="325">
<div class="viz"></div>
<script id="chart">
const data = [
{ date: "8/23/2020", test: 975},
{ date: "8/30/2020", test: 1841},
{ date: "9/6/2020", test: 2316},
{ date: "9/13/2020", test: 1481},
{ date: "9/20/2020", test: 1415},
{ date: "9/27/2020", test: 3076},
{ date: "10/4/2020", test: 2146},
];
const margin = {
top: 20,
right: 20,
bottom: 20,
left: 20,
};
const width = 700 - (margin.left + margin.right);
const height = 350 - (margin.top + margin.bottom);
// time parse
var parseTime = d3.timeParse("%m/%d/%Y");
data.forEach(function (d) {
d.date = parseTime(d.date);
});
// create svg
const svg = d3
.select('#viz')
.append('svg')
.attr('viewBox', `0 0 ${width + (margin.left + margin.right)} ${height + (margin.top + margin.bottom)}`)
.attr('width', width)
.attr('height', height);
const grp = chart
.append("g")
// include the visualization in the nested group
const path = svg
.append('g')
.attr('transform', `translate(${margin.left} ${margin.right})`);
// describe the scales for the line chart
// x-axis: time scale using the dates
const xScale = d3
.scaleTime()
.domain([new Date(data[0].date), new Date(data[data.length - 1].date)])
.range([0, width])
.nice();
// y-axis: linear scale using the percentages
const yScale = d3
.scaleLinear()
.domain(d3.extent(data, ({ test }) => test)) /
.range([height, 0])
.nice();
const line = d3
.line()
.x(({ date }) => xScale(new Date(date)))
.y(({ test }) => yScale(test));
// include the axes based on the defined scales
const xAxis = d3
.axisBottom(xScale);
path
.append('g')
.attr('transform', `translate(0 ${height})`)
.call(xAxis);
const yAxis = d3
.axisLeft(yScale);
path
.append('g')
.call(yAxis);
// add a path element using the line function
path
.append('path')
.attr('d', line(data))
.attr('fill', 'none')
.attr('stroke', '#f5842e')
.attr('stroke-width','3');
// add a animation
const pathLength = path.node().getTotalLength();
const transitionPath = d3
.transition()
.duration(2500);
path
.attr("stroke-dashoffset", pathLength)
.attr("stroke-dasharray", pathLength)
.transition(transitionPath)
.attr("stroke-dashoffset", 0);
</script>
</body>
<footer>
<h5 class="text">Source: UT Austin COVID-19 Dashboard</h5>
</footer>
解决方案
此行有一个“/”,需要删除
.domain(d3.extent(data, ({ test }) => test)) /
您使用的是“路径”,它是许多元素的组。在下面的示例中,我为您要设置动画的路径创建了一个新 pathD,以便 .path()getTotalLength() 在实际路径元素上工作
const data = [
{ date: "8/23/2020", test: 975},
{ date: "8/30/2020", test: 1841},
{ date: "9/6/2020", test: 2316},
{ date: "9/13/2020", test: 1481},
{ date: "9/20/2020", test: 1415},
{ date: "9/27/2020", test: 3076},
{ date: "10/4/2020", test: 2146},
];
const margin = {
top: 20,
right: 20,
bottom: 20,
left: 20,
};
const width = 700 - (margin.left + margin.right);
const height = 350 - (margin.top + margin.bottom);
// time parse
var parseTime = d3.timeParse("%m/%d/%Y");
data.forEach(function (d) {
d.date = parseTime(d.date);
});
// create svg
const svg = d3
.select('#viz')
.append('svg')
.attr('viewBox', `0 0 ${width + (margin.left + margin.right)} ${height + (margin.top + margin.bottom)}`)
.attr('width', width)
.attr('height', height);
const grp = svg
.append("g")
// include the visualization in the nested group
const path = svg
.append('g')
.attr('transform', `translate(${margin.left} ${margin.right})`);
// describe the scales for the line chart
// x-axis: time scale using the dates
const xScale = d3
.scaleTime()
.domain([new Date(data[0].date), new Date(data[data.length - 1].date)])
.range([0, width])
.nice();
// y-axis: linear scale using the percentages
const yScale = d3
.scaleLinear()
.domain(d3.extent(data, ({ test }) => test))
.range([height, 0])
.nice();
const line = d3
.line()
.x(({ date }) => xScale(new Date(date)))
.y(({ test }) => yScale(test));
// include the axes based on the defined scales
const xAxis = d3.axisBottom(xScale);
path
.append('g')
.attr('transform', `translate(0 ${height})`)
.call(xAxis);
const yAxis = d3
.axisLeft(yScale);
path
.append('g')
.call(yAxis);
// add a path element using the line function
let pathD = path
.append('path')
.attr('d', line(data))
.attr('fill', 'none')
.attr('stroke', '#f5842e')
.attr('stroke-width','3');
// add a animation.
const pathNode = pathD.node();
const pathLength = pathNode.getTotalLength();
const transitionPath = d3
.transition()
.duration(2500);
pathD
.attr("stroke-dashoffset", pathLength)
.attr("stroke-dasharray", pathLength)
.transition(transitionPath)
.attr("stroke-dashoffset", 0);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.0.0/d3.min.js"></script>
<!-- container for the visualization -->
<!DOCTYPE html>
<head>
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>
<link href="/Users/megfletch/Desktop/line-chart-draft/src/style.css" type="text/css" rel="stylesheet" />
</head>
<header>
<h1 class="text">Proactive Community Testing — <b class="highlight">Students</b></h1>
<h4 class="text">Since school started the week of Aug. 23, proactive community testing has fluctuated.</h4>
</header>
<body>
<svg class="viz" id="viz" width="1000" height="325">
<div class="viz"></div>
</body>
<footer>
<h5 class="text">Source: UT Austin COVID-19 Dashboard</h5>
</footer>
推荐阅读
- python - python numpy数组中选定元素的最小值的索引
- python - gtk3 | Python:命名空间 Gtk 不可用,找不到命名空间“Gtk”(任何版本)的 Typelib 文件(使用 macOS)
- c++ - c ++构造函数成员初始化:传递参数
- php - MySQLi PHP 结果数组不兼容?
- java - 为 Eclipse Photon 安装 Glassfish 工具时出错
- asp.net - 如何从 ASP.NET 执行 text/nvarchar SQL Server 中的变量
- unity3d - 非玩家对象权限转移问题
- google-cloud-functions - functions.runWith 不是部署时使用firebase云函数的函数
- applicationcontext - 使用 ApplicationContext 在 smali 文件中调用方法
- python - Xpath。按页面出现顺序获取指定标签的文本