使用 cal-heatmap 显示外部数据的问题

Problems displaying external data with cal-heatmap

我正在使用 D3 日历热图库,cal-heatmap

我有一个带有校准热图的 external JSON file hosted on GitHub that I'm getting via a jQuery .getJSON callback function. I'm parsing the original data in the JSON file to the format compatible

数据已正确解析和转换,但未加载到日历中。我已经尝试使用各种 cal-heatmap afterLoadafterLoadData 事件来加载数据,但数据仍然没有显示。

我在 JSbin 上有该项目的副本。

// global data variable
var data = null;

// Convert running log JSON data into readable format for heatmap calendar
function convertRunningLog() {

    // set get URL
    var json_url = "https://raw.githubusercontent.com/kylesb/static/master/JSON/running_log.json";
    // declare object variable
    var ob = {};

    // Get running log file from repository
    $.getJSON(json_url, function(result){

        // for each data entry
        for (var i = 0; i < result.data.length; i++) {

            // get date and miles
            var apoche  = date_to_epoch(result['data'][i]['date']).toString();
            var miles   = parseFloat(result['data'][i]['miles']); 

            // set date and miles
            ob[apoche.toString()] = miles;
        }
        var json_string = JSON.stringify(ob);
        data = JSON.parse(json_string);
        console.log(data);
        return data;
    });
}

// Convert strings to date objects 
function date_to_epoch(key) { 
    var epoch_seconds = new Date(key).getTime();
    return Math.floor (epoch_seconds / 1000);
}

// initilize the calendar
// ------------------------
var cal = new CalHeatMap();
cal.init({
  itemSelector: "#cal",
  domain: "month",
  subDomain: "x_day",
  data: convertRunningLog(),
  start: new Date(2016, 0, 5),
  cellSize: 20,
  cellPadding: 5,
  domainGutter: 20,
  range: 1,
  domainDynamicDimension: false,
  previousSelector: "#example-g-PreviousDomain-selector",
  nextSelector: "#example-g-NextDomain-selector",

  subDomainTextFormat: "%d",
  legend: [0.5, 1, 1.5, 2]
});

$.getJSON 是一个 async 调用。它立即 returns 并在完成时调用结果回调。因此,您的 convertRunningLog 函数 returns 什么也没有。为了使其工作,您的 CalHeatMap 代码需要在结果回调中。此外,如果您仅将 jquery 用于 ajax 调用,则可以使用 d3s corresponding method 并节省 jquery.

的加载时间

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
  <script data-require="jquery@2.1.4" data-semver="2.1.4" src="https://code.jquery.com/jquery-2.1.4.js"></script>
  <link rel="stylesheet" href="https://rawgit.com/wa0x6e/cal-heatmap/master/cal-heatmap.css" />
  <script src="https://rawgit.com/wa0x6e/cal-heatmap/master/cal-heatmap.js"></script>
</head>

<body>
  <div id="cal"></div>
  <script>
    // global data variable
    var data = null;

    // Convert running log JSON data into readable format for heatmap calendar
    function convertRunningLog() {

      // set get URL
      var json_url = "https://raw.githubusercontent.com/kylesb/static/master/JSON/running_log.json";
      // declare object variable
      var ob = {};

      // Get running log file from repository
      d3.json(json_url, function(error, result) {
        
        // for each data entry
        for (var i = 0; i < result.data.length; i++) {

          // get date and miles
          var apoche = date_to_epoch(result['data'][i]['date']).toString();
          var miles = parseFloat(result['data'][i]['miles']);

          // set date and miles
          ob[apoche.toString()] = miles;
        }
        
        var json_string = JSON.stringify(ob);
        data = JSON.parse(json_string);

        var cal = new CalHeatMap();
        cal.init({
          itemSelector: "#cal",
          domain: "month",
          subDomain: "x_day",
          data: data,
          start: new Date(2016, 0, 5),
          cellSize: 20,
          cellPadding: 5,
          domainGutter: 20,
          range: 1,
          domainDynamicDimension: false,
          previousSelector: "#example-g-PreviousDomain-selector",
          nextSelector: "#example-g-NextDomain-selector",

          subDomainTextFormat: "%d",
          legend: [0.5, 1, 1.5, 2]
        });


      });
    }

    // Convert strings to date objects 
    function date_to_epoch(key) {
      var epoch_seconds = new Date(key).getTime();
      return Math.floor(epoch_seconds / 1000);
    }

    convertRunningLog();
    
  </script>
</body>

</html>