2013-11-01 5 views
1

내 목표는 백본 컬렉션에 저장된 일부 실시간 메트릭을 플롯하는 것입니다. 메트릭을 저장하는 백본 컬렉션이 있습니다. 백엔드 서버를 폴링 할 때 매초마다 업데이트됩니다. 내 컬렉션에는 일련의 이전 통계와 '최신 데이터'필드가 있으며 백엔드에서 가져온 최신 데이터입니다. 초마다 '최신 데이터'가 다른 값으로 업데이트됩니다. 입체파 메트릭을 생성하는 함수에 백본 컬렉션에 대한 참조를 전달합니다.입체파가 콜백에 대한 업데이트 된 데이터를 플로팅하지 않음

Cubism.js보기가 포함 된보기가 렌더링되면 콜렉션에 저장된 모든 데이터 지점에 대한 히스토리로드를 수평선 도표로 수행해야합니다. 이것은 내가 성공한 부분입니다. 그러나 메트릭 함수가 콜백을 수행 할 때 매 초마다 업데이트되는 '가장 최근 데이터'필드에서 새로운/올바른 지점을 플로팅하지 않습니다. 다음 'getMetric를 호출

 var context = cubism.context() 
      .serverDelay(0) 
      .clientDelay(0) 
      .step(250) 
      .size(1116); 


     //Getting the metrics from the backbone collection 
     var models = this.dataSet.models; 
     console.log('models in metric view',models); 
     //aggregate 'metrics'. Each component has a 'metric' which contains its stats over time 
     for(model in models){ 
      var attributes = models[model].attributes; 

      if(!attributes['name'] || attributes['type']== "FLOW" || attributes['type'] == "SERVER"){ 
       continue; 
      } 
      if(attributes['name'] == null){ 
       continue; 
      } 
      var name = attributes['name']; 
      var type = attributes['type']; 
      var serverName = attributes['serverName']; 
      var metName = name.concat(serverName); 
      console.log(metName); 

      //Getting the cubism metric for each stat in the backbone collection 
      //Passing in a reference to the current model in the backbone collection (this.dataSet.models[model]) 
      var curContext = getMetric(metName, this.dataSet.models[model]); 

      statsList.push(curContext); 

     } 

     d3.select(this.loc).selectAll(".axis") 
      .data(["top", "bottom"]) 
      .enter().append("div") 
      .attr("class", function(d) { return d + " axis"; }) 
      .each(function(d) { d3.select(this).call(context.axis().ticks(12).orient(d)); }); 

     //create rule 
     d3.select(this.loc).append("div") 
      .style("position", "fixed") 
      .style("top", 0) 
      .style("bottom", 0) 
      .style("width", "1px") 
      .style("pointer-events", "none") 
      .call(context.rule()); 

     d3.select(this.loc).selectAll(".horizon") 
      .data(statsList) 
      .enter().insert("div", ".bottom") 
      .attr("class", "horizon") 
      .call(context.horizon().height(35)); 

그것은 본질적으로 백본 컬렉션에서 모든 통계를 반복 것 : 여기

(나는이 부분에서 문제가 발생하고 믿지 않는)를 DOM과 상호 작용하는 내 코드입니다 '백본 컬렉션의 현재 통계에 대한 참조를 전달합니다. 'getMetric'은 입체파 메트릭을 반환합니다.

 /* Keep a map of intialized metrics 
     When the visualization is initialized, we load the historical data which is in the 
     'attributes' field of the model. The model is an individual set metrics */ 

     var initializedMetrics = {}; 
     function getMetric(name, model){ 
      var format = d3.time.format("%I-%M-%S"); 
      return context.metric(function(start, stop, step, callback){ 
       var statValues = []; 

       if(initializedMetrics[name]){ 
        /* If the metric has already been initialized and we loaded the historical data 
        from 'attributes' field, plot the newest data which is stored in 'most-recent-data' 
        This field should be updated every second on every API call to the server */ 
        while(start<stop){ 
         start+=step; 
         console.log(model.attributes['most-recent-data']['rate']); 
         statValues.push(model.attributes['most-recent-data']['rate']); 
        } 

       } else{ 
        /* Metric has not been initalized, so we load all the historical data in 'all-data' 
        for this stat and plot it over time*/ 
        initializedMetrics[name]=true; 

        var lookup = {}, 
        i = start.getTime(); 
        //console.log('startTime', i); 
        var curStat = null; 
        var metricData = model.attributes['all-data'] 
        for(stat in metricData){ 
         curStat = metricData[stat]; 
         //console.log(name, curStat); 
         var curDate = new Date(curStat['timeStamp']); 
         curDate = format(curDate); 
         lookup[curDate] = curStat; 
        } 
        var lastValue; 
        while((i+=step) < stop){ 
         start+=step; 
         var key = format(new Date(i)); 
         if(key in lookup){ 
          lastValue = lookup[key]['valueLong']; 
         } 
         var curVal = key in lookup ? lookup[key]['valueLong'] : lastValue; 
         //console.log(name,curVal); 
         statValues.push(curVal); 
        } 
       } 
       /* Callback with statValues*/ 
       callback(null,statValues); 
       }, name); 
     } 

I합니다 (다른 브래킷 내부의 모든) 모든 기록 데이터를로드 성공을 보내고 있습니다 :

여기에 (아마도 문제를 일으키는) 각 메트릭을 처리하는 코드입니다. 그러나 메트릭이 초기화 될 때 '가장 최근 데이터'에 저장된 새 데이터를로드하려고합니다. 이 필드는 API 호출과 함께 매 초마다 업데이트되지만 각 콜백에서 '가장 최근 데이터'에 저장된 초기 데이터 만 플로팅합니다. 가장 최근 데이터가 백본 컬렉션 자체에서 실제로 업데이트되고 있음을 확인할 수 있지만 큐비 참조로 전달되는 참조는 각 콜백에서 업데이트되지 않습니다. 입체파 코드에 '최근 데이터'를 기록하면 절대 최신 값으로 업데이트되지 않습니다.

폐쇄 문제입니까? 새로운 데이터를 폴링하기위한 입체파 구문이 빠져 있습니까? 아니면 백본 컬렉션 참조를 다르게 전달해야합니까? 어떤 힌트라도 도움이 될 것입니다. 고맙습니다.

답변

0

해결책을 찾았습니다. 백본 컬렉션에 새 데이터를 병합하는 대신 다시 설정하고 각 데이터 포인트를 다시 추가했습니다. 이것은 원래 입체파에 전달한 모델이 업데이트되는 모델과 같지 않다는 것을 의미했습니다. 다시 설정하는 것과 달리 서버를 호출 할 때마다 콜렉션을 병합하여 문제가 해결되었습니다.

관련 문제