【问题标题】:Javascript comparing dates - bug in d3.js chartJavascript 比较日期 - d3.js 图表中的错误
【发布时间】:2017-09-16 07:50:00
【问题描述】:

我正在尝试稳定此图表 - 我尝试比较日期对象 - 但后来遇到了夏令时差异的问题 - 我不确定为什么数据的变化会破坏图表 - 我遇到了一个未定义的问题.

//工作js小提琴 http://jsfiddle.net/Qh9X5/10379/

//破碎的js小提琴 http://jsfiddle.net/Qh9X5/10380/

-- 所以当向图表添加额外的数据时 - 它会产生一个未定义的错误

, {
  "text-start": "Text9",
  "date-start": "2012-05-01",
  "text-end": "Text10",
  "date-end": "2012-05-03"
}

起初我认为可能需要强制 yAxis 显示 1 天的增量 - .ticks(d3.time.days(min, max).length) 好像中间不存在坐标天。

这是工作图表的代码

var data = [{
  "text-start": "Text1",
  "date-start": "2012-04-21",
  "text-end": "Text2",
  "date-end": "2012-04-26"
}, {
  "text-start": "Text3",
  "date-start": "2012-04-22",
  "text-end": "Text4",
  "date-end": "2012-04-25"
}, {
  "text-start": "Text5",
  "date-start": "2012-04-26",
  "text-end": "Text6",
  "date-end": "2012-04-28"
}, {
  "text-start": "Text7",
  "date-start": "2012-04-21",
  "text-end": "Text8",
  "date-end": "2012-04-23"
}];

var margin = {
    top: 40,
    right: 40,
    bottom: 40,
    left: 60
  },
  width = 600,
  height = 500;

function colores_google(n) {
  var colores_g = ["#e9168a", "#f8dd2f", "#448875", "#c3bd75", "#2b2d39", "#311854", "#553814", "#f7b363", "#89191d", "#c12f34", "#2b2a2c", "#c5b8a6", "#57585b"];

  return colores_g[n % colores_g.length];
}


var y = d3.time.scale().range([height - margin.top - margin.bottom, 0]);


var arrayofDates = [];
$.each(data, function(index, value) {
    arrayofDates.push(value["date-start"]);
    arrayofDates.push(value["date-end"]);
});

var parseDate = d3.time.format("%m/%d/%Y").parse;

var min = new Date(d3.min(arrayofDates.map(d=>d)));
var max = new Date(d3.max(arrayofDates.map(d=>d)));

y.domain([min,max]);

var chart = d3.select('#timelines').append('svg')
  .attr('class', 'chart')
  .attr('width', width)
  .attr('height', height)
  .append('g')
  .attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');

//http://stackoverflow.com/questions/22722952/how-can-i-get-the-d3-js-axis-ticks-and-positions-as-an-array

var axisArray = [];

var yAxis = d3.svg.axis()
  .scale(y)
  .orient('left')
  .tickPadding(1);

chart.append('g')
  .attr('class', 'y axis')
  .call(yAxis)
  .selectAll(".tick").each(function(data) {
    var tick = d3.select(this);
    // pull the transform data out of the tick
    var transform = d3.transform(tick.attr("transform")).translate;
    // passed in "data" is the value of the tick, transform[0] holds the X value
    //console.log("each tick", data, transform);

    var month = data.getMonth() + 1;
    if (month < 10) {
      month = "0" + month;
    }
    var datestring = data.getFullYear() + "-" + month + "-" + data.getDate();

    var obj = {
      "data": datestring,
      "transform": transform
    }

    axisArray.push(obj);
  });


var links = chart.append('g')
  .attr('class', 'links')
  .attr("transform", "translate(0,0)");


function getRadius(d) {
  var count = 2;
  var ratio = count * 2.8;

  if (count == 1) {
    ratio = 10;
  }
  return ratio;
}


function getPos(date) {
  var trans;
  $.each(axisArray, function(index, value) {
    var a = value.data;
    var b = date;

    //console.log("a", a)
    //console.log("b", b)

    if (a == b) {
      //console.log("value", value.transform)
        //if (a.getTime() === b.getTime()) {
      trans = value.transform;
    }
  });

  return trans;
}



var distanceBetween = 70;

var paths = links.selectAll("path")
  .data(data);

