2016-01-21 53 views
1

我有2個問題,我需要幫助...dc.js - 分組數據使用UTC時間

  1. 當使用範圍圖表相應地選擇單個天數據更新表,但是當我延長範圍再次包括我似乎無法選擇最後一天的所有記錄?

  2. UTC時間問題,我似乎不得不將時間更改爲下午5點,以便日子能夠正常顯示,如果我不這樣做,那麼日子似乎會隨着他們的相關價值向下移動。見行85

是與問候更清楚問題#2

如果我使用2010-01-02T00:00:00Z它會不正確地映射到1月1日。 如果我使用2010-01-02T05:00:00Z工作正確映射到一月二

我有這個貼住上Plunker ...在這裏看到:

http://plnkr.co/edit/3nPjiE08ZzRXgNmSeym5?p=preview

任何幫助將非常感謝! Cheers Bruce

<!DOCTYPE html> 
<html lang="en"> 

<head> 
    <title>Chart</title> 
    <meta charset="UTF-8"> 

    <link rel="stylesheet" type="text/css" href="http://www.digitalliquid.com/tank/bootstrap.min.css"> 
    <link rel="stylesheet" type="text/css" href="http://www.digitalliquid.com/tank/dc.css" /> 

    <style> 
    #monthly-volume-chart g.y { 
     display: none; 
    } 

    #logo { 
     margin-right: 2em; 
     margin-top: 2em; 
    } 
    </style> 

</head> 

<body> 

    <!-- <div class="container-fluid"> --> 
    <div class="container"> 

    <div class="row"> 
     <div id="monthly-move-chart"> 
     <strong>Risk History</strong> 
     <span class="reset" style="display: none;">range: <span class="filter"></span></span> 
     <a class="reset" href="javascript:moveChart.filterAll();volumeChart.filterAll();dc.redrawAll();" style="display: none;">reset</a> 

     <div class="clearfix"></div> 
     </div> 
    </div> 

    <div class="row"> 
     <div id="monthly-volume-chart"> 
     </div> 
     <p class="muted pull-right" style="margin-right: 15px;">select a time range to zoom in</p> 
    </div> 

    <div class="row"> 
     <div> 
     <div class="dc-data-count"> 
      <span class="filter-count"></span> selected out of <span class="total-count"></span> records | <a href="javascript:dc.filterAll(); 
      dc.renderAll();">Reset All</a> 
     </div> 
     </div> 

     <table class="table table-hover dc-data-table"> 
     </table> 

    </div> 

    <div class="clearfix"></div> 

    </div> 

    <script type="text/javascript" src="http://www.digitalliquid.com/tank/d3.js"></script> 
    <script type="text/javascript" src="http://www.digitalliquid.com/tank/crossfilter.js"></script> 
    <script type="text/javascript" src="http://www.digitalliquid.com/tank/dc.js"></script> 
    <script type="text/javascript" src="http://www.digitalliquid.com/tank/colorbrewer.js"></script> 

    <script type="text/javascript"> 
    'use strict'; 

    var moveChart = dc.lineChart('#monthly-move-chart'); 
    var volumeChart = dc.barChart('#monthly-volume-chart'); 
    var nasdaqCount = dc.dataCount('.dc-data-count'); 
    var nasdaqTable = dc.dataTable('.dc-data-table'); 

    String.prototype.replaceAt = function(index, character) { 
     return this.substr(0, index) + character + this.substr(index + character.length); 
    } 

    // Load Data /Fix date 

    d3.json('risk.json', function(data) { 
     var dateFormat = d3.time.format.utc("%Y-%m-%dT%H:%M:%SZ"); 
     data.forEach(function(d) { 

     // i seem to have to change the time to 5pm to have the days display properly 
     //if i don't the days seem to shift down with their associated values?????? 
     // comment out the line below to see what i mean 

     // change hour in date to 5 pm 
     d.date = d.date.replaceAt(12, "5"); 


     d.dd = dateFormat.parse(d.date); 
     d.month = d3.time.month(d.dd); 
     d.day = d3.time.day(d.dd); 
      d.risk = +d.risk; // coerce to number 
     }); 

     console.log(JSON.stringify(data)); 


     // ### Create Crossfilter Dimensions and Groups****************** 

     var ndx = crossfilter(data); 
     var totalReadings = ndx.size(); 
     var all = ndx.groupAll(); 

     // var brush = d3.svg.brush(); 

     // Dimension by full date 
     var dateDimension = ndx.dimension(function(d) { 
     return d.dd; 
     }); 

     // Dimension by risk 
     var riskdimension = ndx.dimension(function(d) { 
     return d.risk; 
     }); 

     // Dimension by day 
     var daydim = ndx.dimension(function(d) { 
     return d.day; 
     }); 

     var mygroup = daydim.group().reduce(
     function(p, v) { 
      ++p.days; 
      // p.total += (v.open + v.close)/2; 
      // p.avg = Math.round(p.total/p.days); 
      // return v.risk; 
      p.risk = v.risk 
      return p; 
     }, 
     function(p, v) { 
      --p.days; 
      // p.total -= (v.open + v.close)/2; 
      // p.avg = p.days ? Math.round(p.total/p.days) : 0; 
      // return v.risk; 
      p.risk = v.risk 
      return p; 
     }, 
     function() { 
      return { 
      risk: 0, 

      }; 
     } 
    ); 

     //### Define Chart Attributes 

     moveChart 
     .renderArea(true) 
     .width(960) 
     .height(200) 
     .transitionDuration(1000) 
     .margins({ 
      top: 30, 
      right: 50, 
      bottom: 25, 
      left: 40 
     }) 
     .dimension(daydim) 
     .group(mygroup, 'Risk') 
     .mouseZoomable(true) 
     .rangeChart(volumeChart) 
     .y(d3.scale.linear().domain([0, 100])) 
     .x(d3.time.scale().domain([data[0].dd, data[data.length - 1].dd])) 
     .round(d3.time.day.round) 
     .xUnits(d3.time.days) 
     .renderHorizontalGridLines(true) 

     // ##### Legend ---------------------------------------------------------- 

     .legend(dc.legend().x(880).y(10).itemHeight(13).gap(5)) 
     .brushOn(false) 
     .valueAccessor(function(d) { 
      return d.value.risk; 

     }) 

     // #### Volume Chart ---------------------------------------------------------------------------------------------------------------------- 

     volumeChart 

     .width(960) 
     .height(40) 
     .margins({ 
      top: 0, 
      right: 50, 
      bottom: 20, 
      left: 40 
     }) 

.dimension(daydim) 
     .group(mygroup, 'Risk') 

     .centerBar(true) 
     .gap(1) 
     .x(d3.time.scale().domain([data[0].dd, data[data.length - 1].dd])) 
     .round(d3.time.day.round) 
     .alwaysUseRounding(true) 
     .xUnits(d3.time.days) 

    .valueAccessor(function(d) { 
      return d.value.risk; 

     }); 







     //#### Data Count *********************************** 
     nasdaqCount /* dc.dataCount('.dc-data-count', 'chartGroup'); */ 
     // dc.dataCount(".dc-data-count") 
     // dc.dataCount("#monthly-move-chart") 
     .dimension(ndx) 
     .group(all); 

     // .html({ 
     // some: '<strong>%filter-count</strong> selected out of <strong>%total-count</strong> records' + 
     //  ' | <a href=\'javascript:dc.filterAll(); dc.renderAll();\'\'>Reset All</a>', 
     // all: 'All records selected. Please click on the graph to apply filters.' 
     // }); 







     //#### Data Table 
     nasdaqTable /* dc.dataTable('.dc-data-table', 'chartGroup') */ 
     .dimension(dateDimension) 

     .group(function(d) { 
     var format = d3.format('02d'); 
     return d.dd.getFullYear() + '/' + format((d.dd.getMonth() + 1)); 
     }) 

     .size(100) 

     .columns(['date', 'risk', ]) 

     .sortBy(function(d) { 
      return d.dd; 
     }) 
     // (_optional_) sort order, `default = d3.ascending` 
     .order(d3.ascending) 
     // (_optional_) custom renderlet to post-process chart using [D3](http://d3js.org) 
     .on('renderlet', function(table) { 
      table.selectAll('.dc-table-group').classed('info', true); 
     }); 

     dc.renderAll(); 

    }); 
    </script> 


