How can I draw an autoscaling D3.js graph that plots a mathematical function?

安稳与你 提交于 2020-03-24 08:35:12

问题


I have a working jsfiddle that I made using JSXGraph, a graphing toolkit for mathematical functions. I'd like to port it to D3.js for personal edification, but I'm having a hard time getting started.

The jsfiddle graphs the value of -ke(-x/T) + k, where x is an independent variable and the values of k and t come from sliders.

board.create('functiongraph',
  [
    // y = -k * e(-x/t) + k
    function(x) { return -k.Value()*Math.exp(-x/t.Value()) + k.Value(); },
    0
  ]
);

The three things I'm most stumped on:

  • Actually drawing the graph and its axes - it's not clear to me which of the many parts of the D3 API I should be using, or what level of abstraction I should be operating at.

  • Re-rendering the graph when a slider is changed, and making the graph aware of the value of the sliders.

  • Zooming out the graph so that the asymptote defined by y = k is always visible and not within the top 15% of the graph. I do this now with:

    function getAestheticBoundingBox() {
      var kMag = k.Value();
      var tMag = t.Value();
      var safeMinimum = 10;
      var limit = Math.max(safeMinimum, 1.15 * Math.max(k.Value(), t.Value()));
    
      return [0, Math.ceil(limit), Math.ceil(limit), 0];
    }
    

What's the right way for me to tackle this problem?


回答1:


I threw this example together really quick, so don't ding me on the code quality. But it should give you a good starting point for how you'd do something like this in d3. I implemented everything in straight d3, even the sliders.

As @LarKotthoff says, the key is that you have to loop your function and build your data:

// define your function
var func = function(x) {
  return -sliders.k() * Math.exp(-x / sliders.t()) + sliders.k();
},
// your step for looping function
step = 0.01;

drawPlot();

function drawPlot() {

  // avoid first callback before both sliders are created
  if (!sliders.k ||
      !sliders.t) return;

  // set your limits
  var kMag = sliders.k();
  var tMag = sliders.t();
  var safeMinimum = 10;
  var limit = Math.max(safeMinimum, 1.15 * Math.max(kMag, tMag));

  // generate your data
  var data = [];
  for (var i = 0; i < limit; i += step) {
    data.push({
      x: i,
      y: func(i)
    })
  }

  // set our axis limits
  y.domain(
    [0, Math.ceil(limit)]
  );
  x.domain(
    [0, Math.ceil(limit)]
  );

  // redraw axis
  svg.selectAll("g.y.axis").call(yAxis);
  svg.selectAll("g.x.axis").call(xAxis);

  // redraw line
  svg.select('.myLine')
    .attr('d', lineFunc(data))
}


来源:https://stackoverflow.com/questions/29755411/how-can-i-draw-an-autoscaling-d3-js-graph-that-plots-a-mathematical-function

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!