paths.enter()
  .append("path")
  .attr("class", "link")
  .attr("d", function(d, i) {
    var sx = 0;
    var tx = 0;

    //console.log("d", d);

    var posEnd = getPos(d["date-start"]);
    var posStart = getPos(d["date-end"]);

    var sy = posStart[1];
    var ty = posEnd[1];


    var dx = 0,
      dy = getRadius(d) + 15 + (distanceBetween * i),
      dr = 10 //Math.sqrt(dx * dx + dy * dy);

    return "M" + sx + "," + sy + "A" + dr + "," + dr + " 0 0,1 " + tx + "," + ty;
  })
  .attr('stroke-width', 1.2)
  .attr("stroke", function(d, i) {
    //console.log("d", i);
    return colores_google(i);
  })

【问题讨论】:

  • posEnd[1] - 变得未定义 - 但我不确定为什么 - 或者是什么导致了这个错误
  • 问题似乎是chart.call(yAxis).selectAll(".tick") 的结果比你的arrayofDates 少一个,那么getPos() - if (a == b) 就不会匹配。搜索“d3 missing first item”时有一些结果,但我不知道这如何适用于您的代码。
  • @chrki 是什么导致了这个缺失的勾号——也许一旦我计算了最小/最大日期——应该在前一天/后一天突破界限?
  • 我尝试将域推送过去/未来 -- 但仍然失败 -- jsfiddle.net/Qh9X5/10389
  • var past = new Date(min.getTime());过去.setDate(min.getDate() - 1); var future = new Date(max.getTime());未来.setDate(max.getDate() + 1); y.domain([过去,未来]);

标签: javascript jquery d3.js


【解决方案1】:

-- 稳定的固定版本 http://jsfiddle.net/4v3Ldk93/2/

我设法修复它:http://jsfiddle.net/4v3Ldk93/

错误是因为:

console.log("pos", posEnd, posStart)

返回:

pos undefined [0, 256.6666564941406]

posEnd 未定义。因此,您无法获得posEnd[1];undefined。这正是控制台错误:cannot get attribute 1 of undefined。

这是因为,在getPos中,axisArray的最小值为:{ data: "2012-04-22" }

这不是您的日期转换问题,而是因为:.selectAll(".tick").each(function(data) { 仅将 4 月 22 日作为第一个日期。

如果你没问题,你可以通过在两端添加一天的填充来修复它。在你的最小值和最大值定义之后添加这两行:

min.setDate(min.getDate() - 1);
max.setDate(max.getDate() + 1);

如果你不喜欢最后的额外一天,你实际上只需要在最短日期之前解决这个问题。你可以这样做:

min.setDate(min.getDate() - 1);

我的猜测是域被设置为 (min, max]; 这意味着它包括上边界,但不包括下边界。但是,除了更改有效之外,这不是 100% 确定的。

然后,你在你的月份前修正了 0,但你的日子没有这样做:

var day = data.getDate();
if (day < 10) day = "0" + day;

通过这两个更改,它对我有用。

虽然我不确定为什么这适用于您的“工作版本”而不是“损坏的版本”,但这些更改也使工作版本正常工作:http://jsfiddle.net/Ljrg9v2v/

还将 .ticks(d3.time.days(min, max).length) 添加到 yAxis 以确保时间线有 1 天的增量。

我希望这会有所帮助。

【讨论】:

  • 我认为它是您所做的所有更改的组合 --- var parseDate = d3.time.format("%Y-%m-%d").parse; -- 你确保解析格式是一样的。然后当天用0还是没用。以及在之前/之后推送日期范围。
  • 我认为这进一步解决了这个问题——刻度还需要以 1 天为增量进行调整——以确保日期始终可以绑定到轴上——yAxis 上的jsfiddle.net/4v3Ldk93/2—— .ticks(d3.time.days(min, max).length)
  • 我得到了另一个图表@fvbuendia,它可以做一些稳定性——stackoverflow.com/questions/43415966/…jsfiddle.net/NYEaX/1855
  • 还有@fvbuendia,如果你有办法在这张图表上看到压缩时间线——stackoverflow.com/questions/43417708/…jsfiddle.net/NYEaX/1848
  • 添加/批准了 1 天增量的更改 :)
猜你喜欢
  • 2017-06-28
  • 1970-01-01
  • 1970-01-01
  • 2020-08-12
  • 2018-04-24
  • 1970-01-01
  • 1970-01-01
  • 2021-07-03
  • 2011-12-20
相关资源
最近更新 更多