</body> 

</html> 
+0

問題1.解決了使用很好(d3.time.day,[2]),仍然處理問題#2 – bmcarthur

回答

1

默認情況下,所有時間將在當地時區解釋。

如果要使用UTC時間對數據進行分組,則應使用d3時間間隔實用程序的UTC versions

所以,無論你使用d3.time.days應該是d3.time.days.utc

我們在dc.js茉莉花測試,以確保測試在任何時區始終運行使用這些。

這可能需要一些迭代來擺脫所有假定當地時區的地方。我在你的plunker叉固定幾個:

http://plnkr.co/edit/qX5WvAeLxaO6kq6tqJ4C?p=preview

首先,你可能還需要在您的維度功能使用d3.time.day.utc(注意是單數形式),而不是讀.dd領域,將使用本地時區:(這可能不是你的情況不要緊,如果數據不超過一天的顆粒,但如果你在一天之內需要組多次就沒關係)

// Dimension by day 
    var daydim = ndx.dimension(function(d) { 
    return d3.time.day.utc(d.dd); 
    }); 

接下來,任何打印日期的東西都會再次搞砸了。所以,標題功能:

moveChart 
    .title(function(d) { return d.key.toUTCString() + ': ' + d.value; }) 

接下來,過濾打印機。在這裏,你可能想使用D3時間格式化,我印下面提到爲了調試刷牙問題的細節:

.filterPrinter(function(f) { 
     return f[0][0].toUTCString() + ' - ' + f[0][1].toUTCString() 
    }); 

最後,即使圖表顯示整個最後一天,你實際上已經設置結束的範圍到第一天的開始,所以它不能包含最後一個數據點。

有可能是在這裏dc.js(或一些容易混淆的特點)的錯誤,但我們會忽略,只是添加了第二個到的範圍的末尾:

var endDate = new Date(data[data.length - 1].dd); 
endDate.setSeconds(endDate.getSeconds()+1) 

    .x(d3.time.scale.utc().domain([data[0].dd, endDate])) 
+0

這有幫助,仍然有最後一條記錄的問題,根本沒有顯示在數據表中,如果你看到下面的plunk你會看到我不能選擇使用測距儀的最後一張記錄,爲什麼在線圖上的點數翻轉時,爲什麼UTC日期會以7pm的簽名顯示? http://plnkr.co/edit/qXQddzUu3gMsNBGnPSDm?p=preview – bmcarthur

+0

有幾個地方需要指定UTC,因爲它默認爲本地**無處不在**。我將添加上述內容。 – Gordon

+0

非常感謝Gordon對你的關注,我想知道爲什麼我不能保留這個,因爲我認爲它是在以前的foreach函數中計算的。 var daydim = ndx.dimension(function(d){ return d.day; });} – bmcarthur