简体   繁体   中英

D3.js: Getting x-axis to transition smoothly in a time-series graph for each second?

I am trying to get my x-axis to transition smoothly and continuously for a time-series graph. So far, it transitions, stops, transitions, stops.. each second; my time window is 10 seconds.

Moreover, the transitions start and stop outside my x-axis. Is there a simple fix? Thank you for your consideration: Here is my working example:

 //////////////////////////////////////////////////////////// ////////////////////// Set-up ///////////////////////////// //////////////////////////////////////////////////////////// const margin = { left: 80, right: 80, top: 30, bottom: 165 }; //Actual graph smaller than svg container var width = $('#chart').width() - margin.left - margin.right; var height = $('#chart').height() - margin.top - margin.bottom; //yAxis const yDomain = [0, 70]; const yTickValues = [0, 10, 20, 30, 40, 50, 60, 70]; const TIME_INTERVAL = 1000; //xAxis domain-> 10 seconds const originalTime1 = "1970-01-01T00:00:00", originalTime2 = "1970-01-01T00:00:10"; var date1 = new Date(originalTime1).getTime(), date2 = new Date(originalTime2).getTime(); //////////////////////////////////////////////////////////// ///////////////////////// SVG ////////////////////////////// //////////////////////////////////////////////////////////// const svg = d3.select("#chart").append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom); const g = svg.append("g").attr("transform", "translate(" + margin.left + ", " + margin.top + ")"); //////////////////////////////////////////////////////////// ///////////////////// Axes & Scales //////////////////////// //////////////////////////////////////////////////////////// var xAxisGroup = g.append("g").attr("class", "x-axis"); var yAxisGroup = g.append("g").attr("class", "y-axis"); //Dynamic var xScale = d3.scaleTime(); //Fixed var yScale = d3.scaleLinear().domain([yDomain[0], yDomain[1]]).range([height - margin.bottom, 0]); const xAxis = d3.axisBottom(xScale).ticks(d3.timeSecond.every(1)).tickSizeInner(15).tickFormat(d3.timeFormat("%M:%S")); const yAxis = d3.axisLeft().scale(yScale).tickValues(yTickValues).tickFormat(d3.format(".0f")); //////////////////////////////////////////////////////////// /////////////////////// Function /////////////////////////// //////////////////////////////////////////////////////////// function draw() { //Update xAxis scale xScale.domain([date1, date2]).range([0, width]); //Call axes xAxisGroup.attr("transform", "translate(0," + (height - margin.bottom) + ")").transition().duration(1000).call(xAxis); yAxisGroup.call(yAxis); date1 += TIME_INTERVAL; date2 += TIME_INTERVAL; }; //////////////////////////////////////////////////////////// ///////////////////////// Main ///////////////////////////// //////////////////////////////////////////////////////////// draw(); setInterval(draw, 1000);
 .x-axis, .y-axis { font-size: 0.8em; stroke-width: 0.06em; } #chart { width: 600px; height: 500px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="chart"></div>

Use .transition.ease(d3.easeLinear) to make the entire transition a linear experience. That way, there is no noticeable slowing down at all.

For the second part, I wasn't able to find a nice workaround, but a hacky fix is to simply draw a white rectangle over the area you wish to hide - in this case the left. I added it before adding the y -axis group so it wouldn't be disturbed by it.

 //////////////////////////////////////////////////////////// ////////////////////// Set-up ///////////////////////////// //////////////////////////////////////////////////////////// const margin = { left: 80, right: 80, top: 30, bottom: 165 }; //Actual graph smaller than svg container var width = $('#chart').width() - margin.left - margin.right; var height = $('#chart').height() - margin.top - margin.bottom; //yAxis const yDomain = [0, 70]; const yTickValues = [0, 10, 20, 30, 40, 50, 60, 70]; const TIME_INTERVAL = 1000; //xAxis domain-> 10 seconds const originalTime1 = "1970-01-01T00:00:00", originalTime2 = "1970-01-01T00:00:10"; var date1 = new Date(originalTime1).getTime(), date2 = new Date(originalTime2).getTime(); //////////////////////////////////////////////////////////// ///////////////////////// SVG ////////////////////////////// //////////////////////////////////////////////////////////// const svg = d3.select("#chart").append("svg").attr("width", width + margin.left + margin.right).attr("height", height + margin.top + margin.bottom); const g = svg.append("g").attr("transform", "translate(" + margin.left + ", " + margin.top + ")"); //////////////////////////////////////////////////////////// ///////////////////// Axes & Scales //////////////////////// //////////////////////////////////////////////////////////// var xAxisGroup = g.append("g").attr("class", "x-axis"); // HACK: draw white rectangle over the fading axis g.append('rect').attr('fill', 'white').attr('width', margin.left).attr('height', margin.bottom).attr('x', -margin.left).attr('y', height - margin.bottom); var yAxisGroup = g.append("g").attr("class", "y-axis"); //Dynamic var xScale = d3.scaleTime(); //Fixed var yScale = d3.scaleLinear().domain([yDomain[0], yDomain[1]]).range([height - margin.bottom, 0]); const xAxis = d3.axisBottom(xScale).ticks(d3.timeSecond.every(1)).tickSizeInner(15).tickFormat(d3.timeFormat("%M:%S")); const yAxis = d3.axisLeft().scale(yScale).tickValues(yTickValues).tickFormat(d3.format(".0f")); //////////////////////////////////////////////////////////// /////////////////////// Function /////////////////////////// //////////////////////////////////////////////////////////// function draw() { //Update xAxis scale xScale.domain([date1, date2]).range([0, width]); //Call axes xAxisGroup.attr("transform", "translate(0," + (height - margin.bottom) + ")").transition().duration(1000) // See here for the change: .ease(d3.easeLinear).call(xAxis); yAxisGroup.call(yAxis); date1 += TIME_INTERVAL; date2 += TIME_INTERVAL; }; //////////////////////////////////////////////////////////// ///////////////////////// Main ///////////////////////////// //////////////////////////////////////////////////////////// draw(); setInterval(draw, 1000);
 .x-axis, .y-axis { font-size: 0.8em; stroke-width: 0.06em; } #chart { width: 600px; height: 500px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div id="chart"></div>

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