簡體   English   中英

無限重復的功能

[英]function that repeats indefinitely

下面的代碼來自Mike Bostock D3.js路徑教程http://bost.ocks.org/mike/path/的最后一個/底部示例。 它創建用戶頁面滾動活動的實時圖形。 如果您觀察代碼運行,則會注意到該圖形正在連續運行,無論是否有任何滾動活動,折線圖都會從右向左滑動。 問題:下面的tick功能使它連續運行是什么?如何改變它以在單擊事件停止和開始?

(function() {

var n = 243,
    duration = 750,
    now = new Date(Date.now() - duration),
    count = 0,
    data = d3.range(n).map(function() { return 0; });

var margin = {top: 6, right: 0, bottom: 20, left: 40},
    width = 960 - margin.right,
    height = 120 - margin.top - margin.bottom;

var x = d3.time.scale()
    .domain([now - (n - 2) * duration, now - duration])
    .range([0, width]);

var y = d3.scale.linear()
    .range([height, 0]);

var line = d3.svg.line()
    .interpolate("basis")
    .x(function(d, i) { return x(now - (n - 1 - i) * duration); })
    .y(function(d, i) { return y(d); });

var svg = d3.select("body").append("p").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .style("margin-left", -margin.left + "px")
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.append("defs").append("clipPath")
    .attr("id", "clip")
  .append("rect")
    .attr("width", width)
    .attr("height", height);

var axis = svg.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(x.axis = d3.svg.axis().scale(x).orient("bottom"));

var path = svg.append("g")
    .attr("clip-path", "url(#clip)")
  .append("path")
    .datum(data)
    .attr("class", "line");

var transition = d3.select({}).transition()
    .duration(750)
    .ease("linear");

d3.select(window)
    .on("scroll", function() { ++count; });

(function tick() {
  transition = transition.each(function() {

    // update the domains
    now = new Date();
    x.domain([now - (n - 2) * duration, now - duration]);
    y.domain([0, d3.max(data)]);

    // push the accumulated count onto the back, and reset the count
    data.push(Math.min(30, count));
    count = 0;

    // redraw the line
    svg.select(".line")
        .attr("d", line)
        .attr("transform", null);

    // slide the x-axis left
    axis.call(x.axis);

    // slide the line left
    path.transition()
        .attr("transform", "translate(" + x(now - (n - 1) * duration) + ")");

    // pop the old data point off the front
    data.shift();

  }).transition().each("start", tick);
})();

})()

首先,您缺少定義過渡的部分。
它是某種形式的變量,但未在代碼段中定義。
這有點重要,但是不需要知道為什么該功能繼續運行。

您首先需要了解兩種形式的jquery每個函數。 http://api.jquery.com/each/ http://api.jquery.com/jquery.each/

transition = transition.each(function(){...})。transition()。each(“ start”,tick);

::注意...隱藏了很多代碼::

這本質上是一行代碼。

這是說,對於過渡var的每個子級(如果有),請為其運行“ ...”代碼。 那是每個語句的第一個jquery。 在此函數內,$(this)等於轉換的子obj。 但是,從未使用子對象。

所有迭代完成后,然后運行transition()函數。 (再次不確定那是什么)

最后,每個被再次調用,但形式不同。 這次是說運行帶有字符串“ start”作為obj的tick函數。 這意味着在該函數內$(this)=“ start”。 同樣,從不使用obj。

由於從未使用過調用對象,因此本質上.each只是調用tick函數。

確實,這是一種非常奇怪的方式。 不知道為什么要大量使用.each。 我的理解是,與其他迭代和調用回調的方法相比,.each實際上有點慢。

更新-

通過單擊開始/停止,我將在腳本頂部引入一個變量。

var running = true;

(設置為false以開始不運行)

然后用if語句將tick函數的內容括起來。

if(running) 
{
  transition = transition.each(function() { ... }).transition().each("start", tick);
}

然后創建一兩個點擊處理程序。 (用於一個切換或開始和停止按鈕)

有很多方法可以完成此任務。

$(#[button ID]).click( function(){
   if(running)
   {
     running = false;
   }
   else
   {
     running = true;
     tick();
   }

});

這是基本的攻擊計划。 快速連續單擊按鈕時可能出現問題。 那是您根據需要進行修復。

在轉換之前,我曾遇到過同樣的問題:

var transition = d3.select({}).transition()
  .duration(1000)
  .ease("linear");

您需要運行一個將過渡轉換為零的函數:

transition = transition.transition(0).duration(0);

這從根本上阻止了過渡的完全運行。

然后重新開始過渡:

  transition = d3.select({}).transition()
      .duration(shiftDuration)
      .ease("linear");

  tick();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM