更新while循环D3中的参数

时间:2016-09-10 07:24:26

标签: javascript d3.js while-loop slider interactive

我希望有人能提供帮助,我是javascript的新手,但为了开始在D3中制作交互式输出,我一直在学习它。

所以我开始使用基础知识并生成折线图等,现在我想添加一个交互元素。

所以我有一个折线图,一个滑块和一个函数,问题是如何将它们链接起来?玩一些在线示例我了解如何让滑块更新对象的属性,如文本,但我希望它在循环中更新参数以执行计算,然后运行并给出线图输出。

我的代码如下,我注释了我要更新的循环:

<!DOCTYPE html>
<style type="text/css">
        path {
            stroke-width: 2;
            fill: none;
        }

        line {
            stroke: black;
        }

        text {
            font-family: Arial;
            font-size: 9pt;
        }

    </style>
<body>

 <p>
  <label for="repRate" 
         style="display: inline-block; width: 240px; text-align: right">
         R = <span id="repRate-value">…</span>
  </label>
  <input type="range" min="0.0" max="1.0" step="0.01" id="repRate">
</p>

<script src="http://d3js.org/d3.v3.min.js"></script>
<script>


d3.select("#repRate").on("input", function() {
  update(+this.value);
});


update(0.1);


function update(repRate) {

  // adjust slider text
  d3.select("#repRate-value").text(repRate);
  d3.select("#repRate").property("value", repRate);

}


//This is the function I want to update when the slider moves, I want the parameter R to update
//with the slider value, then loop through and produce a new graph
function parHost (R){
var i = 0;
var result = [];
      do {
      //I want to be able to keep it as a loop or similar, so that I can add more complex
      //equations into it, but for now I've kept it simple
        Nt1 = R*i
        result.push(Nt1++) ;
        Nt = Nt1
        i++;
      }
      while (i < 50);
        return result};



      var data = parHost(0.5),
            w = 900,
            h = 200,
            marginY = 50,
            marginX = 20,
            y = d3.scale.linear().domain([0, d3.max(data)]).range([0 + marginX, h - marginX]),
            x = d3.scale.linear().domain([0, data.length]).range([0 + marginY, w - marginY])


            var vis = d3.select("body")
                .append("svg:svg")
                .attr("width", w)
                .attr("height", h)

            var g = vis.append("svg:g")
                .attr("transform", "translate(0, 200)");

            var line = d3.svg.line()
                .x(function(d,i) { return x(i); })
                .y(function(d) { return -1 * y(d); })

            g.append("svg:path").attr("d", line(data)).attr('stroke', 'blue');

            g.append("svg:line")
                .attr("x1", x(0))
                .attr("y1", -1 * y(0))
                .attr("x2", x(w))
                .attr("y2", -1 * y(0))

            g.append("svg:line")
                .attr("x1", x(0))
                .attr("y1", -1 * y(0))
                .attr("x2", x(0))
                .attr("y2", -1 * y(d3.max(data)))


            g.selectAll(".xLabel")
                .data(x.ticks(5))
                .enter().append("svg:text")
                .attr("class", "xLabel")
                .text(String)
                .attr("x", function(d) { return x(d) })
                .attr("y", 0)
                .attr("text-anchor", "middle")

            g.selectAll(".yLabel")
                .data(y.ticks(4))
                .enter().append("svg:text")
                .attr("class", "yLabel")
                .text(String)
                .attr("x", 0)
                .attr("y", function(d) { return -1 * y(d) })
                .attr("text-anchor", "right")
                .attr("dy", 4)

            g.selectAll(".xTicks")
                .data(x.ticks(5))
                .enter().append("svg:line")
                .attr("class", "xTicks")
                .attr("x1", function(d) { return x(d); })
                .attr("y1", -1 * y(0))
                .attr("x2", function(d) { return x(d); })
                .attr("y2", -1 * y(-0.3))

            g.selectAll(".yTicks")
                .data(y.ticks(4))
                .enter().append("svg:line")
                .attr("class", "yTicks")
                .attr("y1", function(d) { return -1 * y(d); })
                .attr("x1", x(-0.3))
                .attr("y2", function(d) { return -1 * y(d); })
                .attr("x2", x(0))





</script>
</body>

对此的任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

在每个滑块输入事件中,您必须更新图表中的部分(例如lineaxisTicks等),这些部分取决于您的数据。你可以,例如像这样扩展你的更新功能:

function update(repRate) {
  // adjust slider text
  d3.select("#repRate-value").text(repRate);
  d3.select("#repRate").property("value", repRate);

  // Generate new Data depending on slider value
  var newData = parHost(repRate);

  // Update the chart
  drawChart(newData);
}

其中drawChart(newData)可能如下所示:

function drawChart(newData) {
  // Delete the old elements
  g.selectAll("*").remove();

  g.append("svg:path").attr("d", line(newData)).attr('stroke', 'blue');
  ...
}

另一种方法是将数据依赖元素声明为变量,并在更新时更改它们的属性(我建议):

...
var dataLine = g.append("svg:path");
...
function drawChart(newData) {
  path.attr("d", line(newData)).attr('stroke', 'blue');
}

以下是plunker示例。 请查看此example