Reputation: 1
I am not experienced with d3. I only recently learned the basics of the language. As a student journalist, I'm really only fluent in HTML and CSS. I'm trying to make an animated line chart for school.
When I add the animation code, it does not work. I made sure all the names (not sure if that's the term) match and I have pored over others' animated line chart code to find what's going wrong. What's more is that when I try to reorder the code to put the axes below the animation, the chart completely disappears, leaving only the HTML header and footer text.
<!-- 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>
Upvotes: 0
Views: 322
Reputation: 1787
This line has a "/" which needs to be removed
.domain(d3.extent(data, ({ test }) => test)) /
You were using "path" which is a group for many elements. In the example below, I've created a new pathD for the path you want to animate, so that .path()getTotalLength() works on an actual path element
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>
Upvotes: 1