简体   繁体   中英

Animation is not working for d3 line chart

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>

  1. This line has a "/" which needs to be removed

    .domain(d3.extent(data, ({ test }) => test)) /

  2. 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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM