D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
mtranggit
Full window
Github gist
Animate with the General Update Pattern in D3
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v4.min.js"></script> <style> body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } .chart { background: lightgray; border: 1px solid black; } rect { fill: steelblue; } </style> </head> <body> <div class="chart"></div> <button onclick="render('math')">Math</button> <button onclick="render('science')">Science</button> <button onclick="render('language')">Language</button> <script> var data = [ { "name": "Alice", "math": 137, "science": 62, "language": 54 }, { "name": "Billy", "math": null, "science": 34, "language": 85 }, { "name": "Cindy", "math": 86, "science": 48, "language": null }, { "name": "David", "math": 44, "science": null, "language": 65 }, { "name": "Emily", "math": 59, "science": 63, "language": 29 } ] // Feel free to change or delete any of the code you see in this editor! // var svg = d3.select("body").append("svg") // .attr("width", 960) // .attr("height", 500) // svg.append("text") // .text("Edit the code below to change me!") // .attr("y", 200) // .attr("x", 120) // .attr("font-size", 36) // .attr("font-family", "monospace") var margin = { top: 10, right: 25, bottom: 35, left: 20 } var width = 800 - margin.left - margin.right var height = 600 - margin.top - margin.bottom var svg = d3.select('.chart') .append('svg') .attr('width', width + margin.left + margin.right) .attr('height', height + margin.top + margin.bottom) .call(responsivefy) .append('g') .attr('transform', `translate(${margin.left}, ${margin.top})`) var xScale = d3.scaleBand() .domain(data.map(d => d.name)) .range([0, width]) .padding(0.2) var xAxis = d3.axisBottom(xScale) svg.append('g') .attr('transform', `translate(0, ${height})`) .call(xAxis) var yScale = d3.scaleLinear() .domain([0, 100]) .range([height, 0]) // var yAxis = d3.axisLeft(yScale) // .ticks(10) var yAxis = svg.append('g') .attr('transform', `translate(${margin.left}, ${margin.top})`) .call(d3.axisLeft(yScale)) function render (subject = 'math') { var t = d3.transition().duration(500); var update = svg.selectAll('rect') .data(data.filter(d => d[subject]), d => d.name); update.exit() .transition(t) .attr('y', height) .attr('height', 0) .remove(); yScale.domain([0, d3.max(data, d => d[subject])]) yAxis .transition(t) .delay(1000) .call(d3.axisLeft(yScale)) update .transition(t) .delay(1000) .attr('y', d => yScale(d[subject])) .attr('height', d => height - yScale(d[subject])); update .enter() .append('rect') .attr('y', height) .attr('height', 0) .attr('x', d => xScale(d.name)) .attr('width', d => xScale.bandwidth()) .transition(t) .delay(update.exit().size() ? 2000 : 0) .attr('y', d => yScale(d[subject])) .attr('height', d => height - yScale(d[subject])); } render(); function responsivefy(svg) { // get container + svg aspect ratio var container = d3.select(svg.node().parentNode), width = parseInt(svg.style("width")), height = parseInt(svg.style("height")), aspect = width / height; // add viewBox and preserveAspectRatio properties, // and call resize so that svg resizes on inital page load svg.attr("viewBox", "0 0 " + width + " " + height) .attr("preserveAspectRatio", "xMinYMid") .call(resize); // to register multiple listeners for same event type, // you need to add namespace, i.e., 'click.foo' // necessary if you call invoke this function for multiple svgs // api docs: https://github.com/mbostock/d3/wiki/Selections#on d3.select(window).on("resize." + container.attr("id"), resize); // get width of container and resize svg to fit it function resize() { var targetWidth = parseInt(container.style("width")); svg.attr("width", targetWidth); svg.attr("height", Math.round(targetWidth / aspect)); } } </script> </body>
https://d3js.org/d3.v4.min.js