D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
anqi-lu
Full window
Github gist
Debounce troubleshooting
Built with
blockbuilder.org
<!DOCTYPE html> <html> <head> <title>Debounced slider</title> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- D3.js script --> <script src="https://d3js.org/d3.v4.min.js"></script> </head> <style> .slider_no_debounce rect { fill: gray; shape-rendering: crispEdges; } .slider_debounce rect { fill: red; shape-rendering: crispEdges; } .slider line { fill: none; stroke: red; opacity: 0.3; shape-rendering: crispEdges; } </style> <body> <div class="container"> <div class="row"> <div class="col-md-5"> <div id='float_court'> <div id="court"> <h3 id="caption"><text></text></h3> </div> </div> </div> </div> </div> <script> const margin = { left: 20, right: 20, top: 20, bottom: 20 }; var chartDiv = document.getElementById("court"); var court = d3.select(chartDiv).append("svg"); var timer; court.attr("width", 580) .attr("height",100) .attr("transform", "translate(0,0)"); var slider_axis = court.append("g") .attr("class", "slider-axis"); var slider_rect_no_debounce = court.append("g") .attr("class", "slider_rect_no_debounce"); var slider_rect_debounce = court.append("g") .attr("class", "slider_rect_debounce"); var rect_entity_no_debounce = slider_rect_no_debounce.append("rect"); var rect_entity_debounce = slider_rect_debounce.append("rect"); var court_width = 480 Slider(); function Slider () { const parseTime = d3.timeParse("%Y"); const width = court_width; const height = width/50*47; const innerWidth = width - margin.left - margin.right; const innerHeight = height - margin.top - margin.bottom; slider_axis.attr('transform', `translate(0, 50)`) slider_rect_no_debounce.attr("width", innerWidth) .attr("height", innerHeight) .attr('transform', `translate(0, 50)`) slider_rect_debounce.attr("width", innerWidth) .attr("height", innerHeight) .attr('transform', `translate(0, 25)`) var minDate = new Date('1997'), scale = d3.scaleTime() .domain([minDate, d3.timeYear.offset(minDate, 19)]) .range([margin.left, innerWidth]) .clamp(true), format = d3.timeFormat('%Y'); updateHeader(minDate); slider_axis .attr('class', 'axis') .call(d3.axisBottom(scale).ticks(d3.timeYear.every(3))); slider_rect_no_debounce .attr("class", "slider_no_debounce") // without debounce .call(d3.drag().on('drag', dragged)); slider_rect_debounce .attr("class", "slider_debounce") // with debounce .call(d3.drag().on('drag', dragged_debounce)); var rectWidth = 8; rect_entity_no_debounce.attr("x", margin.left) .attr("y", 0) .attr("width", rectWidth) .attr("height", 20); rect_entity_debounce.attr("x", margin.left) .attr("y", 0) .attr("width", rectWidth) .attr("height", 20); function updateHeader(date) { var title_court = d3.select(".col-md-5").select('#caption'); title_court.text(format(date)+'-'+(date.getFullYear()+1).toString()) .attr('x', margin.left) .attr('y', margin.top); } function dragged_debounce(d) { console.log("debounce") var title = d3.select("#caption"); var prev = title.text().split('-')[0] var x = Math.min(d3.event.x, innerWidth); value = scale.invert(x); d3.select('.slider_debounce').attr('transform', 'translate(' + Math.max(0,Math.min(x, x-margin.left)) + ',' + 25 + ')'); delayedUpdatePlot(() => update_all_plots(value, prev), 200); } function dragged(d) { console.log("no debounce") var title = d3.select("#caption"); var prev = title.text().split('-')[0] var x = Math.min(d3.event.x, innerWidth); value = scale.invert(x); d3.select('.slider_no_debounce').attr('transform', 'translate(' + Math.max(0,Math.min(x, x-margin.left)) + ',' + 50 + ')'); update_all_plots(value, prev) } function update_all_plots(value, prev){ console.log("update all plots") updateHeader(value); } } function delayedUpdatePlot(func, wait) { clearTimeout(timer) timer = setTimeout(func, wait) } // https://stackoverflow.com/questions/28773113/d3-event-is-null-inside-of-debounced-function function debounceD3Event(func, wait, immediate) { var timeout; return function() { var context = this; var args = arguments; var evt = d3.event; var later = function() { timeout = null; if (!immediate) { func.apply(context, args); } }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) { var tmpEvent = d3.event; d3.event = evt; func.apply(context, args); d3.event = tmpEvent; } }; } </script> </body> </html>
https://d3js.org/d3.v4.min.js