【问题标题】:D3.js: Getting x-axis to transition smoothly in a time-series graph for each second?D3.js:让 x 轴在时间序列图中每秒平滑过渡?
【发布时间】:2020-08-14 16:18:26
【问题描述】:

我正在尝试让我的 x 轴平滑且连续地转换为时间序列图。到目前为止,它每秒钟都在转换、停止、转换、停止……;我的时间窗口是 10 秒。

此外,转换在我的 x 轴之外开始和停止。有简单的解决方法吗?谢谢您的考虑!这是我的工作示例:

////////////////////////////////////////////////////////////
////////////////////// 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>

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    使用.transition.ease(d3.easeLinear) 使整个过渡成为线性体验。这样一来,根本不会出现明显的减速。

    对于第二部分,我无法找到一个好的解决方法,但一个hacky 解决方法是在您希望隐藏的区域上简单地绘制一个白色矩形 - 在这种情况下是左侧。我在添加y-axis 组之前添加了它,因此它不会被它打扰。

    ////////////////////////////////////////////////////////////
    ////////////////////// 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>

    【讨论】:

    • 非常感谢您的帮助!!
    猜你喜欢
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 2013-06-15
    • 2018-12-16
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 2018-08-02
    相关资源
    最近更新 更多