带有路径和 SVG 的 d3 动画折线图

洛雷托帕里西

我正在尝试将此处的动画折线示例调整为折线图

function displayGraph(id, data, width, height, interpolation, animate, updateDelay, transitionDelay) {
  // create an SVG element inside the #graph div that fills 100% of the div
  var graph = d3.select(id).append("svg:svg").attr("width", "100%").attr("height", "100%");

  // create a simple data array that we'll plot with a line (this array represents only the Y values, X will just be the index location)


  // X scale will fit values from 0-10 within pixels 0-100
  var x = d3.scale.linear().domain([0, 48]).range([-5, width]); // starting point is -5 so the first value doesn't show and slides off the edge as part of the transition
  // Y scale will fit values from 0-10 within pixels 0-100
  var y = d3.scale.linear().domain([0, 10]).range([0, height]);

  // create a line object that represents the SVN line we're creating
  var line = d3.svg.line()
    // assign the X function to plot our line as we wish
    .x(function(d, i) {
      // verbose logging to show what's actually being done
      //console.log('Plotting X value for data point: ' + d + ' using index: ' + i + ' to be at: ' + x(i) + ' using our xScale.');
      // return the X coordinate where we want to plot this datapoint
      return x(i);
    })
    .y(function(d) {
      // verbose logging to show what's actually being done
      //console.log('Plotting Y value for data point: ' + d + ' to be at: ' + y(d) + " using our yScale.");
      // return the Y coordinate where we want to plot this datapoint
      return y(d);
    })
    .interpolate(interpolation)

  // display the line by appending an svg:path element with the data line we created above
  graph.append("svg:path").attr("d", line(data));
  // or it can be done like this
  //graph.selectAll("path").data([data]).enter().append("svg:path").attr("d", line);


  function redrawWithAnimation() {
    // update with animation
    graph.selectAll("path")
      .data([data]) // set the new data
      .attr("transform", "translate(" + x(1) + ")") // set the transform to the right by x(1) pixels (6 for the scale we've set) to hide the new value
      .attr("d", line) // apply the new data values ... but the new value is hidden at this point off the right of the canvas
      .transition() // start a transition to bring the new value into view
      .ease("linear")
      .duration(transitionDelay) // for this demo we want a continual slide so set this to the same as the setInterval amount below
      .attr("transform", "translate(" + x(0) + ")"); // animate a slide to the left back to x(0) pixels to reveal the new value

    /* thanks to 'barrym' for examples of transform: https://gist.github.com/1137131 */
  }

  function redrawWithoutAnimation() {
    // static update without animation
    graph.selectAll("path")
      .data([data]) // set the new data
      .attr("d", line); // apply the new data values
  }
  setInterval(function() {
    if (animate) {
      redrawWithAnimation();
    } else {
      redrawWithoutAnimation();
    }
  }, updateDelay);
} //displayGraph

// input data
var data = [3, 6, 2, 7, 5, 2, 1, 3, 8, 9, 2, 5, 9, 3, 6, 3, 6, 2, 7, 5, 2, 1, 3, 8, 9, 2, 5, 9, 2, 7, 5, 2, 1, 3, 8, 9, 2, 5, 9, 3, 6, 2, 7, 5, 2, 1, 3, 8, 9, 2, 9];

// display
displayGraph("#graph1", data, 300, 30, "basis", true, 1000, 1000);

// update data
setInterval(function() {
  var v = data.shift(); // remove the first element of the array
  data.push(v); // add a new element to the array (we're just taking the number we just shifted off the front and appending to the end)
}, 1000);
path {
  stroke: steelblue;
  stroke-width: 1;
  fill: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="graph1" class="aGraph" style="width:300px; height:30px;"></div>

虽然在示例中我们画了一条简单的线,因此数据由一组x值表示,作为y索引,我的数据集就像

var data=[ 
{"progress":42.3,"words":2116,"lr":0.288598,"loss":4.07032,"eta":"0h0m"}, {"progress":44,"words":2197,"lr":0.279892,"loss":4.06091,"eta":"0h0m"},{"progress":45.7,"words":2279,"lr":0.27161,"loss":4.053332,"eta":"0h0m"},{"progress":46.6,"words":2364,"lr":0.267103,"loss":4.052618,"eta":"0h0m"},{"progress":49.1,"words":2449,"lr":0.254353,"loss":4.055149,"eta":"0h0m"}, {"progress":50.9,"words":2532,"lr":0.245493,"loss":4.057263,"eta":"0h0m"},{"progress":52.7,"words":2617,"lr":0.236479,"loss":4.059458,"eta":"0h0m"},{"progress":57,"words":2833,"lr":0.215139,"loss":4.056543,"eta":"0h0m"},{"progress":58.8,"words":2920,"lr":0.205817,"loss":4.03259,"eta":"0h0m"},{"progress":61.5,"words":3046,"lr":0.192411,"loss":3.980249,"eta":"0h0m"},{"progress":64.2,"words":3175,"lr":0.178891,"loss":3.914494,"eta":"0h0m"},{"progress":66,"words":3262,"lr":0.170031,"loss":3.905593,"eta":"0h0m"},{"progress":67.8,"words":3345,"lr":0.161171,"loss":3.912257,"eta":"0h0m"},
 {"progress":69.4,"words":3425,"lr":0.152928,"loss":3.917797,"eta":"0h0m"},
{"progress":71,"words":3499,"lr":0.145031,"loss":3.922638,"eta":"0h0m"},{"progress":72.8,"words":3587,"lr":0.136055,"loss":3.927278,"eta":"0h0m"},
 {"progress":75.4,"words":3714,"lr":0.123112,"loss":3.932528,"eta":"0h0m"},{"progress":77.1,"words":3799,"lr":0.114638,"loss":3.919754,"eta":"0h0m"},{"progress":78.9,"words":3885,"lr":0.105701,"loss":3.877759,"eta":"0h0m"}
]

我要代表作为ylrloss值,在其同时xprogress数据对象的价值,但我不知道如何让动画绘制时既轴。

[更新]第一次尝试如下

function displayGraph(id, data, width, height, interpolation, animate, updateDelay, transitionDelay) {

  var margin = {
      top: 30,
      right: 20,
      bottom: 30,
      left: 30
    },
    width = width - margin.left - margin.right,
    height = height - margin.top - margin.bottom;

  var graph = d3.select(id)
    .append("svg:svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

  var x = d3.scale.linear().domain([0, data.length]).range([-data.length, width]);
  var y = d3.scale.linear().domain([0, d3.max(data, function(d) {
    return d.lr
  })]).range([height, 0]);
  var y2 = d3.scale.linear().domain([0, d3.max(data, function(d) {
    return d.loss
  })]).range([height, 0]);


  var xAxis = d3.svg.axis().scale(x)
    .orient("bottom").ticks(10);
  var yAxis = d3.svg.axis().scale(y)
    .orient("left").ticks(10);

  var line = d3.svg.line()
    .x(function(d, i) {
      return x(i);
    })
    .y(function(d) {
      return y(d.lr);
    })
    .interpolate(interpolation)

  graph.append("svg:path").attr("d", line(data)).attr('stroke', function(d) {
    return "blue"
  });
  graph.append("g") // Add the X Axis
    .attr('stroke', function(d) {
      return "steelblue"
    })
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);
  graph.append("g") // Add the Y Axis
    .attr('stroke', function(d) {
      return "steelblue"
    })
    .attr("class", "y axis")
    .call(yAxis);


  function redrawWithAnimation() {
    graph.selectAll("path")
      .data([data])
      .attr("transform", "translate(" + x(1) + ")")
      .attr("d", line)
      .transition()
      .ease("linear")
      .duration(transitionDelay)
      .attr("transform", "translate(" + x(0) + ")");
  }

  function redrawWithoutAnimation() {
    graph.selectAll("path")
      .data([data])
      .attr("d", line);
  }
  setInterval(function() {
    if (animate) {
      redrawWithAnimation();
    } else {
      redrawWithoutAnimation();
    }
  }, updateDelay);
} //displayGraph
var data = [];
var dataIn = [{
    "progress": 42.3,
    "words": 2116,
    "lr": 0.288598,
    "loss": 4.07032,
    "eta": "0h0m"
  }, {
    "progress": 44,
    "words": 2197,
    "lr": 0.279892,
    "loss": 4.06091,
    "eta": "0h0m"
  }, {
    "progress": 45.7,
    "words": 2279,
    "lr": 0.27161,
    "loss": 4.053332,
    "eta": "0h0m"
  }, {
    "progress": 46.6,
    "words": 2364,
    "lr": 0.267103,
    "loss": 4.052618,
    "eta": "0h0m"
  }, {
    "progress": 49.1,
    "words": 2449,
    "lr": 0.254353,
    "loss": 4.055149,
    "eta": "0h0m"
  }, {
    "progress": 50.9,
    "words": 2532,
    "lr": 0.245493,
    "loss": 4.057263,
    "eta": "0h0m"
  }, {
    "progress": 52.7,
    "words": 2617,
    "lr": 0.236479,
    "loss": 4.059458,
    "eta": "0h0m"
  }, {
    "progress": 57,
    "words": 2833,
    "lr": 0.215139,
    "loss": 4.056543,
    "eta": "0h0m"
  }, {
    "progress": 58.8,
    "words": 2920,
    "lr": 0.205817,
    "loss": 4.03259,
    "eta": "0h0m"
  }, {
    "progress": 61.5,
    "words": 3046,
    "lr": 0.192411,
    "loss": 3.980249,
    "eta": "0h0m"
  }, {
    "progress": 64.2,
    "words": 3175,
    "lr": 0.178891,
    "loss": 3.914494,
    "eta": "0h0m"
  }, {
    "progress": 66,
    "words": 3262,
    "lr": 0.170031,
    "loss": 3.905593,
    "eta": "0h0m"
  }, {
    "progress": 67.8,
    "words": 3345,
    "lr": 0.161171,
    "loss": 3.912257,
    "eta": "0h0m"
  },
  {
    "progress": 69.4,
    "words": 3425,
    "lr": 0.152928,
    "loss": 3.917797,
    "eta": "0h0m"
  },
  {
    "progress": 71,
    "words": 3499,
    "lr": 0.145031,
    "loss": 3.922638,
    "eta": "0h0m"
  }, {
    "progress": 72.8,
    "words": 3587,
    "lr": 0.136055,
    "loss": 3.927278,
    "eta": "0h0m"
  },
  {
    "progress": 75.4,
    "words": 3714,
    "lr": 0.123112,
    "loss": 3.932528,
    "eta": "0h0m"
  }, {
    "progress": 77.1,
    "words": 3799,
    "lr": 0.114638,
    "loss": 3.919754,
    "eta": "0h0m"
  }, {
    "progress": 78.9,
    "words": 3885,
    "lr": 0.105701,
    "loss": 3.877759,
    "eta": "0h0m"
  }
]
// display
displayGraph("#graph1", dataIn, 600, 200, "basis", true, 750, 1500); //linear

// update data
setInterval(function() {
  var v = dataIn.shift();
  if (v) dataIn.push(v);
}, 1000);
path {
  /*stroke: steelblue;*/
  stroke-width: 1;
  fill: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="graph1" class="aGraph" style="width:600px; height:200px;"></div>

这里有几个问题

  • 我想将新数据点推到点,即我想执行以下操作

    setInterval(function() {
       var v = dataIn.shift();
       if(v) data.push(v);
     }, 1000);
    

sodata将获得一个新值来模拟来自数据源的传入数据;

  • 因此,折线图应该翻译一个点(就像现在一样),但不要重复范围内的“旧”值;
  • 我不知道为什么y轴不显示标签,而x轴在做;

[尝试 3]在这最后一个测试中,我遵循了将图形添加到组的建议,以便翻译正常工作并显示y轴标签。我还添加了额外domain的数据更新。这已经解决了重绘图形时之前的问题:

x.domain([0, 100]); // max(x) is 100
    y.domain([0, d3.max(data, function(d) {
      return d.lr;
    })]);

我能够data在每次更新时数组添加一个新点

// update data
setInterval(function() {
  var v = dataIn.shift();
  if (v) data.push(v);
}, 1000);

我遇到的最后一个问题是y轴上的比例似乎仍然是错误的,因为我想与y应该是data.progress轴进度成正比,但我不知道如何。

function displayGraph(id, data, width, height, interpolation, animate, updateDelay, transitionDelay) {

  var margin = {
      top: 30,
      right: 20,
      bottom: 30,
      left: 30
    },
    width = width - margin.left - margin.right,
    height = height - margin.top - margin.bottom;


var svg = d3.select(id)
  .append("svg:svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
var graph = svg.append('g')
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  
  var x = d3.scale.linear().domain([0, 100]).range([0, width]); // max(x) is 100
  var y = d3.scale.linear().domain([0, 1]).range([height, 0]); // max(y) is 1   
  var line = d3.svg.line()
    .x(function(d, i) {
      return x(i);
    })
    .y(function(d) {
      return y(d.lr);
    })
    .interpolate(interpolation)

  var xAxis = d3.svg.axis().scale(x)
    .orient("bottom").ticks(10);
  var yAxis = d3.svg.axis().scale(y)
    .orient("left").ticks(10);

  graph.append("svg:path")
    .attr("d", line(data))
    .attr('stroke', function(d) {
      return "blue"
    });
  graph.append("g") // Add the X Axis
    .attr('stroke', function(d) {
      return "steelblue"
    })
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(xAxis);
  graph.append("g") // Add the Y Axis
    .attr('stroke', function(d) {
      return "steelblue"
    })
    .attr("class", "y axis")
    .call(yAxis);


  function redrawWithAnimation() {
    //x.domain(d3.extent(data, function(d,i) { return i; }));
    x.domain([0, 100]); // max(x) is 100
    y.domain([0, d3.max(data, function(d) {
      return d.lr;
    })]);
    graph.selectAll("path")
      .data([data])
      .attr("transform", "translate(" + x(1) + ")")
      .attr("d", line)
      .transition()
      .ease("linear")
      .duration(transitionDelay)
      .attr("transform", "translate(" + x(0) + ")");

  }

  function redrawWithoutAnimation() {
    // static update without animation
    graph.selectAll("path")
      .data([data]) // set the new data
      .attr("d", line); // apply the new data values
  }
  setInterval(function() {
    if (animate) {
      redrawWithAnimation();
    } else {
      redrawWithoutAnimation();
    }
  }, updateDelay);
} //displayGraph
var data = [];
var dataIn = [{
    "progress": 42.3,
    "words": 2116,
    "lr": 0.288598,
    "loss": 4.07032,
    "eta": "0h0m"
  }, {
    "progress": 44,
    "words": 2197,
    "lr": 0.279892,
    "loss": 4.06091,
    "eta": "0h0m"
  }, {
    "progress": 45.7,
    "words": 2279,
    "lr": 0.27161,
    "loss": 4.053332,
    "eta": "0h0m"
  }, {
    "progress": 46.6,
    "words": 2364,
    "lr": 0.267103,
    "loss": 4.052618,
    "eta": "0h0m"
  }, {
    "progress": 49.1,
    "words": 2449,
    "lr": 0.254353,
    "loss": 4.055149,
    "eta": "0h0m"
  }, {
    "progress": 50.9,
    "words": 2532,
    "lr": 0.245493,
    "loss": 4.057263,
    "eta": "0h0m"
  }, {
    "progress": 52.7,
    "words": 2617,
    "lr": 0.236479,
    "loss": 4.059458,
    "eta": "0h0m"
  }, {
    "progress": 57,
    "words": 2833,
    "lr": 0.215139,
    "loss": 4.056543,
    "eta": "0h0m"
  }, {
    "progress": 58.8,
    "words": 2920,
    "lr": 0.205817,
    "loss": 4.03259,
    "eta": "0h0m"
  }, {
    "progress": 61.5,
    "words": 3046,
    "lr": 0.192411,
    "loss": 3.980249,
    "eta": "0h0m"
  }, {
    "progress": 64.2,
    "words": 3175,
    "lr": 0.178891,
    "loss": 3.914494,
    "eta": "0h0m"
  }, {
    "progress": 66,
    "words": 3262,
    "lr": 0.170031,
    "loss": 3.905593,
    "eta": "0h0m"
  }, {
    "progress": 67.8,
    "words": 3345,
    "lr": 0.161171,
    "loss": 3.912257,
    "eta": "0h0m"
  },
  {
    "progress": 69.4,
    "words": 3425,
    "lr": 0.152928,
    "loss": 3.917797,
    "eta": "0h0m"
  },
  {
    "progress": 71,
    "words": 3499,
    "lr": 0.145031,
    "loss": 3.922638,
    "eta": "0h0m"
  }, {
    "progress": 72.8,
    "words": 3587,
    "lr": 0.136055,
    "loss": 3.927278,
    "eta": "0h0m"
  },
  {
    "progress": 75.4,
    "words": 3714,
    "lr": 0.123112,
    "loss": 3.932528,
    "eta": "0h0m"
  }, {
    "progress": 77.1,
    "words": 3799,
    "lr": 0.114638,
    "loss": 3.919754,
    "eta": "0h0m"
  }, {
    "progress": 78.9,
    "words": 3885,
    "lr": 0.105701,
    "loss": 3.877759,
    "eta": "0h0m"
  }
]
// display
displayGraph("#graph1", data, 600, 200, "basis", true, 1000, 1000); //linear

// update data
setInterval(function() {
  var v = dataIn.shift();
  if (v) data.push(v);
}, 1000);
path {
  /*stroke: steelblue;*/
  stroke-width: 1;
  fill: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="graph1" class="aGraph" style="width:600px; height:200px;"></div>

另一个问题是,鉴于此代码, 的范围x不会随新值扩展,因此我从y图中获取了值:

在此处输入图片说明

拉齐尔迪尼奥

您的 y 轴不显示的原因是因为它在 svg 之外。如果您将一个组添加到 svg 并按边距进行翻译,它将可见。

var svg = d3.select(id)
  .append("svg:svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
var graph = svg.append('g')
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

您能否澄清目前添加数据的方式有什么问题?对我来说看起来不错。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用d3 + react绘制路径(折线图)

来自分类Dev

D3中的嵌套图和折线图

来自分类Dev

D3中的动画折线图

来自分类Dev

在折线图D3中获得平滑的动画

来自分类Dev

d3折线图的动画区域

来自分类Dev

在 d3 中,如何将样式应用到折线图的折线图和折线图下方的区域?

来自分类Dev

d3折线图,带有enter-update-exit逻辑

来自分类Dev

带有Angular-cli的D3 V4多折线图

来自分类Dev

带有负数的d3.js折线图

来自分类Dev

带有负数的d3.js折线图

来自分类Dev

如何使用SVG和XSL制作折线图

来自分类Dev

D3多折线图-错误:<路径>属性d:期望数字,“ MNaN,NaNLNaN,NaNC…”

来自分类Dev

d3在折线图的最高和最低值上添加圆圈

来自分类Dev

如何创建堆积的折线图D3,多个Y轴和公共X轴

来自分类Dev

D3折线图中的实线和虚线

来自分类Dev

d3在折线图的最高和最低值上添加圆圈

来自分类Dev

如何在我的 d3 折线图中获得线条和区域的样式?

来自分类Dev

D3 折线图 - 在 Y 轴刻度和非刻度上显示值标签

来自分类Dev

d3多折线图,具有不同的功能/变量名称

来自分类Dev

具有JSON数据的D3可重用多折线图

来自分类Dev

具有JSON日期的D3 v4折线图

来自分类Dev

这个 D3 多系列折线图中的 row 函数有什么作用?

来自分类Dev

D3 - 折线图,没有值时不显示线

来自分类Dev

D3 –折线图问题

来自分类Dev

d3累积折线图

来自分类Dev

如何在D3折线图中添加交互式功能(折线和标签)?

来自分类Dev

缩放SVG折线图

来自分类Dev

如何在d3中的每行中制作带有虚线段的多折线图

来自分类Dev

d3 时间线轴 - 带动画的折线图错误 - x.bandwidth 错误

Related 相关文章

热门标签

归档